From 5f837d70fba902a8b13bdc7576ce1d1fb77513f2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jan 2019 17:51:10 +0100 Subject: [PATCH 0001/1786] [maven-release-plugin] prepare release bean-utils-library-1.0.14 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9ec476cee..e83ab0e24 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.4-SNAPSHOT + 1.0.14 jar 2019 @@ -315,6 +315,6 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.2 + bean-utils-library-1.0.14 From 2662e64c07b7406af27c4f0a548af6c40f594a65 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jan 2019 17:51:19 +0100 Subject: [PATCH 0002/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e83ab0e24..39a67278a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.14 + 1.0.15-SNAPSHOT jar 2019 @@ -315,6 +315,6 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.14 + bean-utils-library-1.0.2 From d234b5e010242096d4184631b2fb57c60025cd46 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jan 2019 18:02:04 +0100 Subject: [PATCH 0003/1786] Renamed contributor file --- CONTRIBUTORS.md => CONTRIBUTING.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CONTRIBUTORS.md => CONTRIBUTING.md (100%) diff --git a/CONTRIBUTORS.md b/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTORS.md rename to CONTRIBUTING.md From d358a4701cda81bbbc515e19ac14cab45b8cf1b1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 19 Jan 2019 08:22:53 +0100 Subject: [PATCH 0004/1786] Set theme jekyll-theme-cayman --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 000000000..c4192631f --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file From 21818c0180f45d9d1fc6c26dd488ec9fe9fa6ac4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jan 2019 11:55:47 +0100 Subject: [PATCH 0005/1786] Added github site deploy configuration --- README.md | 58 +++++++++++++++++----------------- docs/site/markdown/overview.md | 1 + pom.xml | 53 ++++++++++++++++++++++++++----- 3 files changed, 75 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 7e19d7c96..5fd7468c4 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ public class FromBean { public class ToBean And one line code as: ~~~Java - beanUtils.getTranformer().withFieldMapping(new FieldMapping("id", "identifier")).transform(fromBean, ToBean.class); +beanUtils.getTranformer().withFieldMapping(new FieldMapping("id", "identifier")).transform(fromBean, ToBean.class); ~~~ Constructor with Java version <= 8 @@ -118,53 +118,53 @@ public class FromBean { public class ToBean From class and To class without custom annotation usage: ~~~Java - @AllArgsConstructor @AllArgsConstructor - @Getter @Getter - @Setter @Setter - public class FromBean { public class ToBean { - private final String name; @NotNull - private final BigInteger id; public BigInteger id; - private final List subBeanList; private final String name; - private List list; private final List list; - private final FromSubBean subObject; private final List nestedObjectList; - private ImmutableToSubFoo nestedObject; - } +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +@Setter @Setter +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List nestedObjectList; + private ImmutableToSubFoo nestedObject; +} } ~~~ And one line code as: ~~~Java - ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); +ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); ~~~ Field transformation through lambda function transformation: ~~~Java - FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); - beanUtils.getTransformer() - .withFieldMapping(new FieldMapping("id", "identifier")) - .withFieldTransformer(fieldTransformer).transform(fromBean, ToBean.class); +FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); +beanUtils.getTransformer() + .withFieldMapping(new FieldMapping("id", "identifier")) + .withFieldTransformer(fieldTransformer).transform(fromBean, ToBean.class); ~~~ or ~~~Java - FieldTransformer localeTransformer = new FieldTransformer<>("locale", Locale::forLanguageTag) - beanUtils.getTransformer() - .withFieldTransformer(localeTransformer).transform(fromBean, ToBean.class); +FieldTransformer localeTransformer = new FieldTransformer<>("locale", Locale::forLanguageTag) +beanUtils.getTransformer() + .withFieldTransformer(localeTransformer).transform(fromBean, ToBean.class); ~~~ Assign a default value in case of missing field in the source object: ~~~Java - @AllArgsConstructor @AllArgsConstructor - @Getter @Getter - public class FromBean { public class ToBean { - private final String name; @NotNull - private final BigInteger id; public BigInteger id; - private final String name; - private String notExistingField; // this will be null and no exceptions will be raised - } } +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final String name; + private String notExistingField; // this will be null and no exceptions will be raised +} } ~~~ And one line code as: ~~~Java - ToBean toBean = beanUtils.getTransformer().setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); +ToBean toBean = beanUtils.getTransformer().setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); ~~~ More sample beans can be found in the test package: `com.hotels.beans.sample` diff --git a/docs/site/markdown/overview.md b/docs/site/markdown/overview.md index 9d0dc0e3e..f242a1a66 100644 --- a/docs/site/markdown/overview.md +++ b/docs/site/markdown/overview.md @@ -27,3 +27,4 @@ This BeanUtils library is a utility library for managing Bean objects. The libra * support copy of beans with different field's name * support lambda function field transformation * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. + * allows to set the default value for all objects not existing in the source object. diff --git a/pom.xml b/pom.xml index 39a67278a..77e68e5f2 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,31 @@ 0.80 3.2.0 + 0.12 + github + + + + scm:git:git@github.com:HotelsDotCom/bull.git + scm:git:git@github.com:HotelsDotCom/bull.git + https://github.com/HotelsDotCom/bull + + + + sonatype-nexus-snapshots + https://oss.sonatype.org/content/repositories/snapshots + + + sonatype-nexus-staging + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + github-site + https://hotelsdotcom.github.io/bull + + + org.springframework.boot @@ -252,6 +276,10 @@ org.codehaus.mojo cobertura-maven-plugin ${cobertura.maven.plugin.version} + + false + true + none @@ -287,6 +315,7 @@ ${maven.site.plugin.version} ${project.basedir}/docs/site + true @@ -296,6 +325,22 @@ + + com.github.github + site-maven-plugin + ${github.site.maven.plugin.version} + + Creating site for ${project.artifactId} ${project.version} + + + + + site + + site + + + @@ -309,12 +354,4 @@ - - - - scm:git:git@github.com:HotelsDotCom/bull.git - scm:git:git@github.com:HotelsDotCom/bull.git - https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.2 - From dd9b04127edc7e27e1398d72fe16b690038aaf6d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jan 2019 12:03:00 +0100 Subject: [PATCH 0006/1786] fixed syntax error --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 77e68e5f2..9a6660f31 100644 --- a/pom.xml +++ b/pom.xml @@ -328,7 +328,7 @@ com.github.github site-maven-plugin - ${github.site.maven.plugin.version} + ${github.site.maven.plugin.version} Creating site for ${project.artifactId} ${project.version} From 0a452683ba9b401f23d1aca8c4094a214389a7ef Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 21 Jan 2019 11:07:28 +0100 Subject: [PATCH 0007/1786] temp github site disable --- pom.xml | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/pom.xml b/pom.xml index 9a6660f31..e6bef852c 100644 --- a/pom.xml +++ b/pom.xml @@ -60,9 +60,13 @@ sonatype-nexus-staging https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + - github-site - https://hotelsdotcom.github.io/bull + devdocs.hcom + scp://devdocs.hcom/var/www/html/beanUtilsLightLibrary @@ -315,7 +319,7 @@ ${maven.site.plugin.version} ${project.basedir}/docs/site - true + @@ -325,22 +329,22 @@ - - com.github.github - site-maven-plugin - ${github.site.maven.plugin.version} - - Creating site for ${project.artifactId} ${project.version} - - - - - site - - site - - - + + + + + + + + + + + + + + + + From e4c804e99ac62817805a8955328c0392f18bbd9b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 21 Jan 2019 11:52:34 +0100 Subject: [PATCH 0008/1786] Added documentation samples --- docs/site/markdown/transformer/samples.md | 164 ++++++++++++++++++++++ docs/site/site.xml | 4 +- 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 docs/site/markdown/transformer/samples.md diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md new file mode 100644 index 000000000..b5530587f --- /dev/null +++ b/docs/site/markdown/transformer/samples.md @@ -0,0 +1,164 @@ + + Bean Transformer + + +# Transformation samples + +### Simple case: + +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +@Setter @Setter +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List nestedObjectList; + private ImmutableToSubFoo nestedObject; +} + } +~~~ +And one line code as: +~~~Java +ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); +~~~ + +### Different field names copy: + +From class and To class with custom annotation usage and different field names: +~~~Java +public class FromBean { public class ToBean { + + private final String name; private final String differentName; + private final int id; private final int id; + private final List subBeanList; private final List subBeanList; + private final List list; private final List list; + private final FromSubBean subObject; private final ToSubBean subObject; + + // getters and setters... + public ToBean(final String name, + final int id, +} final List subBeanList, + final List list, + final ToSubBean subObject) { + this.name = name; + this.id = id; + this.subBeanList = subBeanList; + this.list = list; + this.subObject = subObject; + } + + // getters and setters... + + } +~~~ +And one line code as: + +~~~Java +beanUtils.getTranformer().withFieldMapping(new FieldMapping("id", "identifier")).transform(fromBean, ToBean.class); +~~~ + +### Different field names defining constructor args: + +~~~Java +public class FromBean { public class ToBean { + + private final String name; private final String differentName; + private final int id; private final int id; + private final List subBeanList; private final List subBeanList; + private final List list; private final List list; + private final FromSubBean subObject; private final ToSubBean subObject; + + // getters and setters... + public ToBean(@ConstructorArg("name") final String name, + @ConstructorArg("id") final int id, +} @ConstructorArg("subBeanList") final List subBeanList, + @ConstructorArg(fieldName ="list") final List list, + @ConstructorArg("subObject") final ToSubBean subObject) { + this.name = name; + this.id = id; + this.subBeanList = subBeanList; + this.list = list; + this.subObject = subObject; + } + + // getters and setters... + + } +~~~ +And one line code as: +~~~Java +ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); +~~~ + +### Different field names and types applying transformation through lambda function: + +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +@Setter @Setter +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger identifier; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List nestedObjectList; + private final String locale; private final Locale locale; + private ImmutableToSubFoo nestedObject; +} + } +~~~ + +~~~Java +FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); +FieldTransformer localeTransformer = new FieldTransformer<>("locale", Locale::forLanguageTag); +beanUtils.getTransformer() + .withFieldMapping(new FieldMapping("id", "identifier")) + .withFieldTransformer(fieldTransformer).transform(fromBean, ToBean.class) + .withFieldTransformer(localeTransformer); +~~~ + +### Assign a default value in case of missing field in the source object: + +Assign a default value in case of missing field in the source object: + +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final String name; + private String notExistingField; // this will be null and no exceptions will be raised +} } +~~~ +And one line code as: +~~~Java +ToBean toBean = beanUtils.getTransformer() + .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); +~~~ + +### Applying a transformation function in case of missing fields in the source object: + +Assign a default value in case of missing field in the source object: + +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final String name; + private String notExistingField; // this will be null and no exceptions will be raised +} } +~~~ +And one line code as: +~~~Java +FieldTransformer localeTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); +ToBean toBean = beanUtils.getTransformer() + .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); +~~~ + +More sample beans can be found in the test package: `com.hotels.beans.sample` \ No newline at end of file diff --git a/docs/site/site.xml b/docs/site/site.xml index 7ba7a8cc5..032501cff 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -29,11 +29,13 @@ + - + + From 4819c31e4f7d8eb919434380bdd3a662763baffc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 21 Jan 2019 15:59:51 +0100 Subject: [PATCH 0009/1786] Added samples --- README.md | 78 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 5fd7468c4..07013631e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## Bean Utils Light Library -This BeanUtils library is It's a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. +This BeanUtils library is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. ## Start using @@ -52,7 +52,30 @@ mvn clean install -P relaxed * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. -### A full Sample: +## Transformation samples + +### Simple case: + +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +@Setter @Setter +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List nestedObjectList; + private ImmutableToSubFoo nestedObject; +} + } +~~~ +And one line code as: +~~~Java +ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); +~~~ + +### Different field names copy: From class and To class with custom annotation usage and different field names: ~~~Java @@ -87,7 +110,7 @@ And one line code as: beanUtils.getTranformer().withFieldMapping(new FieldMapping("id", "identifier")).transform(fromBean, ToBean.class); ~~~ -Constructor with Java version <= 8 +### Different field names defining constructor args: ~~~Java public class FromBean { public class ToBean { @@ -115,7 +138,12 @@ public class FromBean { public class ToBean } ~~~ -From class and To class without custom annotation usage: +And one line code as: +~~~Java +ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); +~~~ + +### Different field names and types applying transformation through lambda function: ~~~Java @AllArgsConstructor @AllArgsConstructor @@ -123,33 +151,47 @@ From class and To class without custom annotation usage: @Setter @Setter public class FromBean { public class ToBean { private final String name; @NotNull - private final BigInteger id; public BigInteger id; + private final BigInteger id; public BigInteger identifier; private final List subBeanList; private final String name; private List list; private final List list; private final FromSubBean subObject; private final List nestedObjectList; + private final String locale; private final Locale locale; private ImmutableToSubFoo nestedObject; } - } -~~~ -And one line code as: -~~~Java -ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); + } ~~~ -Field transformation through lambda function transformation: ~~~Java FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); +FieldTransformer localeTransformer = new FieldTransformer<>("locale", Locale::forLanguageTag); beanUtils.getTransformer() .withFieldMapping(new FieldMapping("id", "identifier")) - .withFieldTransformer(fieldTransformer).transform(fromBean, ToBean.class); + .withFieldTransformer(fieldTransformer).transform(fromBean, ToBean.class) + .withFieldTransformer(localeTransformer); ~~~ -or + +### Assign a default value in case of missing field in the source object: + +Assign a default value in case of missing field in the source object: + ~~~Java -FieldTransformer localeTransformer = new FieldTransformer<>("locale", Locale::forLanguageTag) -beanUtils.getTransformer() - .withFieldTransformer(localeTransformer).transform(fromBean, ToBean.class); +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final String name; + private String notExistingField; // this will be null and no exceptions will be raised +} } +~~~ +And one line code as: +~~~Java +ToBean toBean = beanUtils.getTransformer() + .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); ~~~ +### Applying a transformation function in case of missing fields in the source object: + Assign a default value in case of missing field in the source object: ~~~Java @@ -164,7 +206,9 @@ public class FromBean { public class ToBean ~~~ And one line code as: ~~~Java -ToBean toBean = beanUtils.getTransformer().setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); +FieldTransformer localeTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); +ToBean toBean = beanUtils.getTransformer() + .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); ~~~ More sample beans can be found in the test package: `com.hotels.beans.sample` From b16beaa46efb2c951af8d4dcb88b4d346de0877f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 21 Jan 2019 16:01:25 +0100 Subject: [PATCH 0010/1786] tmp removed github site config --- pom.xml | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/pom.xml b/pom.xml index e6bef852c..2c1b66155 100644 --- a/pom.xml +++ b/pom.xml @@ -60,14 +60,6 @@ sonatype-nexus-staging https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - - - devdocs.hcom - scp://devdocs.hcom/var/www/html/beanUtilsLightLibrary - @@ -319,7 +311,6 @@ ${maven.site.plugin.version} ${project.basedir}/docs/site - @@ -329,22 +320,6 @@ - - - - - - - - - - - - - - - - From 77567fd740a8dc94e3b6efd5322d760e6422efb4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 21 Jan 2019 16:38:20 +0100 Subject: [PATCH 0011/1786] Fixed error into readme file --- README.md | 4 ++-- docs/site/markdown/transformer/samples.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 07013631e..58336baca 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ public class FromBean { public class ToBean And one line code as: ~~~Java -beanUtils.getTranformer().withFieldMapping(new FieldMapping("id", "identifier")).transform(fromBean, ToBean.class); +beanUtils.getTranformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); ~~~ ### Different field names defining constructor args: @@ -122,7 +122,7 @@ public class FromBean { public class ToBean private final FromSubBean subObject; private final ToSubBean subObject; // getters and setters... - public ToBean(@ConstructorArg("name") final String name, + public ToBean(@ConstructorArg("name") final String differentName, @ConstructorArg("id") final int id, } @ConstructorArg("subBeanList") final List subBeanList, @ConstructorArg(fieldName ="list") final List list, diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index b5530587f..5741449c8 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -57,7 +57,7 @@ public class FromBean { public class ToBean And one line code as: ~~~Java -beanUtils.getTranformer().withFieldMapping(new FieldMapping("id", "identifier")).transform(fromBean, ToBean.class); +beanUtils.getTranformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); ~~~ ### Different field names defining constructor args: @@ -72,7 +72,7 @@ public class FromBean { public class ToBean private final FromSubBean subObject; private final ToSubBean subObject; // getters and setters... - public ToBean(@ConstructorArg("name") final String name, + public ToBean(@ConstructorArg("name") final String differentName, @ConstructorArg("id") final int id, } @ConstructorArg("subBeanList") final List subBeanList, @ConstructorArg(fieldName ="list") final List list, From 7da8ef4c45afcd56d70f3d7d4c1501ee18c6414e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 22 Jan 2019 22:34:38 +0100 Subject: [PATCH 0012/1786] Fixed documentation errors --- README.md | 15 ++++++++------- docs/site/markdown/transformer/samples.md | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 58336baca..11a88e7cc 100644 --- a/README.md +++ b/README.md @@ -88,12 +88,12 @@ public class FromBean { public class ToBean private final FromSubBean subObject; private final ToSubBean subObject; // getters and setters... - public ToBean(final String name, + public ToBean(final String differentName, final int id, } final List subBeanList, final List list, final ToSubBean subObject) { - this.name = name; + this.differentName = differentName; this.id = id; this.subBeanList = subBeanList; this.list = list; @@ -107,7 +107,7 @@ public class FromBean { public class ToBean And one line code as: ~~~Java -beanUtils.getTranformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); +beanUtils.getTransformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); ~~~ ### Different field names defining constructor args: @@ -127,7 +127,7 @@ public class FromBean { public class ToBean } @ConstructorArg("subBeanList") final List subBeanList, @ConstructorArg(fieldName ="list") final List list, @ConstructorArg("subObject") final ToSubBean subObject) { - this.name = name; + this.differentName = differentName; this.id = id; this.subBeanList = subBeanList; this.list = list; @@ -201,14 +201,15 @@ public class FromBean { public class ToBean private final String name; @NotNull private final BigInteger id; public BigInteger id; private final String name; - private String notExistingField; // this will be null and no exceptions will be raised + private String notExistingField; // this will be have valued with: sampleVal } } ~~~ And one line code as: ~~~Java -FieldTransformer localeTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); +FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); ToBean toBean = beanUtils.getTransformer() - .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); + .withFieldTransformer(true) + .transform(notExistingFieldTransformer, ToBean.class); ~~~ More sample beans can be found in the test package: `com.hotels.beans.sample` diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 5741449c8..92db122fb 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -38,12 +38,12 @@ public class FromBean { public class ToBean private final FromSubBean subObject; private final ToSubBean subObject; // getters and setters... - public ToBean(final String name, + public ToBean(final String differentName, final int id, } final List subBeanList, final List list, final ToSubBean subObject) { - this.name = name; + this.differentName = differentName; this.id = id; this.subBeanList = subBeanList; this.list = list; @@ -57,7 +57,7 @@ public class FromBean { public class ToBean And one line code as: ~~~Java -beanUtils.getTranformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); +beanUtils.getTransformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); ~~~ ### Different field names defining constructor args: @@ -77,7 +77,7 @@ public class FromBean { public class ToBean } @ConstructorArg("subBeanList") final List subBeanList, @ConstructorArg(fieldName ="list") final List list, @ConstructorArg("subObject") final ToSubBean subObject) { - this.name = name; + this.differentName = differentName; this.id = id; this.subBeanList = subBeanList; this.list = list; @@ -151,14 +151,15 @@ public class FromBean { public class ToBean private final String name; @NotNull private final BigInteger id; public BigInteger id; private final String name; - private String notExistingField; // this will be null and no exceptions will be raised + private String notExistingField; // this will be have valued with: sampleVal } } ~~~ And one line code as: ~~~Java -FieldTransformer localeTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); +FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); ToBean toBean = beanUtils.getTransformer() - .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); + .withFieldTransformer(true) + .transform(notExistingFieldTransformer, ToBean.class); ~~~ More sample beans can be found in the test package: `com.hotels.beans.sample` \ No newline at end of file From 294ec17fcf88db7f72fadf7f15ce3ef5dbeb32e8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 22 Jan 2019 22:37:05 +0100 Subject: [PATCH 0013/1786] Fixed typo --- README.md | 2 +- docs/site/markdown/transformer/samples.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 11a88e7cc..aa3136ac9 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ public class FromBean { public class ToBean private final String name; @NotNull private final BigInteger id; public BigInteger id; private final String name; - private String notExistingField; // this will be have valued with: sampleVal + private String notExistingField; // this will have value: sampleVal } } ~~~ And one line code as: diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 92db122fb..2e82dbb76 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -151,7 +151,7 @@ public class FromBean { public class ToBean private final String name; @NotNull private final BigInteger id; public BigInteger id; private final String name; - private String notExistingField; // this will be have valued with: sampleVal + private String notExistingField; // this will have value: sampleVal } } ~~~ And one line code as: From e359c737b69b2e319406577d1257d9d7561c5d34 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 22 Jan 2019 22:50:48 +0100 Subject: [PATCH 0014/1786] fixed typo --- README.md | 4 ++-- docs/site/markdown/transformer/samples.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index aa3136ac9..ff7e6ee54 100644 --- a/README.md +++ b/README.md @@ -208,8 +208,8 @@ And one line code as: ~~~Java FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); ToBean toBean = beanUtils.getTransformer() - .withFieldTransformer(true) - .transform(notExistingFieldTransformer, ToBean.class); + .withFieldTransformer(notExistingFieldTransformer) + .transform(fromBean, ToBean.class); ~~~ More sample beans can be found in the test package: `com.hotels.beans.sample` diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 2e82dbb76..c8b088a46 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -158,8 +158,8 @@ And one line code as: ~~~Java FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); ToBean toBean = beanUtils.getTransformer() - .withFieldTransformer(true) - .transform(notExistingFieldTransformer, ToBean.class); + .withFieldTransformer(notExistingFieldTransformer) + .transform(fromBean, ToBean.class); ~~~ More sample beans can be found in the test package: `com.hotels.beans.sample` \ No newline at end of file From 1243899b902c0d38263d3ea08b9d7190ae3df570 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 22 Jan 2019 23:05:12 +0100 Subject: [PATCH 0015/1786] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/custom.md | 10 ++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/custom.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..dd84ea782 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 000000000..48d5f81fa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,10 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..bbcbbe7d6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 3b9b44413842d2bda31dfb9afc5512d82f334e43 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 00:02:25 +0100 Subject: [PATCH 0016/1786] Added github site configuration --- pom.xml | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 2c1b66155..e37752f43 100644 --- a/pom.xml +++ b/pom.xml @@ -51,16 +51,6 @@ scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - - - sonatype-nexus-snapshots - https://oss.sonatype.org/content/repositories/snapshots - - - sonatype-nexus-staging - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - @@ -311,6 +301,7 @@ ${maven.site.plugin.version} ${project.basedir}/docs/site + true @@ -320,6 +311,22 @@ + + com.github.github + site-maven-plugin + ${github.site.maven.plugin.version} + + Creating site for ${project.artifactId} ${project.version} + + + + + site + + site + + + From 96b60fca4d27d150976c16444023d955aeb81047 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 16:18:06 +0100 Subject: [PATCH 0017/1786] Configured maven site generation and publish on GitHub site --- docs/site/markdown/index.md | 32 ++++++++ docs/site/markdown/transformer/overview.md | 14 ---- docs/site/markdown/transformer/performance.md | 8 +- docs/site/resources/css/site.css | 70 +----------------- ...tels_com_logo_en_int_wakeuphappy_small.png | Bin 4380 -> 0 bytes docs/site/site.xml | 17 ++--- pom.xml | 24 +++++- 7 files changed, 69 insertions(+), 96 deletions(-) create mode 100644 docs/site/markdown/index.md delete mode 100644 docs/site/markdown/transformer/overview.md delete mode 100644 docs/site/resources/images/hotels_com_logo_en_int_wakeuphappy_small.png diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md new file mode 100644 index 000000000..5775211a8 --- /dev/null +++ b/docs/site/markdown/index.md @@ -0,0 +1,32 @@ + + About + + +# ![bull-logo](images/BullBranding_03.png) + +# Overview + +This BeanUtils library is a utility library for managing Bean objects. The library offers the following components: + +- #### Bean Transformer: + + is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. + It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. + + ##### Features: + * support copy of immutable beans. + * support copy of mutable beans. + * support copy of hybrid beans (some fields private and some not). + * support copy of Java beans without getter and setter methods. + * support copy with Java primitive type. + * support copy with Java Collection type. e.g. `List => List` + * support copy with nested map fields. e.g. `Map>` + * support copy with array containing primitive types. e.g. `String[]` => `String[]` + * support copy with array type. e.g. `BeanA[]` => `BeanB[]` + * support copy with property name mapping. e.g. `int id => int userId` + * support copy with recursion copy + * support validation through annotations + * support copy of beans with different field's name + * support lambda function field transformation + * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. + * allows to set the default value for all objects not existing in the source object. diff --git a/docs/site/markdown/transformer/overview.md b/docs/site/markdown/transformer/overview.md deleted file mode 100644 index ea55f5901..000000000 --- a/docs/site/markdown/transformer/overview.md +++ /dev/null @@ -1,14 +0,0 @@ - - Bean Transformer - - -# Transformer - -Transformer component of the BULL project offers low-level utility classes that assist in getting and setting property values on Java classes. - -This page documents the following APIs: - -* Mutable bean transformation -* Immutable bean transformation -* Mixed bean transformation -* Bean with different field names transformation \ No newline at end of file diff --git a/docs/site/markdown/transformer/performance.md b/docs/site/markdown/transformer/performance.md index 7d74b1bc7..2ea65b7ee 100644 --- a/docs/site/markdown/transformer/performance.md +++ b/docs/site/markdown/transformer/performance.md @@ -16,9 +16,9 @@ This page shows the transformer performance for the following objects: | :----------- | :-----------: | :-----------: | :-----------: | | Simple objects (without nested objects) | ~0.05ms | ~0.034ms | NA | | Complex objects (containing several nested object and several items in Map and Array objects) | ~0.38ms | ~0.21ms | ~0.22ms | -| CPU/Heap usage | [~0.2%/35 MB](../../resources/images/stats/performance/mutableObject/jvmStats.jpg) | [~0.2%/30 MB](../../resources/images/stats/performance/immutableObject/jvmStats.jpg) | [~0.2%/25 MB](../../resources/images/stats/performance/mixedObject/jvmStats.jpg) | +| CPU/Heap usage | [~0.2%/35 MB](../images/stats/performance/mutableObject/jvmStats.jpg) | [~0.2%/30 MB](../images/stats/performance/immutableObject/jvmStats.jpg) | [~0.2%/25 MB](../images/stats/performance/mixedObject/jvmStats.jpg) | -Transformation time [screenshot](../../resources/images/stats/performance/transformationTime.jpg) +Transformation time [screenshot](../images/stats/performance/transformationTime.jpg) ## Real case testing @@ -33,5 +33,5 @@ Following the obtained results: | Average CPU usage | 0.3% | 0.3% | | Min/Max Heap Memory Usage (MB) | 90/320 | 90/320 | | Average Latency than the downstream service | +2ms | +2ms | -| JVM stats screenshot | [screenshot](../../resources/images/stats/performance/realTestCase/classicTransformer/jvmStats.jpg) | [screenshot](../../resources/images/stats/performance/realTestCase/beanUtilsLib/jvmStats.jpg) | -| Dashboard screenshot | [screenshot](../../resources/images/stats/performance/realTestCase/classicTransformer/dashboard.jpg) | [screenshot](../../resources/images/stats/performance/realTestCase/beanUtilsLib/dashboard.jpg) | +| JVM stats screenshot | [screenshot](../images/stats/performance/realTestCase/classicTransformer/jvmStats.jpg) | [screenshot](../images/stats/performance/realTestCase/beanUtilsLib/jvmStats.jpg) | +| Dashboard screenshot | [screenshot](../images/stats/performance/realTestCase/classicTransformer/dashboard.jpg) | [screenshot](../images/stats/performance/realTestCase/beanUtilsLib/dashboard.jpg) | diff --git a/docs/site/resources/css/site.css b/docs/site/resources/css/site.css index 921ffd190..7e3918357 100644 --- a/docs/site/resources/css/site.css +++ b/docs/site/resources/css/site.css @@ -1,69 +1,3 @@ -body { - margin: 0; - padding: 0; -} - -::-moz-selection, -::selection { - background:#eb3512; - color:#fff; -} - -#banner { - background: #eb3512; - background: -moz-linear-gradient(top, #eb3512 0%, #c11000 100%); - background: -webkit-linear-gradient(top, #eb3512 0%,#c11000 100%); - background: -ms-linear-gradient(top, #eb3512 0%,#c11000 100%); - background: linear-gradient(top, #eb3512 0%,#c11000 100%); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eb3512', EndColorStr='#c11000')"; - border-bottom: 1px solid #9C0C1E; - color: #fff; - position: relative; -} - -#banner img { - margin: 20px 0 8px 15px; -} - -#breadcrumbs { - font-size: small; -} - -.breadcrumb { - padding: 2px 15px; -} - -h1, h2 { - border-bottom: 2px solid #EE3424; -} - -body.topBarDisabled { - padding: 0; -} - -.nav-header { - color: #4E4E4E; - border-bottom: 1px solid #AAA; -} - -.container-fluid { - padding: 0px; -} - -.sidebar-nav { - margin-left: 10px; -} - -#bodyColumn .section { - margin-right: 10px; -} - -a.nolink { - text-decoration: none; - color: black; -} - -table thead tr th { - background-color: #6E7F93; - color: #fff; +img[alt=bull-logo] { + width: 30%; } \ No newline at end of file diff --git a/docs/site/resources/images/hotels_com_logo_en_int_wakeuphappy_small.png b/docs/site/resources/images/hotels_com_logo_en_int_wakeuphappy_small.png deleted file mode 100644 index 097dca67fb5bf917c169b9943700a50a9f5f1b42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4380 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 WOo%b6Y`H!F0000 - - Bean Utils Light Library - images/hotels_com_logo_en_int_wakeuphappy_small.png - org.apache.maven.skins maven-fluido-skin @@ -13,18 +9,21 @@ - false - span2 - span10 + false + true + + BULL + right + gray + - + - diff --git a/pom.xml b/pom.xml index e37752f43..ee9d4cfde 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.15-SNAPSHOT + 1.0-SNAPSHOT jar 2019 @@ -272,6 +272,19 @@ + + org.codehaus.mojo + findbugs-maven-plugin + ${findbugs.maven.plugin.version} + + true + + + + none + + + org.apache.maven.plugins @@ -338,6 +351,15 @@ public + + org.codehaus.mojo + cobertura-maven-plugin + ${cobertura.maven.plugin.version} + true + + true + + From 5ec7e8187462e0ae6bfaf3ca1169ed06b7a6bde5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 16:21:55 +0100 Subject: [PATCH 0018/1786] minor: removed overview file --- docs/site/markdown/overview.md | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 docs/site/markdown/overview.md diff --git a/docs/site/markdown/overview.md b/docs/site/markdown/overview.md deleted file mode 100644 index f242a1a66..000000000 --- a/docs/site/markdown/overview.md +++ /dev/null @@ -1,30 +0,0 @@ - - Overview - - -# Overview - -This BeanUtils library is a utility library for managing Bean objects. The library offers the following components: - - -- #### Bean Transformer: - - is a Java bean copy utility with powerful functionality and high performance. - - ##### Features: - * support copy of immutable beans. - * support copy of mutable beans. - * support copy of hybrid beans (some fields private and some not). - * support copy of Java beans without getter and setter methods. - * support copy with Java primitive type. - * support copy with Java Collection type. e.g. `List => List` - * support copy with nested map fields. e.g. `Map>` - * support copy with array containing primitive types. e.g. `String[]` => `String[]` - * support copy with array type. e.g. `BeanA[]` => `BeanB[]` - * support copy with property name mapping. e.g. `int id => int userId` - * support copy with recursion copy - * support validation through annotations - * support copy of beans with different field's name - * support lambda function field transformation - * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. - * allows to set the default value for all objects not existing in the source object. From 888f745c4c609cc2e412aa6b83035b6b968d2819 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 16:23:56 +0100 Subject: [PATCH 0019/1786] removed not used plugin --- pom.xml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pom.xml b/pom.xml index ee9d4cfde..34789d1d5 100644 --- a/pom.xml +++ b/pom.xml @@ -272,19 +272,6 @@ - - org.codehaus.mojo - findbugs-maven-plugin - ${findbugs.maven.plugin.version} - - true - - - - none - - - org.apache.maven.plugins From bc872a69172e6352066915b31bcf672a51a7d50c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 17:36:14 +0100 Subject: [PATCH 0020/1786] [maven-release-plugin] prepare release bean-utils-library-1.0.15 --- pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 34789d1d5..aa649d2d6 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0-SNAPSHOT + 1.0.15 jar 2019 @@ -50,7 +50,8 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - + bean-utils-library-1.0.15 + From 7068374ae6777e4ee9f587e4003591469fcbfdcb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 17:36:23 +0100 Subject: [PATCH 0021/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index aa649d2d6..745fca622 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.15 + 1.0.16-SNAPSHOT jar 2019 @@ -50,7 +50,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.15 + HEAD From b560cea7409ffafd977e93614e748add043a0b73 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 17:44:01 +0100 Subject: [PATCH 0022/1786] restored version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 745fca622..6273cbfb3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.16-SNAPSHOT + 1.0-SNAPSHOT jar 2019 From c4418c7aad460cb72c7438929ae806f38564abb2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 18:08:06 +0100 Subject: [PATCH 0023/1786] Added basic travis configuration --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100755 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100755 index 000000000..45f5ff80f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: java +jdk: + - openjdk11 +cache: + directories: + - ~/.m2/repository +install: + - mvn clean install From 856f7923ed5ffb5dc6fc543e9c59c7c8afcf2252 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 18:12:51 +0100 Subject: [PATCH 0024/1786] modified travis jdk --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 45f5ff80f..12db5ea77 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - openjdk11 + - oraclejdk11 cache: directories: - ~/.m2/repository From 8a4559d82c96bec936ad929fee036bdee9e4cd80 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 18:16:25 +0100 Subject: [PATCH 0025/1786] downgraded build jdk version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 12db5ea77..ea855bf6c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - oraclejdk11 + - oraclejdk8 cache: directories: - ~/.m2/repository From 72f2e0106dbb07ef6dddf217fa711e7b5d4981d4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 18:19:57 +0100 Subject: [PATCH 0026/1786] - Increases jdk version - Added javadoc and test skip --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ea855bf6c..4f17eddd7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ language: java jdk: - - oraclejdk8 + - openjdk11 cache: directories: - ~/.m2/repository install: - - mvn clean install + - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true From 7319943cfcf7c462fe8d24ba78602cef4a55a02f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 18:29:43 +0100 Subject: [PATCH 0027/1786] Added sonar cloud build --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4f17eddd7..99c57aca3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,3 +6,5 @@ cache: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true +script: + - mvn clean deploy sonar:sonar -Dsonar.projectKey=${sonar.projectKey} -Dsonar.organization=${sonar.organization} -Dsonar.host.url=${sonar.host.url} -Dsonar.login=${sonar.token} From a51842b0a7292f8ef0ee8c425dfa1a307eae7702 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 18:31:04 +0100 Subject: [PATCH 0028/1786] removed clean before sonar data publish --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 99c57aca3..c6f4a54c4 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,4 @@ cache: install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true script: - - mvn clean deploy sonar:sonar -Dsonar.projectKey=${sonar.projectKey} -Dsonar.organization=${sonar.organization} -Dsonar.host.url=${sonar.host.url} -Dsonar.login=${sonar.token} + - mvn deploy sonar:sonar -Dsonar.projectKey=${sonar.projectKey} -Dsonar.organization=${sonar.organization} -Dsonar.host.url=${sonar.host.url} -Dsonar.login=${sonar.token} From b09f57b38828928cd5f7e1881bd0bac461c63e89 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 18:35:09 +0100 Subject: [PATCH 0029/1786] modified sonar deploy config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c6f4a54c4..39bac2ee7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,4 @@ cache: install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true script: - - mvn deploy sonar:sonar -Dsonar.projectKey=${sonar.projectKey} -Dsonar.organization=${sonar.organization} -Dsonar.host.url=${sonar.host.url} -Dsonar.login=${sonar.token} + - mvn deploy sonar:sonar -Dsonar.projectKey=${sonar.projectKey} -Dsonar.organization=${sonar.organization} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${sonar.token} From 7d9e92785f79e9b1f5f0e41d84870b1f2a09cf7f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jan 2019 18:39:48 +0100 Subject: [PATCH 0030/1786] modified travis env variables and script configuration --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 39bac2ee7..8eff2bdb0 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,4 @@ cache: install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true script: - - mvn deploy sonar:sonar -Dsonar.projectKey=${sonar.projectKey} -Dsonar.organization=${sonar.organization} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${sonar.token} + - mvn deploy sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} From 5a4f1d6df3eb03eec3b780926254fd281ccb4caa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 09:31:26 +0100 Subject: [PATCH 0031/1786] - Modified travis configuration - Added changelog information - Added documentation link into readme file --- .travis.yml | 2 +- README.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8eff2bdb0..3d8891454 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - openjdk11 + - oraclejdk11 cache: directories: - ~/.m2/repository diff --git a/README.md b/README.md index ff7e6ee54..5da516f7d 100644 --- a/README.md +++ b/README.md @@ -284,6 +284,10 @@ _[*] Immutable types are not supported by Dozer. When a type doesn't have a no-a Workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ _[+] Requires a custom configuration_ +## Documentation + +A detailed project documentation is available [here](https://hotelsdotcom.github.io/bull). + ## Credits Created by: [Fabio Borriello](https://github.com/fborriello) with the contribution of: [Patrizio Munzi](https://github.com/patriziomunzi), From 8d4683b17b1d916bd927100c83b563d07da314c8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 09:49:00 +0100 Subject: [PATCH 0032/1786] trying fixing travis build --- pom.xml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 34789d1d5..e356c09f1 100644 --- a/pom.xml +++ b/pom.xml @@ -335,18 +335,10 @@ org.apache.maven.plugins maven-javadoc-plugin + 8 public - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura.maven.plugin.version} - true - - true - - From c40536586eb3fb217e2a455c8abf3839496f8ee5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 10:00:34 +0100 Subject: [PATCH 0033/1786] added double jdk --- .travis.yml | 5 ++++- pom.xml | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3d8891454..8bccb8535 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,13 @@ language: java jdk: + - oraclejdk8 - oraclejdk11 +os: + - linux cache: directories: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true script: - - mvn deploy sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - mvn test deploy sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} diff --git a/pom.xml b/pom.xml index e356c09f1..502c14b8f 100644 --- a/pom.xml +++ b/pom.xml @@ -335,7 +335,6 @@ org.apache.maven.plugins maven-javadoc-plugin - 8 public From c712d8ecfcbda324b8b4722694024df1f58f8d90 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 10:06:27 +0100 Subject: [PATCH 0034/1786] Modifying travis config --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8bccb8535..6b31f7454 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: java jdk: - - oraclejdk8 - oraclejdk11 os: - linux @@ -10,4 +9,4 @@ cache: install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true script: - - mvn test deploy sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - mvn deploy sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} From 17a52276fd4c15d243b1433e1551dc423a75713e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 10:09:32 +0100 Subject: [PATCH 0035/1786] removed sonar build --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6b31f7454..7cecbf8fe 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,5 @@ cache: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -script: - - mvn deploy sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +#script: +# - mvn deploy sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} From d9fd230b44cc114a2f605bca856f34812a018bd1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 10:12:57 +0100 Subject: [PATCH 0036/1786] added sonar deploy --- .travis.yml | 2 +- CHANGELOG.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7cecbf8fe..2cc64dceb 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,5 @@ cache: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true + - mvn test deploy sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url}-Dsonar.login=${sonar_token} #script: -# - mvn deploy sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} diff --git a/CHANGELOG.md b/CHANGELOG.md index e1ea5696f..dada0ad72 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.0.15] +#### Added +* Added GitHub site build with maven. + ### [1.0.14] #### Added * Added possibility to configure the transformer in order to set the default value for all destination's object fields that are not existing in the source object. From c7c1427103b3f436aca2e6ee9dda5936c2480713 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 10:18:13 +0100 Subject: [PATCH 0037/1786] removed sonar push --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2cc64dceb..4d87cbb7d 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,5 @@ cache: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - - mvn test deploy sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url}-Dsonar.login=${sonar_token} #script: + #- mvn test deploy sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url}-Dsonar.login=${sonar_token} From 6895ac22f73b1963c69da38040e5af60629b55c3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 10:23:27 +0100 Subject: [PATCH 0038/1786] Added sonar cloud stats push --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4d87cbb7d..ae3569af2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,6 @@ cache: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -#script: - #- mvn test deploy sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url}-Dsonar.login=${sonar_token} + - mvn test -Dmaven.javadoc.skip=true sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url}-Dsonar.login=${sonar_token} +script: + #- mvn sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url}-Dsonar.login=${sonar_token} From a43e333854058197dadb4aeb02e2e3bf4d0c9213 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 10:26:56 +0100 Subject: [PATCH 0039/1786] fixed space --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ae3569af2..b7e44576c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,6 @@ cache: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - - mvn test -Dmaven.javadoc.skip=true sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url}-Dsonar.login=${sonar_token} + - mvn test -Dmaven.javadoc.skip=true sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} script: #- mvn sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url}-Dsonar.login=${sonar_token} From f97aa2876a87d9434a160936232f3400de6040d5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 10:33:23 +0100 Subject: [PATCH 0040/1786] removed travis script --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b7e44576c..333e68dbc 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - oraclejdk11 + - openjdk11 os: - linux cache: @@ -8,6 +8,4 @@ cache: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - - mvn test -Dmaven.javadoc.skip=true sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -script: - #- mvn sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url}-Dsonar.login=${sonar_token} + - mvn sonar:sonar -Dmaven.javadoc.skip=true sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} From f88a1cb07a7b41f3705b8b58931165144f477acf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 15:41:41 +0100 Subject: [PATCH 0041/1786] - Modified travis config in order to build the site too - Updated changelog with the latest changes - added documentation link into readme file --- .travis.yml | 3 ++- CHANGELOG.md | 21 ++++++++++++++------- README.md | 3 +++ config/travis/mvn-settings.xml | 20 ++++++++++++++++++++ pom.xml | 4 ++-- 5 files changed, 41 insertions(+), 10 deletions(-) create mode 100755 config/travis/mvn-settings.xml diff --git a/.travis.yml b/.travis.yml index 333e68dbc..d4c665bff 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,4 +8,5 @@ cache: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - - mvn sonar:sonar -Dmaven.javadoc.skip=true sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - mvn test sonar:sonar -Dmaven.javadoc.skip=true sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - mvn site --settings config/travis/mvn-settings.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index dada0ad72..f6c03992c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,29 +2,36 @@ All notable changes to this project will be documented in this file. -### [1.0.15] +### [1.0.16] TBD +#### Changed +* Updated `hotels-oss-parent` version to `3.0.0` (was `2.3.5`). +#### Added +* Configured Travis in order to automatically build the application and build the site. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) +* Added build, test coverage and security badge to readme file. + +### [1.0.15] 2019.01.23 #### Added * Added GitHub site build with maven. -### [1.0.14] +### [1.0.14] 2019.01.18 #### Added * Added possibility to configure the transformer in order to set the default value for all destination's object fields that are not existing in the source object. See [README.md](https://github.com/HotelsDotCom/bull/blob/master/README.md) for more details. #### Changed -* Jumped to version **1.0.14** in order to be consequent to the previous library version hosted on a private repo. +* Jumped to version `1.0.14` in order to be consequent to the previous library version hosted on a private repo. -### [1.0.3] +### [1.0.3] 2019.01.17 #### Added * Added changelog file. -### [1.0.2] +### [1.0.2] 2019.01.17 #### Changed * Removed not needed comments -### [1.0.1] +### [1.0.1] 2019.01.17 #### Changed * Added maven build info to the readme file. -### [1.0.0] +### [1.0.0] 2019.01.16 #### Added * First `BULL` release. diff --git a/README.md b/README.md index 5da516f7d..42ba83401 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou ## Start using [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=com.hotels.beans:bean-utils-library)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) +[![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) You can obtain BULL from Maven Central: diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml new file mode 100755 index 000000000..9de5c81ca --- /dev/null +++ b/config/travis/mvn-settings.xml @@ -0,0 +1,20 @@ + + + + + sonatype-nexus-snapshots + ${sonatype_username} + ${sonatype_password} + + + sonatype-nexus-staging + ${sonatype_username} + ${sonatype_password} + + + + ${github_server_id} + ${github_oauth_token} + + + diff --git a/pom.xml b/pom.xml index 502c14b8f..152ff31fc 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0-SNAPSHOT + 1.0.15 jar 2019 @@ -15,7 +15,7 @@ com.hotels hotels-oss-parent - 2.3.5 + 3.0.0 From 8fdc2f41d4b4dd17db7852d9508d17ef2ea6588b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 17:10:02 +0100 Subject: [PATCH 0042/1786] Modified travis config --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d4c665bff..d2db2a04b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - openjdk11 + - oraclejdk8 os: - linux cache: @@ -8,5 +8,5 @@ cache: - ~/.m2/repository install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - - mvn test sonar:sonar -Dmaven.javadoc.skip=true sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - mvn site --settings config/travis/mvn-settings.xml + - mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - mvn site --settings config/travis/mvn-settings.xml -Dmaven.javadoc.skip=true From 5acb968156a53c1fa4913bd160092bcb5408d0ae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 17:49:46 +0100 Subject: [PATCH 0043/1786] Added travis site build --- .travis.yml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d2db2a04b..657108296 100755 --- a/.travis.yml +++ b/.travis.yml @@ -9,4 +9,4 @@ cache: install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - mvn site --settings config/travis/mvn-settings.xml -Dmaven.javadoc.skip=true + - mvn site --settings config/travis/mvn-settings.xml diff --git a/pom.xml b/pom.xml index 152ff31fc..e48487115 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ com.hotels hotels-oss-parent - 3.0.0 + 3.0.1 From adf939dd8feea2ce9107f31665f937a9c4edfe85 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jan 2019 18:02:31 +0100 Subject: [PATCH 0044/1786] modified travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 657108296..1b53c7106 100755 --- a/.travis.yml +++ b/.travis.yml @@ -9,4 +9,4 @@ cache: install: - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - mvn site --settings config/travis/mvn-settings.xml + - mvn clean install site --settings config/travis/mvn-settings.xml From a979dcc62adda0eb969aee26ce66ba8559961ebb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 09:50:01 +0100 Subject: [PATCH 0045/1786] Testing travis config with conditional stages --- .travis.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1b53c7106..ef791acac 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,24 @@ language: java jdk: - - oraclejdk8 + - openjdk11 os: - linux cache: directories: - ~/.m2/repository -install: - - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - - mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - mvn clean install site --settings config/travis/mvn-settings.xml +#install: +# - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true +# - mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - mvn clean install site --settings config/travis/mvn-settings.xml +jobs: + include: + - stage: "Build" + name: "Build" + install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true + - stage: "Test" + name: "Test" + install: mvn test -Dmaven.javadoc.skip=true + - stage: "QualityCheck" + if: branch = master + name: "Quality check" + install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} From 7332caa68adc9a21556f36f5d14af2a66c794b14 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 10:53:18 +0100 Subject: [PATCH 0046/1786] Restored project pom version --- .travis.yml | 8 ++++++-- pom.xml | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ef791acac..faaea4ce3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,11 @@ jobs: - stage: "Test" name: "Test" install: mvn test -Dmaven.javadoc.skip=true - - stage: "QualityCheck" + - stage: "Quality Check" if: branch = master - name: "Quality check" + name: "Sonar check" install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Deploy" +# if: branch = master +# name: "Deploy" +# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} diff --git a/pom.xml b/pom.xml index e48487115..abd2a1e38 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.15 + 1.0-SNAPSHOT jar 2019 From 9792b73b6c6b6f317f401d9b801cf38345ea714a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 11:10:16 +0100 Subject: [PATCH 0047/1786] Added specific config for bamboo --- config/bamboo/mvn-settings.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100755 config/bamboo/mvn-settings.xml diff --git a/config/bamboo/mvn-settings.xml b/config/bamboo/mvn-settings.xml new file mode 100755 index 000000000..743498bf0 --- /dev/null +++ b/config/bamboo/mvn-settings.xml @@ -0,0 +1,20 @@ + + + + + sonatype-nexus-snapshots + ${bamboo.sonatype_username} + ${bamboo.sonatype_password} + + + sonatype-nexus-staging + ${bamboo.sonatype_username} + ${bamboo.sonatype_password} + + + + ${bamboo.github_server_id} + ${bamboo.github_oauth_token} + + + From 653ff0ed1daed75f2a5d8e3397a0f8dec7014d9d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 12:08:34 +0100 Subject: [PATCH 0048/1786] Added travis site build --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index faaea4ce3..a98bba2fe 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - openjdk11 + - oraclejdk8 os: - linux cache: @@ -22,6 +22,9 @@ jobs: if: branch = master name: "Sonar check" install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build" + name: "GitHub Site Build and Publish" + install: travis_wait 50 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true # - stage: "Deploy" # if: branch = master # name: "Deploy" From 397ca8690c9a4c4b8f788651cb800cab61a6e70d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 12:21:06 +0100 Subject: [PATCH 0049/1786] removed travis wait --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a98bba2fe..1fd1f21a8 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ cache: # - mvn clean install site --settings config/travis/mvn-settings.xml jobs: include: - - stage: "Build" + - stage: "Build & Test" name: "Build" install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - stage: "Test" @@ -24,7 +24,7 @@ jobs: install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build" name: "GitHub Site Build and Publish" - install: travis_wait 50 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true + install: mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true # - stage: "Deploy" # if: branch = master # name: "Deploy" From 17225497f50c93d175d0f4c945a4b0d0441521af Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 14:19:10 +0100 Subject: [PATCH 0050/1786] Added travis wait --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1fd1f21a8..7facb8628 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ cache: # - mvn clean install site --settings config/travis/mvn-settings.xml jobs: include: - - stage: "Build & Test" + - stage: "Build" name: "Build" install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - stage: "Test" @@ -24,7 +24,7 @@ jobs: install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build" name: "GitHub Site Build and Publish" - install: mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true + install: travis_wait mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true # - stage: "Deploy" # if: branch = master # name: "Deploy" From 2f55031389b0eb39cd58f516154e0eb131db2d44 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 14:30:59 +0100 Subject: [PATCH 0051/1786] testing travis --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7facb8628..8e78f9415 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,8 @@ jobs: include: - stage: "Build" name: "Build" - install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true +# install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true + install: travis_wait clean install -DskipTests=true -Dmaven.javadoc.skip=true - stage: "Test" name: "Test" install: mvn test -Dmaven.javadoc.skip=true From b94c29255d9ed84b153416adb8f4178f3734aff5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 14:33:02 +0100 Subject: [PATCH 0052/1786] fixed command --- .travis.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8e78f9415..390991f33 100755 --- a/.travis.yml +++ b/.travis.yml @@ -15,17 +15,17 @@ jobs: - stage: "Build" name: "Build" # install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - install: travis_wait clean install -DskipTests=true -Dmaven.javadoc.skip=true - - stage: "Test" - name: "Test" - install: mvn test -Dmaven.javadoc.skip=true - - stage: "Quality Check" - if: branch = master - name: "Sonar check" - install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build" - name: "GitHub Site Build and Publish" - install: travis_wait mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true + install: travis_wait mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true +# - stage: "Test" +# name: "Test" +# install: mvn test -Dmaven.javadoc.skip=true +# - stage: "Quality Check" +# if: branch = master +# name: "Sonar check" +# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build" +# name: "GitHub Site Build and Publish" +# install: travis_wait mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true # - stage: "Deploy" # if: branch = master # name: "Deploy" From e0610068b026b537cd9fdb5b26488aca704e0b50 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 14:44:25 +0100 Subject: [PATCH 0053/1786] testing github pages build --- .travis.yml | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 390991f33..05000fad4 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,26 +6,29 @@ os: cache: directories: - ~/.m2/repository -#install: -# - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -# - mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - mvn clean install site --settings config/travis/mvn-settings.xml jobs: include: - stage: "Build" name: "Build" -# install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - install: travis_wait mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true + install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true # - stage: "Test" # name: "Test" # install: mvn test -Dmaven.javadoc.skip=true -# - stage: "Quality Check" -# if: branch = master -# name: "Sonar check" -# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Quality Check" + if: branch = master + name: "Sonar check" + install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Deploy" + deploy: + provider: pages + skip-cleanup: true + github-token: $github_oauth_token + keep-history: true + on: + branch: master # - stage: "Site Build" # name: "GitHub Site Build and Publish" -# install: travis_wait mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true +# install: travis_wait 60 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true # - stage: "Deploy" # if: branch = master # name: "Deploy" From d22f541d31ac1673e41335e90237c71be64c4343 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 14:51:06 +0100 Subject: [PATCH 0054/1786] added deploy only --- .travis.yml | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05000fad4..3901b81f4 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,26 +6,18 @@ os: cache: directories: - ~/.m2/repository -jobs: - include: - - stage: "Build" - name: "Build" - install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true +#jobs: +# include: +# - stage: "Build" +# name: "Build" +# install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true # - stage: "Test" # name: "Test" # install: mvn test -Dmaven.javadoc.skip=true - - stage: "Quality Check" - if: branch = master - name: "Sonar check" - install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Deploy" - deploy: - provider: pages - skip-cleanup: true - github-token: $github_oauth_token - keep-history: true - on: - branch: master +# - stage: "Quality Check" +# if: branch = master +# name: "Sonar check" +# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} # - stage: "Site Build" # name: "GitHub Site Build and Publish" # install: travis_wait 60 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true @@ -33,3 +25,10 @@ jobs: # if: branch = master # name: "Deploy" # install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +deploy: + provider: pages + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + branch: master \ No newline at end of file From ec274198e9ac7231142eb82f81f51e7fcc56574a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 14:53:52 +0100 Subject: [PATCH 0055/1786] changed branch --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3901b81f4..2e6d7bd14 100755 --- a/.travis.yml +++ b/.travis.yml @@ -31,4 +31,4 @@ deploy: github-token: ${github_oauth_token} keep-history: true on: - branch: master \ No newline at end of file + branch: feature/travis-configuration \ No newline at end of file From 5aab43117f027180f1c3dcb2135bd12dbe233dee Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 15:02:55 +0100 Subject: [PATCH 0056/1786] Added Github site pages build. Testing feature --- .travis.yml | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2e6d7bd14..2b2f3c4c7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,29 +6,30 @@ os: cache: directories: - ~/.m2/repository -#jobs: -# include: -# - stage: "Build" -# name: "Build" -# install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -# - stage: "Test" -# name: "Test" -# install: mvn test -Dmaven.javadoc.skip=true -# - stage: "Quality Check" +jobs: + include: + - stage: "Build" + name: "Build" + install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true + - stage: "Test" + name: "Test" + install: mvn test -Dmaven.javadoc.skip=true + - stage: "Quality Check" + if: branch = master + name: "Sonar check" + install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build" # if: branch = master -# name: "Sonar check" -# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build" -# name: "GitHub Site Build and Publish" -# install: travis_wait 60 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true + name: "GitHub Site Build and Publish" + install: travis_wait 60 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true # - stage: "Deploy" # if: branch = master # name: "Deploy" # install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -deploy: - provider: pages - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true - on: - branch: feature/travis-configuration \ No newline at end of file +#deploy: +# provider: pages +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# branch: feature/travis-configuration \ No newline at end of file From 06ba5b935c2cbe2478d3f4148ac54a6b8541444b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 15:08:46 +0100 Subject: [PATCH 0057/1786] trying to specify a specific jdk version for each step --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2b2f3c4c7..6d706d145 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - oraclejdk8 + - openjdk11 os: - linux cache: @@ -21,6 +21,8 @@ jobs: - stage: "Site Build" # if: branch = master name: "GitHub Site Build and Publish" + jdk: + - oraclejdk8 install: travis_wait 60 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true # - stage: "Deploy" # if: branch = master From 69d3d43a71b7e543af03a3609aa001139648e833 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 15:27:21 +0100 Subject: [PATCH 0058/1786] Set build with java 8 --- .travis.yml | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6d706d145..c0595949e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - openjdk11 + - oraclejdk8 os: - linux cache: @@ -21,17 +21,4 @@ jobs: - stage: "Site Build" # if: branch = master name: "GitHub Site Build and Publish" - jdk: - - oraclejdk8 - install: travis_wait 60 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true -# - stage: "Deploy" -# if: branch = master -# name: "Deploy" -# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -#deploy: -# provider: pages -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true -# on: -# branch: feature/travis-configuration \ No newline at end of file + install: travis_wait 60 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true \ No newline at end of file From 4d8f15d6ad5498909b571e5e29165d45cb6cea5a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 15:28:31 +0100 Subject: [PATCH 0059/1786] specified lib version temporary --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index abd2a1e38..e48487115 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0-SNAPSHOT + 1.0.15 jar 2019 From fc9d21392d16111b29b98e990460814ee7955db4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 16:05:15 +0100 Subject: [PATCH 0060/1786] testing site build --- .travis.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index c0595949e..427778239 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,17 +8,17 @@ cache: - ~/.m2/repository jobs: include: - - stage: "Build" - name: "Build" - install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - - stage: "Test" - name: "Test" - install: mvn test -Dmaven.javadoc.skip=true - - stage: "Quality Check" - if: branch = master - name: "Sonar check" - install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Build" +# name: "Build" +# install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true +# - stage: "Test" +# name: "Test" +# install: mvn test -Dmaven.javadoc.skip=true +# - stage: "Quality Check" +# if: branch = master +# name: "Sonar check" +# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build" # if: branch = master name: "GitHub Site Build and Publish" - install: travis_wait 60 mvn clean install site --settings config/travis/mvn-settings.xml -DskipTests=true \ No newline at end of file + install: travis_wait mvn install site --settings config/travis/mvn-settings.xml -DskipTests=true \ No newline at end of file From 961a9fdf03084036981884cda5461cb64cead5ae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 16:17:31 +0100 Subject: [PATCH 0061/1786] trying to push site --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 427778239..d22ea0170 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,4 +21,4 @@ jobs: - stage: "Site Build" # if: branch = master name: "GitHub Site Build and Publish" - install: travis_wait mvn install site --settings config/travis/mvn-settings.xml -DskipTests=true \ No newline at end of file + script: travis_wait mvn site --settings config/travis/mvn-settings.xml -DskipTests=true \ No newline at end of file From 95780288e217adf014209061155bd473eb616efd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Jan 2019 18:16:52 +0100 Subject: [PATCH 0062/1786] Added Travis configuration for maven site too --- .travis.yml | 24 ++++++++++++------------ config/bamboo/mvn-settings.xml | 20 -------------------- 2 files changed, 12 insertions(+), 32 deletions(-) delete mode 100755 config/bamboo/mvn-settings.xml diff --git a/.travis.yml b/.travis.yml index d22ea0170..b0dfbf551 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,17 +8,17 @@ cache: - ~/.m2/repository jobs: include: -# - stage: "Build" -# name: "Build" -# install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -# - stage: "Test" -# name: "Test" -# install: mvn test -Dmaven.javadoc.skip=true -# - stage: "Quality Check" -# if: branch = master -# name: "Sonar check" -# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Build" + name: "Build" + install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true + - stage: "Test" + name: "Test" + install: mvn test -Dmaven.javadoc.skip=true + - stage: "Quality Check" + if: branch = master + name: "Sonar check" + install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build" -# if: branch = master + if: branch = master name: "GitHub Site Build and Publish" - script: travis_wait mvn site --settings config/travis/mvn-settings.xml -DskipTests=true \ No newline at end of file + script: travis_wait 50 mvn site --settings config/travis/mvn-settings.xml --quiet -DskipTests=true \ No newline at end of file diff --git a/config/bamboo/mvn-settings.xml b/config/bamboo/mvn-settings.xml deleted file mode 100755 index 743498bf0..000000000 --- a/config/bamboo/mvn-settings.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - sonatype-nexus-snapshots - ${bamboo.sonatype_username} - ${bamboo.sonatype_password} - - - sonatype-nexus-staging - ${bamboo.sonatype_username} - ${bamboo.sonatype_password} - - - - ${bamboo.github_server_id} - ${bamboo.github_oauth_token} - - - From 77c094226acebe2ac323dea62b16271056492653 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 07:53:55 +0100 Subject: [PATCH 0063/1786] testing site publish on github page with travis --- .travis.yml | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index b0dfbf551..4e54cce69 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,17 +8,30 @@ cache: - ~/.m2/repository jobs: include: - - stage: "Build" - name: "Build" - install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - - stage: "Test" - name: "Test" - install: mvn test -Dmaven.javadoc.skip=true - - stage: "Quality Check" - if: branch = master - name: "Sonar check" - install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Build" +# name: "Build" +# install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true +# - stage: "Test" +# name: "Test" +# install: mvn test -Dmaven.javadoc.skip=true +# - stage: "Quality Check" +# if: branch = master +# name: "Sonar check" +# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build" +# if: branch = master +# name: "GitHub Site Build and Publish" +# script: travis_wait 50 mvn site --settings config/travis/mvn-settings.xml --quiet -DskipTests=true - stage: "Site Build" - if: branch = master - name: "GitHub Site Build and Publish" - script: travis_wait 50 mvn site --settings config/travis/mvn-settings.xml --quiet -DskipTests=true \ No newline at end of file + name: "Site Build" + script: mvn clean site:site + - stage: "Site Publish" + name: "Publish site on GitHub pages" + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + branch: feature/travis-configuration \ No newline at end of file From 707af5efea410c4e9ddbde6f03cb84d2142be0ea Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 07:59:35 +0100 Subject: [PATCH 0064/1786] modified conf --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4e54cce69..05f1b9f9c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -22,11 +22,9 @@ jobs: # if: branch = master # name: "GitHub Site Build and Publish" # script: travis_wait 50 mvn site --settings config/travis/mvn-settings.xml --quiet -DskipTests=true - - stage: "Site Build" - name: "Site Build" - script: mvn clean site:site - - stage: "Site Publish" + - stage: "Site Build and Publish" name: "Publish site on GitHub pages" + install: mvn clean site:site deploy: provider: pages local-dir: target/site From 6924dffeb1aa9e65eab78433ff7789a9940f6838 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:04:21 +0100 Subject: [PATCH 0065/1786] adeed test skip --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 05f1b9f9c..28f2f1b5d 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: # script: travis_wait 50 mvn site --settings config/travis/mvn-settings.xml --quiet -DskipTests=true - stage: "Site Build and Publish" name: "Publish site on GitHub pages" - install: mvn clean site:site + install: mvn clean site:site -DskipTests=true deploy: provider: pages local-dir: target/site From 177cfe6a9229ecde82b46f1e8fcd94763723fab7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:10:17 +0100 Subject: [PATCH 0066/1786] testing travis with java 11 --- .travis.yml | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 28f2f1b5d..e25a84c0c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: - - oraclejdk8 + - oraclejdk11 os: - linux cache: @@ -8,22 +8,19 @@ cache: - ~/.m2/repository jobs: include: -# - stage: "Build" -# name: "Build" -# install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -# - stage: "Test" -# name: "Test" -# install: mvn test -Dmaven.javadoc.skip=true -# - stage: "Quality Check" -# if: branch = master -# name: "Sonar check" -# install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build" -# if: branch = master -# name: "GitHub Site Build and Publish" -# script: travis_wait 50 mvn site --settings config/travis/mvn-settings.xml --quiet -DskipTests=true + - stage: "Build" + name: "Build" + install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true + - stage: "Test" + name: "Test" + install: mvn test -Dmaven.javadoc.skip=true + - stage: "Quality Check" + if: branch = master + name: "Sonar check" + install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" - name: "Publish site on GitHub pages" + if: branch = master + name: "Build site and publish on GitHub pages" install: mvn clean site:site -DskipTests=true deploy: provider: pages From c67819905332c54994c322f71b839196331810fa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:11:09 +0100 Subject: [PATCH 0067/1786] removed branch condition --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e25a84c0c..5dba5c4e8 100755 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ jobs: name: "Sonar check" install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" - if: branch = master +# if: branch = master name: "Build site and publish on GitHub pages" install: mvn clean site:site -DskipTests=true deploy: From 666b21533c6bbde452db7b1958e43bacc82bd2a2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:20:12 +0100 Subject: [PATCH 0068/1786] testing with specif jdk per each stage --- .travis.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5dba5c4e8..dac5eb22b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java -jdk: - - oraclejdk11 +#jdk: +# - oraclejdk11 os: - linux cache: @@ -10,17 +10,21 @@ jobs: include: - stage: "Build" name: "Build" + jdk: oraclejdk11 install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - stage: "Test" name: "Test" + jdk: oraclejdk11 install: mvn test -Dmaven.javadoc.skip=true - stage: "Quality Check" if: branch = master name: "Sonar check" + jdk: oraclejdk11 install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" # if: branch = master name: "Build site and publish on GitHub pages" + jdk: oraclejdk8 install: mvn clean site:site -DskipTests=true deploy: provider: pages @@ -29,4 +33,7 @@ jobs: github-token: ${github_oauth_token} keep-history: true on: - branch: feature/travis-configuration \ No newline at end of file + branch: feature/travis-configuration +# - stage: "Release" +# name: "Releasing artifacts on Maven central" +# "https://blog.travis-ci.com/2017-03-30-deploy-maven-travis-ci-packagecloud/" \ No newline at end of file From 667b2fe6d9788eca050ead5548c0269f68934770 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:29:17 +0100 Subject: [PATCH 0069/1786] Added final site build configuration --- .travis.yml | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index dac5eb22b..9fadd1acd 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,4 @@ language: java -#jdk: -# - oraclejdk11 os: - linux cache: @@ -9,23 +7,19 @@ cache: jobs: include: - stage: "Build" - name: "Build" + name: "Build and Test" jdk: oraclejdk11 - install: mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true - - stage: "Test" - name: "Test" - jdk: oraclejdk11 - install: mvn test -Dmaven.javadoc.skip=true + install: mvn clean install -Dmaven.javadoc.skip=true -B - stage: "Quality Check" if: branch = master name: "Sonar check" jdk: oraclejdk11 - install: mvn test sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" -# if: branch = master - name: "Build site and publish on GitHub pages" + if: branch = master + name: "Site build and publish on GitHub pages" jdk: oraclejdk8 - install: mvn clean site:site -DskipTests=true + install: mvn clean site:site -DskipTests=true -B deploy: provider: pages local-dir: target/site From ce43f0e734fb90c3e451e6daef7889f4d0f408bb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:34:51 +0100 Subject: [PATCH 0070/1786] testing release --- .travis.yml | 3 +++ pom.xml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9fadd1acd..f1cdfa8ad 100755 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,9 @@ jobs: keep-history: true on: branch: feature/travis-configuration + - stage: "Release" + name: "Releasing artifacts on Maven central" + script: mvn deploy --settings config/travis/mvn-settings.xml -DskipTests=true -B # - stage: "Release" # name: "Releasing artifacts on Maven central" # "https://blog.travis-ci.com/2017-03-30-deploy-maven-travis-ci-packagecloud/" \ No newline at end of file diff --git a/pom.xml b/pom.xml index e48487115..f839b1743 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.15 + 1.0.4 jar 2019 From e787c0f0f9b496fce4d1abba8bb31edee62312ca Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:35:35 +0100 Subject: [PATCH 0071/1786] specified jdk --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f1cdfa8ad..3d088ecb7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,7 @@ jobs: branch: feature/travis-configuration - stage: "Release" name: "Releasing artifacts on Maven central" + jdk: oraclejdk11 script: mvn deploy --settings config/travis/mvn-settings.xml -DskipTests=true -B # - stage: "Release" # name: "Releasing artifacts on Maven central" From 3c6440d67e5e03bc7436777e4006cbbad25f41a6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:43:09 +0100 Subject: [PATCH 0072/1786] testing release --- .travis.yml | 55 +++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3d088ecb7..ea64650cd 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,32 +6,37 @@ cache: - ~/.m2/repository jobs: include: - - stage: "Build" - name: "Build and Test" - jdk: oraclejdk11 - install: mvn clean install -Dmaven.javadoc.skip=true -B - - stage: "Quality Check" - if: branch = master - name: "Sonar check" - jdk: oraclejdk11 - install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build and Publish" - if: branch = master - name: "Site build and publish on GitHub pages" - jdk: oraclejdk8 - install: mvn clean site:site -DskipTests=true -B - deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true - on: - branch: feature/travis-configuration +# - stage: "Build" +# name: "Build and Test" +# jdk: oraclejdk11 +# install: mvn clean install -Dmaven.javadoc.skip=true -B +# - stage: "Quality Check" +# if: branch = master +# name: "Sonar check" +# jdk: oraclejdk11 +# install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build and Publish" +# if: branch = master +# name: "Site build and publish on GitHub pages" +# jdk: oraclejdk8 +# install: mvn clean site:site -DskipTests=true -B +# deploy: +# provider: pages +# local-dir: target/site +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# branch: feature/travis-configuration - stage: "Release" name: "Releasing artifacts on Maven central" - jdk: oraclejdk11 - script: mvn deploy --settings config/travis/mvn-settings.xml -DskipTests=true -B + jdk: oraclejdk8 + script: mvn deploy --settings config/travis/mvn-settings.xml -DskipTests=true -B -DskipTests # - stage: "Release" # name: "Releasing artifacts on Maven central" -# "https://blog.travis-ci.com/2017-03-30-deploy-maven-travis-ci-packagecloud/" \ No newline at end of file +# "https://blog.travis-ci.com/2017-03-30-deploy-maven-travis-ci-packagecloud/" +#deploy: +# provider: script +# script: "mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -B -U -P release --settings travis/settings.xml" +# on: +# tags: true \ No newline at end of file From 773463e2da6f03c3ad9b118e9e5e77b145cca98c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:48:48 +0100 Subject: [PATCH 0073/1786] modified release script --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ea64650cd..62518afa0 100755 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,11 @@ jobs: - stage: "Release" name: "Releasing artifacts on Maven central" jdk: oraclejdk8 - script: mvn deploy --settings config/travis/mvn-settings.xml -DskipTests=true -B -DskipTests + deploy: + provider: script + script: mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -B -U -P -DskipTests=true release --settings config/travis/mvn-settings.xml + on: + tags: true # - stage: "Release" # name: "Releasing artifacts on Maven central" # "https://blog.travis-ci.com/2017-03-30-deploy-maven-travis-ci-packagecloud/" From 2c5d6e18decd9c5ef7e8911a8911afb039af773b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:49:37 +0100 Subject: [PATCH 0074/1786] added skipCleanup --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 62518afa0..b81fe9919 100755 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ jobs: jdk: oraclejdk8 deploy: provider: script + skip_cleanup: true script: mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -B -U -P -DskipTests=true release --settings config/travis/mvn-settings.xml on: tags: true From 1b3622eb08d0a14272cac3664dea464820b7f12c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:52:53 +0100 Subject: [PATCH 0075/1786] set deploy --- .travis.yml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index b81fe9919..77ee5bdc1 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,13 +11,13 @@ jobs: # jdk: oraclejdk11 # install: mvn clean install -Dmaven.javadoc.skip=true -B # - stage: "Quality Check" -# if: branch = master -# name: "Sonar check" +# name: "Sonar check" +# if: branch = master # jdk: oraclejdk11 # install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} # - stage: "Site Build and Publish" -# if: branch = master -# name: "Site build and publish on GitHub pages" +# name: "Site build and publish on GitHub pages" +# if: branch = master # jdk: oraclejdk8 # install: mvn clean site:site -DskipTests=true -B # deploy: @@ -30,13 +30,11 @@ jobs: # branch: feature/travis-configuration - stage: "Release" name: "Releasing artifacts on Maven central" + # if: branch = master jdk: oraclejdk8 - deploy: - provider: script - skip_cleanup: true - script: mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -B -U -P -DskipTests=true release --settings config/travis/mvn-settings.xml - on: - tags: true + script: mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -B -U -P -DskipTests=true release --settings config/travis/mvn-settings.xml + on: + tags: true # - stage: "Release" # name: "Releasing artifacts on Maven central" # "https://blog.travis-ci.com/2017-03-30-deploy-maven-travis-ci-packagecloud/" From fa01ccf41fc5108ec364202326c7beceb790b0ff Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 08:56:43 +0100 Subject: [PATCH 0076/1786] added push imageTag option --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 77ee5bdc1..aaeec1ed1 100755 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ jobs: name: "Releasing artifacts on Maven central" # if: branch = master jdk: oraclejdk8 - script: mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -B -U -P -DskipTests=true release --settings config/travis/mvn-settings.xml + script: mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -DforceTags -DpushImageTag -B -U -P -DskipTests=true release --settings config/travis/mvn-settings.xml on: tags: true # - stage: "Release" From aaec0b7608357391bdd917b2a9ffa210486a7d93 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 09:00:53 +0100 Subject: [PATCH 0077/1786] Completed Travis build, quality check and site release with travis --- .travis.yml | 57 ++++++++++++++++++++--------------------------------- pom.xml | 2 +- 2 files changed, 22 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index aaeec1ed1..1348414fe 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,40 +6,25 @@ cache: - ~/.m2/repository jobs: include: -# - stage: "Build" -# name: "Build and Test" -# jdk: oraclejdk11 -# install: mvn clean install -Dmaven.javadoc.skip=true -B -# - stage: "Quality Check" -# name: "Sonar check" -# if: branch = master -# jdk: oraclejdk11 -# install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build and Publish" -# name: "Site build and publish on GitHub pages" -# if: branch = master -# jdk: oraclejdk8 -# install: mvn clean site:site -DskipTests=true -B -# deploy: -# provider: pages -# local-dir: target/site -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true -# on: -# branch: feature/travis-configuration - - stage: "Release" - name: "Releasing artifacts on Maven central" - # if: branch = master + - stage: "Build" + name: "Build and Test" + jdk: oraclejdk11 + install: mvn clean install -Dmaven.javadoc.skip=true -B + - stage: "Quality Check" + name: "Sonar check" + if: branch = master + jdk: oraclejdk11 + install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build and Publish" + name: "Site build and publish on GitHub pages" + if: branch = master jdk: oraclejdk8 - script: mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -DforceTags -DpushImageTag -B -U -P -DskipTests=true release --settings config/travis/mvn-settings.xml - on: - tags: true -# - stage: "Release" -# name: "Releasing artifacts on Maven central" -# "https://blog.travis-ci.com/2017-03-30-deploy-maven-travis-ci-packagecloud/" -#deploy: -# provider: script -# script: "mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -B -U -P release --settings travis/settings.xml" -# on: -# tags: true \ No newline at end of file + install: mvn clean site:site -DskipTests=true -B + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + branch: feature/travis-configuration \ No newline at end of file diff --git a/pom.xml b/pom.xml index f839b1743..abd2a1e38 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.4 + 1.0-SNAPSHOT jar 2019 From 1522cfbef0346df29177349ab75cec4169a80ae4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 09:02:46 +0100 Subject: [PATCH 0078/1786] updated changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6c03992c..e87e449af 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,12 @@ All notable changes to this project will be documented in this file. -### [1.0.16] TBD +### [1.0.16] 2019.01.26 #### Changed * Updated `hotels-oss-parent` version to `3.0.0` (was `2.3.5`). #### Added -* Configured Travis in order to automatically build the application and build the site. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) +* Configured Travis in order to automatically build the application, perform a quality check and publish the site. Travis build site available [here](https://travis-ci +.org/HotelsDotCom/bull) * Added build, test coverage and security badge to readme file. ### [1.0.15] 2019.01.23 From 674cce23d5e070c39e1527381ace99d8237db0ac Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 09:05:49 +0100 Subject: [PATCH 0079/1786] fixed travis indentation --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1348414fe..b9cb02576 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,13 +11,13 @@ jobs: jdk: oraclejdk11 install: mvn clean install -Dmaven.javadoc.skip=true -B - stage: "Quality Check" - name: "Sonar check" - if: branch = master + name: "Sonar check" + if: branch = master jdk: oraclejdk11 install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" - name: "Site build and publish on GitHub pages" - if: branch = master + name: "Site build and publish on GitHub pages" + if: branch = master jdk: oraclejdk8 install: mvn clean site:site -DskipTests=true -B deploy: From 4834ba472086f1aceae8ea3843f7147f5cfe95c1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 09:08:06 +0100 Subject: [PATCH 0080/1786] fixed travis config indentation --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1348414fe..b9cb02576 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,13 +11,13 @@ jobs: jdk: oraclejdk11 install: mvn clean install -Dmaven.javadoc.skip=true -B - stage: "Quality Check" - name: "Sonar check" - if: branch = master + name: "Sonar check" + if: branch = master jdk: oraclejdk11 install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" - name: "Site build and publish on GitHub pages" - if: branch = master + name: "Site build and publish on GitHub pages" + if: branch = master jdk: oraclejdk8 install: mvn clean site:site -DskipTests=true -B deploy: From 650ff4d7ab9ae747466256c35c0400cf6f46f17c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 09:10:45 +0100 Subject: [PATCH 0081/1786] [maven-release-plugin] prepare release bean-utils-library-1.0.16 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7bd01f896..4bf48726b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0-SNAPSHOT + 1.0.16 jar 2019 @@ -50,7 +50,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + bean-utils-library-1.0.16 From 42d5f209dae658ab059cc2ac3f88bde19884efa9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 09:10:52 +0100 Subject: [PATCH 0082/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4bf48726b..128c97942 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.16 + 1.0.17-SNAPSHOT jar 2019 @@ -50,7 +50,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.16 + HEAD From 850ba622da8df7123752c91bc8d728779add9e66 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 16:42:39 +0100 Subject: [PATCH 0083/1786] release testing --- .travis.yml | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index b9cb02576..9f68e1c60 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: java +jdk: oraclejdk11 os: - linux cache: @@ -6,25 +7,34 @@ cache: - ~/.m2/repository jobs: include: - - stage: "Build" - name: "Build and Test" - jdk: oraclejdk11 - install: mvn clean install -Dmaven.javadoc.skip=true -B - - stage: "Quality Check" - name: "Sonar check" - if: branch = master - jdk: oraclejdk11 - install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build and Publish" - name: "Site build and publish on GitHub pages" - if: branch = master - jdk: oraclejdk8 - install: mvn clean site:site -DskipTests=true -B +# - stage: "Build" +# name: "Build and Test" +## jdk: oraclejdk11 +# install: mvn clean install -Dmaven.javadoc.skip=true -B +# - stage: "Quality Check" +# name: "Sonar check" +# if: branch = master +## jdk: oraclejdk11 +# install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build and Publish" +# name: "Site build and publish on GitHub pages" +# if: branch = master +## jdk: oraclejdk8 +# install: mvn clean site:site -DskipTests=true -B +# deploy: +# provider: pages +# local-dir: target/site +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# branch: master + - stage: "Release" + name: "Releasing artifacts on Maven central" +# if: branch = master deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true + provider: script +# script: "mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -B -U -P release --settings config/travis/settings.xml" + script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} on: - branch: feature/travis-configuration \ No newline at end of file + tags: true From 5412937cdee8a0e69f4b0c96ad316117f3096a25 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 16:44:07 +0100 Subject: [PATCH 0084/1786] restored travis configuration --- .travis.yml | 57 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9f68e1c60..b837dbd27 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: java -jdk: oraclejdk11 +#jdk: oraclejdk11 os: - linux cache: @@ -7,34 +7,33 @@ cache: - ~/.m2/repository jobs: include: -# - stage: "Build" -# name: "Build and Test" -## jdk: oraclejdk11 -# install: mvn clean install -Dmaven.javadoc.skip=true -B -# - stage: "Quality Check" -# name: "Sonar check" -# if: branch = master -## jdk: oraclejdk11 -# install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build and Publish" -# name: "Site build and publish on GitHub pages" + - stage: "Build" + name: "Build and Test" + jdk: oraclejdk11 + install: mvn clean install -Dmaven.javadoc.skip=true -B + - stage: "Quality Check" + name: "Sonar check" + if: branch = master + jdk: oraclejdk11 + install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build and Publish" + name: "Site build and publish on GitHub pages" + if: branch = master + jdk: oraclejdk8 + install: mvn clean site:site -DskipTests=true -B + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + branch: master +# - stage: "Release" +# name: "Releasing artifacts on Maven central" # if: branch = master -## jdk: oraclejdk8 -# install: mvn clean site:site -DskipTests=true -B # deploy: -# provider: pages -# local-dir: target/site -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true +# provider: script +# script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} # on: -# branch: master - - stage: "Release" - name: "Releasing artifacts on Maven central" -# if: branch = master - deploy: - provider: script -# script: "mvn versions:set -DnewVersion=${TRAVIS_TAG} && mvn clean deploy -B -U -P release --settings config/travis/settings.xml" - script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} - on: - tags: true +# tags: true From 4d5c247e2b19b4e8c1f56b461f6dd5ae9e6c2f0a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 16:47:35 +0100 Subject: [PATCH 0085/1786] testing release --- .travis.yml | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index b9cb02576..8a329d839 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: java +jdk: oraclejdk11 os: - linux cache: @@ -6,25 +7,33 @@ cache: - ~/.m2/repository jobs: include: - - stage: "Build" - name: "Build and Test" - jdk: oraclejdk11 - install: mvn clean install -Dmaven.javadoc.skip=true -B - - stage: "Quality Check" - name: "Sonar check" +# - stage: "Build" +# name: "Build and Test" +# jdk: oraclejdk11 +# install: mvn clean install -Dmaven.javadoc.skip=true -B +# - stage: "Quality Check" +# name: "Sonar check" +# if: branch = master +# jdk: oraclejdk11 +# install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build and Publish" +# name: "Site build and publish on GitHub pages" +# if: branch = master +# jdk: oraclejdk8 +# install: mvn clean site:site -DskipTests=true -B +# deploy: +# provider: pages +# local-dir: target/site +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# branch: master + - stage: "Release" + name: "Releasing artifacts on Maven central" if: branch = master - jdk: oraclejdk11 - install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build and Publish" - name: "Site build and publish on GitHub pages" - if: branch = master - jdk: oraclejdk8 - install: mvn clean site:site -DskipTests=true -B deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true + provider: script + script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} on: - branch: feature/travis-configuration \ No newline at end of file + tags: true From 4216134c09a969c2d7eb825d1c25f62a0ae3adbd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 16:49:42 +0100 Subject: [PATCH 0086/1786] triggered release --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8a329d839..573ede39c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ jobs: # branch: master - stage: "Release" name: "Releasing artifacts on Maven central" - if: branch = master +# if: branch = master deploy: provider: script script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} From 32cd4ed785189e9464e865d70f54857f8c912793 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 16:53:42 +0100 Subject: [PATCH 0087/1786] testing --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 573ede39c..5c4d91d7c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,6 @@ jobs: # if: branch = master deploy: provider: script - script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} + script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=1.0.15 -Dbuild.number=1.0.15 -Dbuildlabel=bean-utils.library.1.0.15 on: tags: true From 5ae5a411d4270d55c19af82f8e676b1641a76d02 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 17:16:40 +0100 Subject: [PATCH 0088/1786] testing release --- .travis.yml | 5 ++++- src/main/java/com/hotels/beans/utils/ReflectionUtils.java | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5c4d91d7c..167b189a3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -32,8 +32,11 @@ jobs: - stage: "Release" name: "Releasing artifacts on Maven central" # if: branch = master + before_script: + - git tag -a ${TRAVIS_TAG} -m 'bean-utils.library.${TRAVIS_TAG}' + - git push origin --tags deploy: provider: script - script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=1.0.15 -Dbuild.number=1.0.15 -Dbuildlabel=bean-utils.library.1.0.15 + script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} on: tags: true diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index a421be3ab..464886e92 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -271,13 +271,13 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f /** * Check if a field is accessible or not. - * To make the project compiling with Java version > 8, replace the following line with: {@code field.canAccess(target);} + * To make the project compiling with Java version <= 8, replace the following line with: {@code field.isAccessible();} * @param field the field to check * @param target the field's class * @return true id is accessible, false otherwise */ private boolean isFieldAccessible(final Field field, final Object target) { - return field.isAccessible(); + return field.canAccess(target); } /** From ff1e95f15505fcaf71146b5b0d400bebe2106383 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 17:19:47 +0100 Subject: [PATCH 0089/1786] removed git tagging --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 167b189a3..573ede39c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -32,9 +32,6 @@ jobs: - stage: "Release" name: "Releasing artifacts on Maven central" # if: branch = master - before_script: - - git tag -a ${TRAVIS_TAG} -m 'bean-utils.library.${TRAVIS_TAG}' - - git push origin --tags deploy: provider: script script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} From 0344c64556bf2bf388d372afbd36ca28ef94c03d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 17:28:16 +0100 Subject: [PATCH 0090/1786] testing automatic release --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 573ede39c..2891a904c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: java -jdk: oraclejdk11 +#jdk: oraclejdk11 os: - linux cache: @@ -29,9 +29,13 @@ jobs: # keep-history: true # on: # branch: master + # To Trigger the deploy the following commands needs to be executed + # git tag -a x.y.z -m 'bean-utils-library.x.y.z' e.g. git tag -a bean-utils-library.1.0.4 -m 'bean-utils-library.1.0.4' + # git push origin --tags - stage: "Release" name: "Releasing artifacts on Maven central" # if: branch = master + jdk: oraclejdk8 deploy: provider: script script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} From a4d3c3256f612109cc413bd94f0db0d791004b1e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 17:29:41 +0100 Subject: [PATCH 0091/1786] added project clean before deploy --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 2891a904c..22b3939ab 100755 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ jobs: name: "Releasing artifacts on Maven central" # if: branch = master jdk: oraclejdk8 + install: mvn clean -B deploy: provider: script script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} From e3e0a47a2676539e59ca312998960f59075d3358 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 17:30:19 +0100 Subject: [PATCH 0092/1786] added skip tests option --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 22b3939ab..a29838bc4 100755 --- a/.travis.yml +++ b/.travis.yml @@ -39,6 +39,6 @@ jobs: install: mvn clean -B deploy: provider: script - script: mvn clean deploy -B --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} + script: mvn clean deploy -B -DskipTests --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} on: tags: true From 327bf02972e5dba9cbead2c871326ade477759cc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 17:32:45 +0100 Subject: [PATCH 0093/1786] reverted class --- src/main/java/com/hotels/beans/utils/ReflectionUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 464886e92..a421be3ab 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -271,13 +271,13 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f /** * Check if a field is accessible or not. - * To make the project compiling with Java version <= 8, replace the following line with: {@code field.isAccessible();} + * To make the project compiling with Java version > 8, replace the following line with: {@code field.canAccess(target);} * @param field the field to check * @param target the field's class * @return true id is accessible, false otherwise */ private boolean isFieldAccessible(final Field field, final Object target) { - return field.canAccess(target); + return field.isAccessible(); } /** From c13587c66df63c5e095fa5cfe32729c8247fc52a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 17:40:12 +0100 Subject: [PATCH 0094/1786] finalized travis config? --- .travis.yml | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index a29838bc4..dfcd24281 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,38 +7,39 @@ cache: - ~/.m2/repository jobs: include: -# - stage: "Build" -# name: "Build and Test" -# jdk: oraclejdk11 -# install: mvn clean install -Dmaven.javadoc.skip=true -B -# - stage: "Quality Check" -# name: "Sonar check" -# if: branch = master -# jdk: oraclejdk11 -# install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build and Publish" -# name: "Site build and publish on GitHub pages" -# if: branch = master -# jdk: oraclejdk8 -# install: mvn clean site:site -DskipTests=true -B -# deploy: -# provider: pages -# local-dir: target/site -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true -# on: -# branch: master + - stage: "Build" + name: "Build and Test" + jdk: oraclejdk11 + install: mvn clean install -Dmaven.javadoc.skip=true -B + - stage: "Quality Check" + name: "Sonar check" + if: branch = master + jdk: oraclejdk11 + install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build and Publish" + name: "Site build and publish on GitHub pages" + if: branch = master + jdk: oraclejdk8 + install: mvn clean site:site -DskipTests=true -B + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + branch: master # To Trigger the deploy the following commands needs to be executed # git tag -a x.y.z -m 'bean-utils-library.x.y.z' e.g. git tag -a bean-utils-library.1.0.4 -m 'bean-utils-library.1.0.4' # git push origin --tags - stage: "Release" name: "Releasing artifacts on Maven central" -# if: branch = master + if: branch = master jdk: oraclejdk8 install: mvn clean -B deploy: provider: script - script: mvn clean deploy -B -DskipTests --settings config/travis/mvn-settings.xml -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} +# script: cp --settings config/travis/mvn-settings.xml $HOME/.m2/settings.xml && mvn clean deploy -B -DskipTests -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} + script: cp --settings config/travis/mvn-settings.xml $HOME/.m2/settings.xml && mvn deploy -B --settings config/travis/mvn-settings.xml on: tags: true From f093979d57142ddbe66f1d1ecba150ab19874e51 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 17:41:59 +0100 Subject: [PATCH 0095/1786] fixed cp instruction --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index dfcd24281..2650876f4 100755 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ jobs: install: mvn clean -B deploy: provider: script -# script: cp --settings config/travis/mvn-settings.xml $HOME/.m2/settings.xml && mvn clean deploy -B -DskipTests -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} - script: cp --settings config/travis/mvn-settings.xml $HOME/.m2/settings.xml && mvn deploy -B --settings config/travis/mvn-settings.xml +# script: mvn clean deploy -B -DskipTests -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} + script: cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml && mvn deploy -B --settings config/travis/mvn-settings.xml on: tags: true From 7a334328be232b5208e23f616dc57711e52918cd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 17:52:02 +0100 Subject: [PATCH 0096/1786] trying trigger deploy --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2650876f4..7f9f854c6 100755 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ jobs: # git push origin --tags - stage: "Release" name: "Releasing artifacts on Maven central" - if: branch = master +# if: branch = master jdk: oraclejdk8 install: mvn clean -B deploy: From f8538eeb250b1ef7ec1e200318bf87b9b951133d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:01:21 +0100 Subject: [PATCH 0097/1786] testing release --- .travis.yml | 59 ++++++++++++++++++---------------- config/travis/mvn-settings.xml | 8 ++--- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7f9f854c6..53952b4d9 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,28 +7,28 @@ cache: - ~/.m2/repository jobs: include: - - stage: "Build" - name: "Build and Test" - jdk: oraclejdk11 - install: mvn clean install -Dmaven.javadoc.skip=true -B - - stage: "Quality Check" - name: "Sonar check" - if: branch = master - jdk: oraclejdk11 - install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build and Publish" - name: "Site build and publish on GitHub pages" - if: branch = master - jdk: oraclejdk8 - install: mvn clean site:site -DskipTests=true -B - deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true - on: - branch: master +# - stage: "Build" +# name: "Build and Test" +# jdk: oraclejdk11 +# install: mvn clean install -Dmaven.javadoc.skip=true -B +# - stage: "Quality Check" +# name: "Sonar check" +# if: branch = master +# jdk: oraclejdk11 +# install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build and Publish" +# name: "Site build and publish on GitHub pages" +# if: branch = master +# jdk: oraclejdk8 +# install: mvn clean site:site -DskipTests=true -B +# deploy: +# provider: pages +# local-dir: target/site +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# branch: master # To Trigger the deploy the following commands needs to be executed # git tag -a x.y.z -m 'bean-utils-library.x.y.z' e.g. git tag -a bean-utils-library.1.0.4 -m 'bean-utils-library.1.0.4' # git push origin --tags @@ -36,10 +36,13 @@ jobs: name: "Releasing artifacts on Maven central" # if: branch = master jdk: oraclejdk8 - install: mvn clean -B - deploy: - provider: script + before_install: "git clone -b travis `git config --get remote.origin.url` target/config/travis" + script: mvn deploy --settings target/travis/mvn-settings.xml +# install: mvn clean -B +# deploy: +# provider: script # script: mvn clean deploy -B -DskipTests -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} - script: cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml && mvn deploy -B --settings config/travis/mvn-settings.xml - on: - tags: true +# script: cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml && mvn deploy -B --settings config/travis/mvn-settings.xml +# script: mvn deploy --settings target/travis/mvn-settings.xml +# on: +# tags: true diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 9de5c81ca..c820040d3 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -3,13 +3,13 @@ sonatype-nexus-snapshots - ${sonatype_username} - ${sonatype_password} + ${env.sonatype_username} + ${env.sonatype_password} sonatype-nexus-staging - ${sonatype_username} - ${sonatype_password} + ${env.sonatype_username} + ${env.sonatype_password} From 6811a91dbad14fa6dfbe66de4eb2ad55b8e13ee7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:03:00 +0100 Subject: [PATCH 0098/1786] removed not needed property prefix --- config/travis/mvn-settings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index c820040d3..9de5c81ca 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -3,13 +3,13 @@ sonatype-nexus-snapshots - ${env.sonatype_username} - ${env.sonatype_password} + ${sonatype_username} + ${sonatype_password} sonatype-nexus-staging - ${env.sonatype_username} - ${env.sonatype_password} + ${sonatype_username} + ${sonatype_password} From f26573fb8597456695c9085354ecc0087d5cf17b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:04:20 +0100 Subject: [PATCH 0099/1786] trying in a different way --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 53952b4d9..516db9822 100755 --- a/.travis.yml +++ b/.travis.yml @@ -36,8 +36,8 @@ jobs: name: "Releasing artifacts on Maven central" # if: branch = master jdk: oraclejdk8 - before_install: "git clone -b travis `git config --get remote.origin.url` target/config/travis" - script: mvn deploy --settings target/travis/mvn-settings.xml + before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" + script: mvn deploy # install: mvn clean -B # deploy: # provider: script From 50252b4b17f75b16dd22ae40e7ee46a1de27145c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:13:06 +0100 Subject: [PATCH 0100/1786] hopefully the final test --- .travis.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 516db9822..8afb1ee04 100755 --- a/.travis.yml +++ b/.travis.yml @@ -37,12 +37,9 @@ jobs: # if: branch = master jdk: oraclejdk8 before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" - script: mvn deploy -# install: mvn clean -B -# deploy: -# provider: script -# script: mvn clean deploy -B -DskipTests -DforceTags -DpushImageTag -DdeployAtEnd -Dshortname=BULL -DreleaseVersion=${TRAVIS_TAG} -Dbuild.number=${TRAVIS_TAG} -Dbuildlabel=bean-utils.library.${TRAVIS_TAG} -# script: cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml && mvn deploy -B --settings config/travis/mvn-settings.xml -# script: mvn deploy --settings target/travis/mvn-settings.xml -# on: -# tags: true + deploy: + skip_cleanup: true + provider: script + script: mvn deploy -B + on: + tags: true From 7e20fb3cf227f53d6e2276ea5a7351fee11d218b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:14:11 +0100 Subject: [PATCH 0101/1786] added skip tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8afb1ee04..675ceb4f1 100755 --- a/.travis.yml +++ b/.travis.yml @@ -40,6 +40,6 @@ jobs: deploy: skip_cleanup: true provider: script - script: mvn deploy -B + script: mvn deploy -B -DskipTests=true on: tags: true From 9ceb7279c1c65743ce7980085c430767ee086fe8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:18:39 +0100 Subject: [PATCH 0102/1786] removed deploy --- .travis.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 675ceb4f1..4f2438c7c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -36,10 +36,5 @@ jobs: name: "Releasing artifacts on Maven central" # if: branch = master jdk: oraclejdk8 - before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" - deploy: - skip_cleanup: true - provider: script - script: mvn deploy -B -DskipTests=true - on: - tags: true + before_script: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" + script: mvn deploy -B -DskipTests=true From 3dac850c788fec3d6f67ff965dbcf8154628a0a0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:23:59 +0100 Subject: [PATCH 0103/1786] testing release --- .travis.yml | 8 +++++--- pom.xml | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f2438c7c..df9f2edea 100755 --- a/.travis.yml +++ b/.travis.yml @@ -29,12 +29,14 @@ jobs: # keep-history: true # on: # branch: master - # To Trigger the deploy the following commands needs to be executed - # git tag -a x.y.z -m 'bean-utils-library.x.y.z' e.g. git tag -a bean-utils-library.1.0.4 -m 'bean-utils-library.1.0.4' - # git push origin --tags + # To Trigger the deploy the following commands needs to be executed + # git tag -a x.y.z -m 'bean-utils-library.x.y.z' e.g. git tag -a bean-utils-library.1.0.4 -m 'bean-utils-library.1.0.4' + # git push origin --tags - stage: "Release" name: "Releasing artifacts on Maven central" # if: branch = master jdk: oraclejdk8 before_script: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" script: mvn deploy -B -DskipTests=true + on: + tags: true diff --git a/pom.xml b/pom.xml index abd2a1e38..f839b1743 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0-SNAPSHOT + 1.0.4 jar 2019 From 1642ffaf59cd15883afc86cb7f2bc5446c8d34aa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:27:40 +0100 Subject: [PATCH 0104/1786] added clean install --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index df9f2edea..85504d587 100755 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,4 @@ jobs: # if: branch = master jdk: oraclejdk8 before_script: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" - script: mvn deploy -B -DskipTests=true - on: - tags: true + script: mvn clean install deploy -B -DskipTests=true \ No newline at end of file From 0dd53e9f31a8ca265bd672a02d85d662f8ecde59 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:28:00 +0100 Subject: [PATCH 0105/1786] made install --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 85504d587..a50224100 100755 --- a/.travis.yml +++ b/.travis.yml @@ -36,5 +36,5 @@ jobs: name: "Releasing artifacts on Maven central" # if: branch = master jdk: oraclejdk8 - before_script: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" - script: mvn clean install deploy -B -DskipTests=true \ No newline at end of file + before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" + install: mvn clean install deploy -B -DskipTests=true \ No newline at end of file From 24777445cbcd08d7ece47801d7c9415a09f2bd8a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:31:12 +0100 Subject: [PATCH 0106/1786] Added automatic snapshot release --- .travis.yml | 49 +++++++++++++++++++++++-------------------------- pom.xml | 2 +- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index a50224100..02b812e0e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,34 +7,31 @@ cache: - ~/.m2/repository jobs: include: -# - stage: "Build" -# name: "Build and Test" -# jdk: oraclejdk11 -# install: mvn clean install -Dmaven.javadoc.skip=true -B -# - stage: "Quality Check" -# name: "Sonar check" -# if: branch = master -# jdk: oraclejdk11 -# install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build and Publish" -# name: "Site build and publish on GitHub pages" -# if: branch = master -# jdk: oraclejdk8 -# install: mvn clean site:site -DskipTests=true -B -# deploy: -# provider: pages -# local-dir: target/site -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true -# on: -# branch: master - # To Trigger the deploy the following commands needs to be executed - # git tag -a x.y.z -m 'bean-utils-library.x.y.z' e.g. git tag -a bean-utils-library.1.0.4 -m 'bean-utils-library.1.0.4' - # git push origin --tags + - stage: "Build" + name: "Build and Test" + jdk: oraclejdk11 + install: mvn clean install -Dmaven.javadoc.skip=true -B + - stage: "Quality Check" + name: "Sonar check" + if: branch = master + jdk: oraclejdk11 + install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build and Publish" + name: "Site build and publish on GitHub pages" + if: branch = master + jdk: oraclejdk8 + install: mvn clean site:site -DskipTests=true -B + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + branch: master - stage: "Release" name: "Releasing artifacts on Maven central" -# if: branch = master + if: NOT branch = master jdk: oraclejdk8 before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" install: mvn clean install deploy -B -DskipTests=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index f839b1743..abd2a1e38 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.4 + 1.0-SNAPSHOT jar 2019 From 5fa2df58ddf889ee90c7e0a15cb48cd4f390cb8e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 26 Jan 2019 18:33:04 +0100 Subject: [PATCH 0107/1786] made just deploying --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 02b812e0e..e06267b59 100755 --- a/.travis.yml +++ b/.travis.yml @@ -34,4 +34,4 @@ jobs: if: NOT branch = master jdk: oraclejdk8 before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" - install: mvn clean install deploy -B -DskipTests=true \ No newline at end of file + install: mvn deploy -B -DskipTests=true \ No newline at end of file From 530b94fb10505c12a7d71a3597b025b867ff8d81 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 27 Jan 2019 08:19:22 +0100 Subject: [PATCH 0108/1786] changed pom version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 128c97942..7bd01f896 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library - 1.0.17-SNAPSHOT + 1.0-SNAPSHOT jar 2019 From 121041ed51029abdbff59fd2dcc05bed1b85a5b1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 27 Jan 2019 08:45:53 +0100 Subject: [PATCH 0109/1786] Modified travis configuration in order to execute less test step --- .travis.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index e06267b59..39f7acd27 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,17 +7,20 @@ cache: - ~/.m2/repository jobs: include: + # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" + if: NOT branch = master jdk: oraclejdk11 install: mvn clean install -Dmaven.javadoc.skip=true -B - - stage: "Quality Check" - name: "Sonar check" + # If the branch is master it sends the quality report to SonarCloud + - stage: "Build, Test and Quality Check" + name: "Building, testing and sending a quality report to SonarCloud" if: branch = master jdk: oraclejdk11 - install: mvn test -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + install: mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" - name: "Site build and publish on GitHub pages" + name: "Building site and publishing on GitHub pages" if: branch = master jdk: oraclejdk8 install: mvn clean site:site -DskipTests=true -B From 16049ae51993c046c012021ff31d3881c37ff8a8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 27 Jan 2019 08:48:56 +0100 Subject: [PATCH 0110/1786] minor: added project url --- pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7bd01f896..ab31fa118 100644 --- a/pom.xml +++ b/pom.xml @@ -4,6 +4,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library + https://github.com/HotelsDotCom/bull 1.0-SNAPSHOT jar 2019 @@ -50,8 +51,8 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD - + HEAD + From 0dbad0cf2d78104d6d761310e31aae4d3ed90661 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 27 Jan 2019 08:51:31 +0100 Subject: [PATCH 0111/1786] modified tag name --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ab31fa118..81b117d4c 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + bean-utils-library-{project.version} From 5a528676bcace9fb8c5b6f4a04ab670cc68714ed Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 27 Jan 2019 09:04:31 +0100 Subject: [PATCH 0112/1786] - Modified tag name - Upgraded spring version --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 81b117d4c..882ebf0d4 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 1.8 ${jdk.version} ${jdk.version} - 2.1.0.RELEASE + 2.1.2.RELEASE 1.18.4 1.3 3.8.1 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-{project.version} + bean-utils-library-1.0.16 From 5c11c91c974c055506317265f65991f81dd33812 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 27 Jan 2019 09:15:58 +0100 Subject: [PATCH 0113/1786] - Upgraded to java 11 - Modified changelog - Removed depracated method --- .travis.yml | 5 +---- CHANGELOG.md | 8 ++++++-- pom.xml | 4 ++-- src/main/java/com/hotels/beans/utils/ReflectionUtils.java | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 39f7acd27..a26705d4a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: java -#jdk: oraclejdk11 +jdk: oraclejdk11 os: - linux cache: @@ -11,7 +11,6 @@ jobs: - stage: "Build" name: "Build and Test" if: NOT branch = master - jdk: oraclejdk11 install: mvn clean install -Dmaven.javadoc.skip=true -B # If the branch is master it sends the quality report to SonarCloud - stage: "Build, Test and Quality Check" @@ -22,7 +21,6 @@ jobs: - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" if: branch = master - jdk: oraclejdk8 install: mvn clean site:site -DskipTests=true -B deploy: provider: pages @@ -35,6 +33,5 @@ jobs: - stage: "Release" name: "Releasing artifacts on Maven central" if: NOT branch = master - jdk: oraclejdk8 before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" install: mvn deploy -B -DskipTests=true \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e87e449af..c3b129050 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,16 @@ All notable changes to this project will be documented in this file. +### [1.1.0] TBD +#### Changed +* Updated `jdk.version` version to `11` (was `1.8`). +* Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). + ### [1.0.16] 2019.01.26 #### Changed * Updated `hotels-oss-parent` version to `3.0.0` (was `2.3.5`). #### Added -* Configured Travis in order to automatically build the application, perform a quality check and publish the site. Travis build site available [here](https://travis-ci -.org/HotelsDotCom/bull) +* Configured Travis in order to automatically build the application, perform a quality check and publish the site. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) * Added build, test coverage and security badge to readme file. ### [1.0.15] 2019.01.23 diff --git a/pom.xml b/pom.xml index 882ebf0d4..aa1b5dc41 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0-SNAPSHOT + 1.1-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 2.1.2.RELEASE diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index a421be3ab..2c5bc6081 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -271,13 +271,13 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f /** * Check if a field is accessible or not. - * To make the project compiling with Java version > 8, replace the following line with: {@code field.canAccess(target);} + * To make the project compiling with Java version < 9, replace the following line with: {@code field.isAccessible()} * @param field the field to check * @param target the field's class * @return true id is accessible, false otherwise */ private boolean isFieldAccessible(final Field field, final Object target) { - return field.isAccessible(); + return field.canAccess(target); } /** From 7a4812b5da675e113f9bb04a191a1b795e15ed7b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 27 Jan 2019 09:16:41 +0100 Subject: [PATCH 0114/1786] Modified tag name --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aa1b5dc41..c1d7d3c06 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.16 + bean-utils-library-1.1-SNAPSHOT From 95fd2bc3ad7cbb5dc5a0644b22a9de9edb1ddba6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 27 Jan 2019 20:51:39 +0100 Subject: [PATCH 0115/1786] Modified package's description files --- pom.xml | 2 +- src/main/java/com/hotels/beans/annotation/package-info.java | 2 +- src/main/java/com/hotels/beans/application/package-info.java | 2 +- src/main/java/com/hotels/beans/base/package-info.java | 2 +- src/main/java/com/hotels/beans/cache/package-info.java | 2 +- src/main/java/com/hotels/beans/constant/package-info.java | 2 +- src/main/java/com/hotels/beans/package-info.java | 2 +- src/main/java/com/hotels/beans/utils/package-info.java | 2 +- src/test/java/com/hotels/beans/application/package-info.java | 2 +- src/test/java/com/hotels/beans/base/package-info.java | 2 +- src/test/java/com/hotels/beans/cache/package-info.java | 2 +- src/test/java/com/hotels/beans/package-info.java | 2 +- src/test/java/com/hotels/beans/populator/package-info.java | 2 +- src/test/java/com/hotels/beans/transformer/package-info.java | 2 +- src/test/java/com/hotels/beans/utils/package-info.java | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index 81b117d4c..4170fab7a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0-SNAPSHOT + 1.0.16 jar 2019 diff --git a/src/main/java/com/hotels/beans/annotation/package-info.java b/src/main/java/com/hotels/beans/annotation/package-info.java index 000c0df8a..16b9f0b35 100644 --- a/src/main/java/com/hotels/beans/annotation/package-info.java +++ b/src/main/java/com/hotels/beans/annotation/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Annotations package. + * Support package for annotation-driven bean configuration. */ package com.hotels.beans.annotation; diff --git a/src/main/java/com/hotels/beans/application/package-info.java b/src/main/java/com/hotels/beans/application/package-info.java index 2d2e1befb..1fd4d8f86 100644 --- a/src/main/java/com/hotels/beans/application/package-info.java +++ b/src/main/java/com/hotels/beans/application/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Spring boot starter package. + * Spring boot starter package (not included into jar file). */ package com.hotels.beans.application; diff --git a/src/main/java/com/hotels/beans/base/package-info.java b/src/main/java/com/hotels/beans/base/package-info.java index 3cd1ac121..89be2bd3a 100644 --- a/src/main/java/com/hotels/beans/base/package-info.java +++ b/src/main/java/com/hotels/beans/base/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Base package. + * Default objects support classes. */ package com.hotels.beans.base; diff --git a/src/main/java/com/hotels/beans/cache/package-info.java b/src/main/java/com/hotels/beans/cache/package-info.java index 40f771047..4f4b8ddc5 100644 --- a/src/main/java/com/hotels/beans/cache/package-info.java +++ b/src/main/java/com/hotels/beans/cache/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * cache package. + * Classes for declarative cache management. */ package com.hotels.beans.cache; diff --git a/src/main/java/com/hotels/beans/constant/package-info.java b/src/main/java/com/hotels/beans/constant/package-info.java index 667c40cda..64905c2de 100644 --- a/src/main/java/com/hotels/beans/constant/package-info.java +++ b/src/main/java/com/hotels/beans/constant/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Constants package. + * Constants container package. */ package com.hotels.beans.constant; diff --git a/src/main/java/com/hotels/beans/package-info.java b/src/main/java/com/hotels/beans/package-info.java index 3fbb5a4ce..a96e4a241 100644 --- a/src/main/java/com/hotels/beans/package-info.java +++ b/src/main/java/com/hotels/beans/package-info.java @@ -14,6 +14,6 @@ * limitations under the License. */ /** - * Main package. + * Base application package. */ package com.hotels.beans; diff --git a/src/main/java/com/hotels/beans/utils/package-info.java b/src/main/java/com/hotels/beans/utils/package-info.java index eb3622d9f..e940949f5 100644 --- a/src/main/java/com/hotels/beans/utils/package-info.java +++ b/src/main/java/com/hotels/beans/utils/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * utilities package. + * Utilities classes. */ package com.hotels.beans.utils; diff --git a/src/test/java/com/hotels/beans/application/package-info.java b/src/test/java/com/hotels/beans/application/package-info.java index 2d2e1befb..f768c7ab1 100644 --- a/src/test/java/com/hotels/beans/application/package-info.java +++ b/src/test/java/com/hotels/beans/application/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Spring boot starter package. + * Spring boot starter test package. */ package com.hotels.beans.application; diff --git a/src/test/java/com/hotels/beans/base/package-info.java b/src/test/java/com/hotels/beans/base/package-info.java index 2cd723341..cbd67b1bb 100644 --- a/src/test/java/com/hotels/beans/base/package-info.java +++ b/src/test/java/com/hotels/beans/base/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Base item package. + * Default objects support classes test. */ package com.hotels.beans.base; diff --git a/src/test/java/com/hotels/beans/cache/package-info.java b/src/test/java/com/hotels/beans/cache/package-info.java index 40f771047..300e9ac07 100644 --- a/src/test/java/com/hotels/beans/cache/package-info.java +++ b/src/test/java/com/hotels/beans/cache/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * cache package. + * Classes for declarative cache management test. */ package com.hotels.beans.cache; diff --git a/src/test/java/com/hotels/beans/package-info.java b/src/test/java/com/hotels/beans/package-info.java index 6d16e426d..592a8e9a6 100644 --- a/src/test/java/com/hotels/beans/package-info.java +++ b/src/test/java/com/hotels/beans/package-info.java @@ -14,6 +14,6 @@ * limitations under the License. */ /** - * Test package. + * Base test package. */ package com.hotels.beans; diff --git a/src/test/java/com/hotels/beans/populator/package-info.java b/src/test/java/com/hotels/beans/populator/package-info.java index f388b9779..181e82970 100644 --- a/src/test/java/com/hotels/beans/populator/package-info.java +++ b/src/test/java/com/hotels/beans/populator/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Populator objects package. + * Populator objects test package. */ package com.hotels.beans.populator; diff --git a/src/test/java/com/hotels/beans/transformer/package-info.java b/src/test/java/com/hotels/beans/transformer/package-info.java index 9100b3f26..8fe03d1a8 100644 --- a/src/test/java/com/hotels/beans/transformer/package-info.java +++ b/src/test/java/com/hotels/beans/transformer/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Bean transformer package. + * Bean transformer test package. */ package com.hotels.beans.transformer; diff --git a/src/test/java/com/hotels/beans/utils/package-info.java b/src/test/java/com/hotels/beans/utils/package-info.java index eb3622d9f..49c8a489e 100644 --- a/src/test/java/com/hotels/beans/utils/package-info.java +++ b/src/test/java/com/hotels/beans/utils/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * utilities package. + * Utilities test classes. */ package com.hotels.beans.utils; From 43d570d335e8f887680fd39da65725b396fa114a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Jan 2019 17:08:41 +0100 Subject: [PATCH 0116/1786] Started travis configuration for publish the release artifact on maven central --- .travis.yml | 15 +++++++++++---- config/travis/deploy.sh | 13 +++++++++++++ config/travis/mvn-settings.xml | 14 ++++++++++++++ pom.xml | 2 +- .../com/hotels/beans/annotation/package-info.java | 2 +- .../hotels/beans/application/package-info.java | 2 +- .../java/com/hotels/beans/base/package-info.java | 2 +- .../java/com/hotels/beans/cache/package-info.java | 2 +- .../com/hotels/beans/constant/package-info.java | 2 +- src/main/java/com/hotels/beans/package-info.java | 2 +- .../java/com/hotels/beans/utils/package-info.java | 2 +- .../hotels/beans/application/package-info.java | 2 +- .../java/com/hotels/beans/base/package-info.java | 2 +- .../java/com/hotels/beans/cache/package-info.java | 2 +- src/test/java/com/hotels/beans/package-info.java | 2 +- .../com/hotels/beans/populator/package-info.java | 2 +- .../hotels/beans/transformer/package-info.java | 2 +- .../java/com/hotels/beans/utils/package-info.java | 2 +- 18 files changed, 53 insertions(+), 19 deletions(-) create mode 100755 config/travis/deploy.sh diff --git a/.travis.yml b/.travis.yml index 39f7acd27..729462fba 100755 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,14 @@ jobs: branch: master - stage: "Release" name: "Releasing artifacts on Maven central" - if: NOT branch = master - jdk: oraclejdk8 - before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" - install: mvn deploy -B -DskipTests=true \ No newline at end of file + deploy: + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + branch: master + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh new file mode 100755 index 000000000..235dab507 --- /dev/null +++ b/config/travis/deploy.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e + +if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then + if [ ! -z "$TRAVIS_TAG" ]; then + echo "Deploying release" + mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P sonatype-oss-release "$@" -DskipTests=true + else + echo "Deploying snapshot" + mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true + fi +fi \ No newline at end of file diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 9de5c81ca..46bdf5ae9 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -17,4 +17,18 @@ ${github_oauth_token} + + + + sonatype-oss-release + + gpg2 + false + ${env.GPG_DIR}/pubring.gpg + ${env.GPG_DIR}/secring.gpg + ${env.GPG_KEY_NAME} + ${env.GPG_PASSPHRASE} + + + diff --git a/pom.xml b/pom.xml index 2f73d477e..c8a08ff88 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.16 + 1.0.16-SNAPSHOT jar 2019 diff --git a/src/main/java/com/hotels/beans/annotation/package-info.java b/src/main/java/com/hotels/beans/annotation/package-info.java index 16b9f0b35..000c0df8a 100644 --- a/src/main/java/com/hotels/beans/annotation/package-info.java +++ b/src/main/java/com/hotels/beans/annotation/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Support package for annotation-driven bean configuration. + * Annotations package. */ package com.hotels.beans.annotation; diff --git a/src/main/java/com/hotels/beans/application/package-info.java b/src/main/java/com/hotels/beans/application/package-info.java index 1fd4d8f86..2d2e1befb 100644 --- a/src/main/java/com/hotels/beans/application/package-info.java +++ b/src/main/java/com/hotels/beans/application/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Spring boot starter package (not included into jar file). + * Spring boot starter package. */ package com.hotels.beans.application; diff --git a/src/main/java/com/hotels/beans/base/package-info.java b/src/main/java/com/hotels/beans/base/package-info.java index 89be2bd3a..3cd1ac121 100644 --- a/src/main/java/com/hotels/beans/base/package-info.java +++ b/src/main/java/com/hotels/beans/base/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Default objects support classes. + * Base package. */ package com.hotels.beans.base; diff --git a/src/main/java/com/hotels/beans/cache/package-info.java b/src/main/java/com/hotels/beans/cache/package-info.java index 4f4b8ddc5..40f771047 100644 --- a/src/main/java/com/hotels/beans/cache/package-info.java +++ b/src/main/java/com/hotels/beans/cache/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Classes for declarative cache management. + * cache package. */ package com.hotels.beans.cache; diff --git a/src/main/java/com/hotels/beans/constant/package-info.java b/src/main/java/com/hotels/beans/constant/package-info.java index 64905c2de..667c40cda 100644 --- a/src/main/java/com/hotels/beans/constant/package-info.java +++ b/src/main/java/com/hotels/beans/constant/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Constants container package. + * Constants package. */ package com.hotels.beans.constant; diff --git a/src/main/java/com/hotels/beans/package-info.java b/src/main/java/com/hotels/beans/package-info.java index a96e4a241..3fbb5a4ce 100644 --- a/src/main/java/com/hotels/beans/package-info.java +++ b/src/main/java/com/hotels/beans/package-info.java @@ -14,6 +14,6 @@ * limitations under the License. */ /** - * Base application package. + * Main package. */ package com.hotels.beans; diff --git a/src/main/java/com/hotels/beans/utils/package-info.java b/src/main/java/com/hotels/beans/utils/package-info.java index e940949f5..eb3622d9f 100644 --- a/src/main/java/com/hotels/beans/utils/package-info.java +++ b/src/main/java/com/hotels/beans/utils/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Utilities classes. + * utilities package. */ package com.hotels.beans.utils; diff --git a/src/test/java/com/hotels/beans/application/package-info.java b/src/test/java/com/hotels/beans/application/package-info.java index f768c7ab1..2d2e1befb 100644 --- a/src/test/java/com/hotels/beans/application/package-info.java +++ b/src/test/java/com/hotels/beans/application/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Spring boot starter test package. + * Spring boot starter package. */ package com.hotels.beans.application; diff --git a/src/test/java/com/hotels/beans/base/package-info.java b/src/test/java/com/hotels/beans/base/package-info.java index cbd67b1bb..2cd723341 100644 --- a/src/test/java/com/hotels/beans/base/package-info.java +++ b/src/test/java/com/hotels/beans/base/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Default objects support classes test. + * Base item package. */ package com.hotels.beans.base; diff --git a/src/test/java/com/hotels/beans/cache/package-info.java b/src/test/java/com/hotels/beans/cache/package-info.java index 300e9ac07..40f771047 100644 --- a/src/test/java/com/hotels/beans/cache/package-info.java +++ b/src/test/java/com/hotels/beans/cache/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Classes for declarative cache management test. + * cache package. */ package com.hotels.beans.cache; diff --git a/src/test/java/com/hotels/beans/package-info.java b/src/test/java/com/hotels/beans/package-info.java index 592a8e9a6..6d16e426d 100644 --- a/src/test/java/com/hotels/beans/package-info.java +++ b/src/test/java/com/hotels/beans/package-info.java @@ -14,6 +14,6 @@ * limitations under the License. */ /** - * Base test package. + * Test package. */ package com.hotels.beans; diff --git a/src/test/java/com/hotels/beans/populator/package-info.java b/src/test/java/com/hotels/beans/populator/package-info.java index 181e82970..f388b9779 100644 --- a/src/test/java/com/hotels/beans/populator/package-info.java +++ b/src/test/java/com/hotels/beans/populator/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Populator objects test package. + * Populator objects package. */ package com.hotels.beans.populator; diff --git a/src/test/java/com/hotels/beans/transformer/package-info.java b/src/test/java/com/hotels/beans/transformer/package-info.java index 8fe03d1a8..9100b3f26 100644 --- a/src/test/java/com/hotels/beans/transformer/package-info.java +++ b/src/test/java/com/hotels/beans/transformer/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Bean transformer test package. + * Bean transformer package. */ package com.hotels.beans.transformer; diff --git a/src/test/java/com/hotels/beans/utils/package-info.java b/src/test/java/com/hotels/beans/utils/package-info.java index 49c8a489e..eb3622d9f 100644 --- a/src/test/java/com/hotels/beans/utils/package-info.java +++ b/src/test/java/com/hotels/beans/utils/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Utilities test classes. + * utilities package. */ package com.hotels.beans.utils; From 1442259c0f30cb82a718d08c81fb9b3abafbfa6a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Jan 2019 17:15:11 +0100 Subject: [PATCH 0117/1786] - Updated parent library version - Testing artifact sign before releasing on maven central --- .travis.yml | 4 ++-- pom.xml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index a26705d4a..1511ff8d6 100755 --- a/.travis.yml +++ b/.travis.yml @@ -33,5 +33,5 @@ jobs: - stage: "Release" name: "Releasing artifacts on Maven central" if: NOT branch = master - before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" - install: mvn deploy -B -DskipTests=true \ No newline at end of file +# before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" + install: mvn deploy --settings config/travis/mvn-settings.xml -B -U -P sonatype-oss-release -DskipTests=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index c1d7d3c06..409e7b074 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1-SNAPSHOT + 1.0.16-SNAPSHOT jar 2019 @@ -16,7 +16,7 @@ com.hotels hotels-oss-parent - 3.0.1 + 4.0.0 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.1-SNAPSHOT + bean-utils-library-${project.version} From 3655d3ed5b5673af3d21591f7a0ae7d0eab161d8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Jan 2019 17:46:27 +0100 Subject: [PATCH 0118/1786] testing automatic deploy --- .travis.yml | 24 +++++++++++------------- pom.xml | 4 ++-- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 729462fba..585e77398 100755 --- a/.travis.yml +++ b/.travis.yml @@ -32,16 +32,14 @@ jobs: keep-history: true on: branch: master - - stage: "Release" - name: "Releasing artifacts on Maven central" - deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - branch: master - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true +deploy: + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + branch: master + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true diff --git a/pom.xml b/pom.xml index c8a08ff88..8389c15ac 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.16-SNAPSHOT + 1.0.5 jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.16 + bean-utils-library-1.0.5 From d041b14f3e23289349b895e32f7d62abe08b8c22 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Jan 2019 17:52:30 +0100 Subject: [PATCH 0119/1786] restored old travis stage definition --- .travis.yml | 24 +++++++++++++----------- pom.xml | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 585e77398..729462fba 100755 --- a/.travis.yml +++ b/.travis.yml @@ -32,14 +32,16 @@ jobs: keep-history: true on: branch: master -deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - branch: master - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true + - stage: "Release" + name: "Releasing artifacts on Maven central" + deploy: + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + branch: master + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true diff --git a/pom.xml b/pom.xml index 8389c15ac..0d883c394 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.5 + 1.0.17-SNAPSHOT jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.5 + bean-utils-library-${project.version} From 49f0178938d56cba13aea2ce9f1222d3a80b54e5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Jan 2019 17:54:58 +0100 Subject: [PATCH 0120/1786] Fixed maven snapshot release --- .travis.yml | 5 ++--- pom.xml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1511ff8d6..ba17b503e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,6 @@ jobs: - stage: "Build, Test and Quality Check" name: "Building, testing and sending a quality report to SonarCloud" if: branch = master - jdk: oraclejdk11 install: mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" @@ -33,5 +32,5 @@ jobs: - stage: "Release" name: "Releasing artifacts on Maven central" if: NOT branch = master -# before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" - install: mvn deploy --settings config/travis/mvn-settings.xml -B -U -P sonatype-oss-release -DskipTests=true \ No newline at end of file + before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" + install: mvn deploy -B -DskipTests=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index 409e7b074..efd8e999f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.16-SNAPSHOT + 1.0.17-SNAPSHOT jar 2019 From eddebd9104e898be2033ffb30b9fa0ae20af4a82 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 29 Jan 2019 16:34:55 +0100 Subject: [PATCH 0121/1786] temp commit --- config/travis/mvn-settings.xml | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 46bdf5ae9..d58cf8172 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -19,16 +19,29 @@ + + + + + + + + + + + + - sonatype-oss-release + ossrh + + true + - gpg2 - false - ${env.GPG_DIR}/pubring.gpg - ${env.GPG_DIR}/secring.gpg + gpg ${env.GPG_KEY_NAME} ${env.GPG_PASSPHRASE} + From ec4480755cc45161fa0198b2c1eaba9a1f2cd7de Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 29 Jan 2019 16:40:53 +0100 Subject: [PATCH 0122/1786] - Updated changelog file - Finalized travis configuration --- .travis.yml | 2 +- CHANGELOG.md | 8 ++------ pom.xml | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index ba17b503e..4ecc12c75 100755 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ jobs: - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" if: branch = master - install: mvn clean site:site -DskipTests=true -B + before_deploy: mvn clean install site:site -DskipTests=true -B deploy: provider: pages local-dir: target/site diff --git a/CHANGELOG.md b/CHANGELOG.md index c3b129050..2cb7722d5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,10 @@ All notable changes to this project will be documented in this file. -### [1.1.0] TBD -#### Changed -* Updated `jdk.version` version to `11` (was `1.8`). -* Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). - ### [1.0.16] 2019.01.26 #### Changed -* Updated `hotels-oss-parent` version to `3.0.0` (was `2.3.5`). +* Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). +* Updated `hotels-oss-parent` version to `4.0.0` (was `2.3.5`). #### Added * Configured Travis in order to automatically build the application, perform a quality check and publish the site. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) * Added build, test coverage and security badge to readme file. diff --git a/pom.xml b/pom.xml index efd8e999f..02da6ab7e 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 2.1.2.RELEASE From 7e3e2bceb321efa7a2581e3381aeab859d9d73ed Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 29 Jan 2019 16:46:23 +0100 Subject: [PATCH 0123/1786] minor: modified stage travis name --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4ecc12c75..ac5eacea8 100755 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ jobs: on: branch: master - stage: "Release" - name: "Releasing artifacts on Maven central" + name: "Releasing SNAPSHOT artifact on Maven central" if: NOT branch = master before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" install: mvn deploy -B -DskipTests=true \ No newline at end of file From 9bb63d73eb809f4b6bd9d72944e63345b3c57d5a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 29 Jan 2019 16:49:53 +0100 Subject: [PATCH 0124/1786] Added travis_retry option on maven build in order to execute the tests twice in case of failure --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac5eacea8..516496744 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,16 +11,16 @@ jobs: - stage: "Build" name: "Build and Test" if: NOT branch = master - install: mvn clean install -Dmaven.javadoc.skip=true -B + install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B # If the branch is master it sends the quality report to SonarCloud - stage: "Build, Test and Quality Check" name: "Building, testing and sending a quality report to SonarCloud" if: branch = master - install: mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" if: branch = master - before_deploy: mvn clean install site:site -DskipTests=true -B + before_deploy: mvn install site:site -DskipTests=true -B deploy: provider: pages local-dir: target/site From eef37f824f64d8e2ab8e7177adb2452e65a7c3cd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 29 Jan 2019 16:55:49 +0100 Subject: [PATCH 0125/1786] adding fix that avoid the execution of `mvn test` twice with Travis --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 516496744..39d3f8420 100755 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ os: cache: directories: - ~/.m2/repository +install: + - jobs: include: # If the branch is not master it just builds the application From fe193dab7e7e66976ca3a924f7281e8ad8fce621 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 29 Jan 2019 17:00:16 +0100 Subject: [PATCH 0126/1786] added deploy fix --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 39d3f8420..3a2ac6daf 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,27 +1,29 @@ language: java -jdk: oraclejdk11 os: - linux cache: directories: - ~/.m2/repository install: - - + - jobs: include: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" if: NOT branch = master + jdk: oraclejdk11 install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B # If the branch is master it sends the quality report to SonarCloud - stage: "Build, Test and Quality Check" name: "Building, testing and sending a quality report to SonarCloud" if: branch = master + jdk: oraclejdk11 install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" if: branch = master + jdk: oraclejdk8 before_deploy: mvn install site:site -DskipTests=true -B deploy: provider: pages @@ -34,5 +36,6 @@ jobs: - stage: "Release" name: "Releasing SNAPSHOT artifact on Maven central" if: NOT branch = master + jdk: oraclejdk8 before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" install: mvn deploy -B -DskipTests=true \ No newline at end of file From 6311c071190b1c753c15fc675f30d479d406e717 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 29 Jan 2019 17:10:15 +0100 Subject: [PATCH 0127/1786] minor travis fixes --- .travis.yml | 3 +-- src/main/java/com/hotels/beans/utils/ReflectionUtils.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3a2ac6daf..8965ad60e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,7 @@ os: cache: directories: - ~/.m2/repository -install: - - +install: skip jobs: include: # If the branch is not master it just builds the application diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 2c5bc6081..a421be3ab 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -271,13 +271,13 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f /** * Check if a field is accessible or not. - * To make the project compiling with Java version < 9, replace the following line with: {@code field.isAccessible()} + * To make the project compiling with Java version > 8, replace the following line with: {@code field.canAccess(target);} * @param field the field to check * @param target the field's class * @return true id is accessible, false otherwise */ private boolean isFieldAccessible(final Field field, final Object target) { - return field.canAccess(target); + return field.isAccessible(); } /** From 288e68deb06dcfe1cfd5690498e47203a4b8b833 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 29 Jan 2019 17:15:39 +0100 Subject: [PATCH 0128/1786] Added pr check --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8965ad60e..7997aa494 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,12 +16,12 @@ jobs: # If the branch is master it sends the quality report to SonarCloud - stage: "Build, Test and Quality Check" name: "Building, testing and sending a quality report to SonarCloud" - if: branch = master + if: branch = master AND type NOT IN (pull_request) jdk: oraclejdk11 install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" - if: branch = master + if: branch = master AND type NOT IN (pull_request) jdk: oraclejdk8 before_deploy: mvn install site:site -DskipTests=true -B deploy: From 6f1e8ebbb224cd677714733b772f5bb0097dd1ae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Feb 2019 15:28:52 +0100 Subject: [PATCH 0129/1786] Added procedure for contributing to the project --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- CONTRIBUTING.md | 34 +++++++++++++++++++--------- CONTRIBUTORS.md | 15 ++++++++++++ 3 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 CONTRIBUTORS.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea782..af9b02254 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,7 +3,7 @@ name: Bug report about: Create a report to help us improve title: '' labels: '' -assignees: '' +assignees: '[Fabio Borriello](https://github.com/fborriello)' --- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b30155498..decec42c0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,15 +1,27 @@ -## Contributors +Contributing +============ +If you want to contribute to the project and make it better, your help is very welcome. Contributing is also a great way to learn more about social coding on Github, new +technologies and and their ecosystems and how to make constructive, helpful bug reports, feature requests and the noblest of all contributions: a good, clean pull request. -### Original Developers +### How to make a clean pull request -* [Fabio Borriello](https://github.com/fborriello) +Look for a project's contribution instructions. If there are any, follow them. -### Additional Developers -* [Andrea Marsiglia](https://github.com/AndreaMars94) -* [Patrizio Munzi](https://github.com/patriziomunzi) +- Create a personal fork of the project on Github. +- Clone the fork on your local machine. Your remote repo on Github is called `origin`. +- Add the original repository as a remote called `upstream`. +- If you created your fork a while ago be sure to pull upstream changes into your local repository. +- Create a new branch to work on! Branch from `develop` if it exists, else from `master`. +- Implement/fix your feature, comment your code. +- Follow the code style of the project, including indentation. +- If the project has tests run them! +- Write or adapt tests as needed. +- Add or change the documentation as needed. +- Squash your commits into a single commit with git's [interactive rebase](https://help.github.com/articles/interactive-rebase). Create a new branch if necessary. +- Push your branch to your fork on Github, the remote `origin`. +- From your fork open a pull request in the correct branch. Target the project's `develop` branch if there is one, else go for `master`! +- If the maintainer requests further changes just push them to your branch. The PR will be updated automatically. +- Once the pull request is approved and merged you can [pull the changes from upstream](https://help.github.com/articles/syncing-a-fork/) to your local repo and delete your extra branch(es). -### Other Contributors - -* [Giorgio Delle Grottaglie](https://github.com/geordie--) -* Hotels.com's Checkout team in Rome -* Rob Light \ No newline at end of file +And last but not least: Always write your commit messages in the present tense. Your commit message should describe what the commit, when applied, does to the code – not what you +did to the code. \ No newline at end of file diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 000000000..b30155498 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,15 @@ +## Contributors + +### Original Developers + +* [Fabio Borriello](https://github.com/fborriello) + +### Additional Developers +* [Andrea Marsiglia](https://github.com/AndreaMars94) +* [Patrizio Munzi](https://github.com/patriziomunzi) + +### Other Contributors + +* [Giorgio Delle Grottaglie](https://github.com/geordie--) +* Hotels.com's Checkout team in Rome +* Rob Light \ No newline at end of file From d7da96d95c44e6f120f9849acbbd439e9106fb4b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Feb 2019 15:42:25 +0100 Subject: [PATCH 0130/1786] testing automatic release --- .travis.yml | 89 +++++++++++++++++++--------------- config/travis/deploy.sh | 4 +- config/travis/secrets.tar.enc | Bin 0 -> 524304 bytes pom.xml | 2 +- 4 files changed, 52 insertions(+), 43 deletions(-) create mode 100644 config/travis/secrets.tar.enc diff --git a/.travis.yml b/.travis.yml index 729462fba..04a9cc86a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -5,43 +5,52 @@ os: cache: directories: - ~/.m2/repository -jobs: - include: - # If the branch is not master it just builds the application - - stage: "Build" - name: "Build and Test" - if: NOT branch = master - jdk: oraclejdk11 - install: mvn clean install -Dmaven.javadoc.skip=true -B - # If the branch is master it sends the quality report to SonarCloud - - stage: "Build, Test and Quality Check" - name: "Building, testing and sending a quality report to SonarCloud" - if: branch = master - jdk: oraclejdk11 - install: mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build and Publish" - name: "Building site and publishing on GitHub pages" - if: branch = master - jdk: oraclejdk8 - install: mvn clean site:site -DskipTests=true -B - deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true - on: - branch: master - - stage: "Release" - name: "Releasing artifacts on Maven central" - deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - branch: master - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true +#jobs: +# include: +# # If the branch is not master it just builds the application +# - stage: "Build" +# name: "Build and Test" +# if: NOT branch = master +# jdk: oraclejdk11 +# install: mvn clean install -Dmaven.javadoc.skip=true -B +# # If the branch is master it sends the quality report to SonarCloud +# - stage: "Build, Test and Quality Check" +# name: "Building, testing and sending a quality report to SonarCloud" +# if: branch = master +# jdk: oraclejdk11 +# install: mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build and Publish" +# name: "Building site and publishing on GitHub pages" +# if: branch = master +# jdk: oraclejdk8 +# install: mvn clean site:site -DskipTests=true -B +# deploy: +# provider: pages +# local-dir: target/site +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# branch: master +# - stage: "Release" +# name: "Releasing artifacts on Maven central" +# before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d +# deploy: +# - provider: script +# script: config/travis/deploy.sh +# skip_cleanup: true +# on: +# branch: master +# - provider: script +# script: config/travis/deploy.sh +# skip_cleanup: true +# on: +# tags: true + +before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml +script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Psonatype-oss-release +notifications: + email: + - borriello.fabio@gmail.com + diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 235dab507..ef123d2fd 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -5,9 +5,9 @@ set -e if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ ! -z "$TRAVIS_TAG" ]; then echo "Deploying release" - mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P sonatype-oss-release "$@" -DskipTests=true + mvn clean deploy --settings mvn-settings.xml -B -U -P sonatype-oss-release "$@" -DskipTests=true else echo "Deploying snapshot" - mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true + mvn clean deploy --settings mvn-settings.xml -B -U -P -DskipTests=true fi fi \ No newline at end of file diff --git a/config/travis/secrets.tar.enc b/config/travis/secrets.tar.enc new file mode 100644 index 0000000000000000000000000000000000000000..0f5654fe78f75034de3d3e3e5b56febbec9e08d5 GIT binary patch literal 524304 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

<36#r>Izi*05rK-e*ellBeh(JC&nEhBpCz2 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೜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

{;mrRZ(vRzsK$CJECXke$=)l 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¥k8D#tsLNU4hk-FjFqvJYxKwo5egH_p?)TRPA_`) zd4*W>7YOW8#`6uShF5cYCCuvx{TT&6*Yl)13VsgcA~i>2*7Feg76thCv+mB~NO2t} z4Yd#v22)=|ws1%#>4(n>Yaf7rQD}vUP)$gb3&O&DogMTk9pH-eeu5XP%FGv2BBe#U zWe;EN`z|#c%KTX{q*+(z_(%^TsXbxOTm_qaJ2+XFfcWk7W7&^QOx+cJy800hAiP zti;YHVe8g*nOO_~X$!`k!oLnkPXS4c11O5k^I^ zp>B@^1^vHB{YNvW9mz6;+9w=6(pRJiI)MX-& zb!J^yE-GLo;VZef)?|SLh4t@%1{6&%k`q9F6|al|YUE;x#1)tzVN`1%X<*3x%YqTM^@9vc0OqE7`Xc(bqV`M5K zcRarb-4=@si*^$xbHF#lU(`i^xsaU=u`LnU9@iHTKnfG z;?vB)LHbZsp$ewVN>Bj%%VbgLJO!%mWO7{jp3Jjt5kX4F1PM+l|g8^#db8)!CxiCNLv!Wjk&?gy1yR$*o!yOwUnH<%7x<4 z1C0++?R4h)&5o!vJPN}!}XqwPH_6fEd76p38~L!n0&-^ksC z8k^s2xnYUSc(0roU?bX)g2R@Dd)+|->&XjPYjZ=22q6mpz>r$A@XW;d`~Z593BS;D zo!%XmO;lTa`0f?YXQZ2rJ7S$Ev%pKjjy0L+Cx6EMs@i%O;;R4Nt(jitWVO|ci}EfP zU79e`zALK5Dt?G=P|&UCV9rG5VQx-FbQP8zD9t?4D!SvFkkP=7VCT%sG2F$+!T>Jr zm|Y!z?^tWeuHQXR9R1*c?THinD+xn`dENvGCEpAj5-XW89G0dfbw`PkLKjK9!QO7< zF8G%Kfz4}L^d0)&j)}#MG|Wp!l_ObFC1BBiYiUyYoaHs@fQ`7fXn%CYx%`Y}u&fx4 z^}JkL&-a3Ql64Wc5wGb*Wb1?B7gOcrIksf((QFMMm zI@yzkdj7f3>e5*5SdXfOvh7}wlFj07X~0O$!IV92N@4%Z_PG{7n?ViE%bIo|*w0Ok zQQ0nmR<$pv#$dr(mTRrKUuOcflZ{#BhDN?^M z-kvW%MFeN1h%|%zc|IVtT|AFhS!w9>zBNZ`@_2czZ=xa)r($R3n#blG?&?9`mcf%p z4htZml#tVkyPQqL_|x-$eMup{9f)*t*J-!&`m&MQ)c8!<_|o=}EXy)%m%)NiVQv*l z{8#JWXD8!|3?Hgu1%Ofpjsr2k(S~(;jvD-${S2YAe#4%nqnUbKkb#sVZ z#UJnz7(U^>A@I4WW2aY-YRf6$q6+uF?$3NS&XuN$BPWL?Nj@+I{pW2E=F@g!&0KMM z&eQ1zl&*X5K(GAorKs8xWG=qcCb}^bl;SGPrx&=vhhcz&0>GKB2`@P z{A5=TcJC16cAL$qL|IYp@=Z|}`PU+mkFg)XDwC~D6R;}>-^78^lv(hNrCPB#{O@Uw ze90N!cvK5wKPK&y)gf#3cV>`94j?SRT7Jo5o3_3$rgQ|H0Cs9kYtuE1{D5|TInd^G z_R_=;hJ*FeoYyG%4a9zZu02R(a$d%s+wSH0`yXJtk`9uqft#|irV)hULtaA2RQ?7- zZAuZ(_s|h0B!18!?M&1h%%Ou1mbPvk%XI)Z;S!7IF}wVGJLrH8uL`hj870iGwJMhZ z4q9~(Hkz5+PrjD$%={mLe~WNGp;0Itj0GyH^%mC32Y_qJ+p|QM{i7YTJxY87^TZ}; zji4kUGOWE<9mckWYtMkAPaXANB2$W5 zDGv$sGqkOsuTrQ6ex2u0tEz%Pw)`-8%cAfw-z!n$R=#6s_Z8&Mz11P1TO_n+?fe~r zQdn|n17?{g@V6FMqhP32Q_9dQBJ{4QfJ(8!g3`W8R?xctwowH-=&#u`xa(53CDK8A z*H=v&+TSqZDTdt4l1_m*6{`DXAi1mx^Umh*jz zc>lklE>>w{iBXe1gh^mfY8!QSzMi`r0ad8J!Ph{1^q?U|<{cl9R>B*N(QIUmXJBBG zG8*RnItNPFhyQo>+a-0z3tS@$qQ*AoS=0&#gppVErPkSbY&{ zj|K!@dsZJ07I4Yk;hrcgpZHpUnzLVW1AxM`r7{wk#S0lg1TOP7meuET0hS2UA$1+_ zHh+5b@J~RZG?9umC@{2dG}TE!*A15ahukKWruZu|0=&#a5qn<)nbZvTulVl<_6hF=32s%wd0~oiNKn6ct(&2OYO)EhaFhQ62r))g3>Ch03T67zpKBLFP$m; zoPbAVm_b;<`MVbZlp83FWAi!;AOr0NX1dK7nZI1br;LFG=K$qdp_g#+rk{=@D z(F)j2Q_Bth&`V3`5VH7`m2DHWA>)YRf_ieTx$W7K+UUI|$?4_K{6(C%inikhanzvt zUnZfL4fDRuoYbK;B>W3NaNGwBMHPEO#uP(o^pLjjVEpcoUW6htZj~eaj~D>Pvh7N^z*w4^S)(72OzZ!~2Y;Xy%s$vxcwu7^ zm1x*>3h@6kovA)F3AM+ePXAgQQsJmn#sWk~hRL_zvhf+0p>7}GV1cNuba5FaB`3peVo^2J)~f6PR&_(o7# z>M3`CckRSGs=xO?-stf)NMU2mKzr~jm`a)Y0>z>!0DuBr8|JEM`XEw5TIP4oQMkhN z-f(a??0cd{in-@Q_!(5dST7|zJN_mS=rAkW0T>sZM?b#cMXq{PMIp8V`fl$>`UmAA zP=cOc4d1bC9WzwMHSwk@^Zx)tclo7NRz!$`!g+tUy`-3wR|2q8X{@~tlb?6+%aC6I zE>O;H4Nh+;2Zp0PVhsM9E#zH0Bm2Pk@D>cg zGp)mcrIZh3Mr4bSxlt4m^B;n#&Ursu8Zt>yN#3~%(6tWy@Na+}0~liC%He2&hP^&d z_}56~tELdXViSh1ZvoSMFB$Qp|Hg?-d(a40ha2axG9Be(QXG5H$Oii+%|A9Rm@gk* z0AClV6|4xRA|{T?g2(*Z6ZuGhB<;+i35{;4lh=MCOr*7$uJqw8$dd~3QeJ5T-Z?&( zFxmRSA;T5yGZ8CWB40BQvj9JoKp-QG`r$sG6*qY{uCk*dHb`k?iBRNaj%HV8hzNlB z>KH-GY)Y7^>Z1uMP{Jv5@?+Z0zFj5GnU+K*^5Ii*CJ=6?{XSyc} zL`BFs4l{TZ$nLs-b>ZNWuJuY%W2)H3+hKM($aHMI?bDXsKpk3r%4+l;waH1QP0;JS zp?D&gf~LlFgU1+sc1p|7)0Lv8B{wgw;M$EzretMWcG7{*K;4eiVrb7i3*KyY-uGaR ze{Wf(i1~DH>)sEjpq8N&M@1D#et>}OK@$IDtmBgfoDY^e|2 z)lCRa%=>EA06E@4qw4jEtyI5}dm=?7WdY@QjYn<&cWDbw3&x;OSc(f?@&ZRg(}@L9 zG$+*Gl?&-J7a4z{+sb9DaztUM;&Xq&_~2*R@7#J>8k7A^{*5`zNY+UjKu-C|`ER8{% zu#_}D5UAljPHd3zG$O(3IDgeF`l`sYlm_I*0hKOm_V9}!R2h4@(K1aZDuN~c+6Dz~ zBqfNeXF^_1EltLt4quEm{@h!INvwe0&e4>QM+`6hGY;Le)tPBqrY6xHZEIZxgtkro z1A?mVJ>)EjSt?Dl<51Y9nGKNhQ{uXO9~+>$r1nOP-py4edSm<_Yr6VLM5SJpJ*2oH z2ZQaz!iLYFB?+mjSY81-9=C6E*pMvQ>iM)zl!&JvGYYicreofdvF0CMxLkmE3@bU{ zlEjd)95;z>RKeHnZz6fPq|9+CWLC_ksp~%;w;uMw zMj>Bv>kdSjc>`J?j|NK&8N7)wM~Mbbxsem&;uo}iM;;4mB!HPy)q^M;v^<#@m2n&R z57di7#3h8fHO3$wHx?`I$8z0Lw^dJ1vV*dv#^n)(_KBEObTIZGu?YkmeM|Bvf4<%r zr4`DyHxDR3hrp`;gEfMgYj5BTHaIz`?>7fMx+3&6M^ZTe$lwK>(c*0F3Mh%@XqlV(onjCX|!?-iko57+)m=aF; zvLi0rI)h24{Tq`&TeOU)vi3Sp%(+Dw9yj?Rs*solQJLLk>#qQikfmo4$$$!>s!lEVMwH(wkJ^qC za^IYz_a{qz610JiZ4Cv(D29LU=$j{rGmQYI3g}&81{h|LMnNqe5VmKE=sld!0}0D6 zau0l7#;iYY*;p}kpE(r?8dKrLk>J>BFa48(@d8s?Du&cy*|J33VqQpHw%dHs`7Gd5 zveir01d3b=YHPxK__L6;sq4R=2vh4Ifq~EM?S2CQz|0Hyz=<6QwltMz`DxLg>~eZxWdK$HDyMlRG^ne z%%=PTfFh9I<=ai738mDLe7%!ZNTEy(mkfoj`_ zxJtA~pM++52(~iq1g3NOn%yS$sWy3DOqz1 zyg33YH*!#1UF~x*6=I^6rBTU#aR1xLOinw%s0%&6pNjZj@dLvHE4*t1kEl+xwwgq+ z3?F=*o-|?`m@73|NcYI5Pl}+U=uh>t?OxIu&btM&9krP+mMqDZf5l1BZ-xV^f8~@l z$>?5CfTe3Y$s4f_%GDL`3vx=%0s|KdAk=0+8g_`{Uo8S){Xcb7JoSLd<-zYh zl@j$~2#3e|`H(b)0&;qC5OTU7?Ai99{UU)7mwKmsmki!bXpX{Wvwini{%ho#VdIwS z8K@jndjZ)`{7c|C#XsRo2VEa8j4=h5J{tB_}X z_=PQ=uYl7)12<8*Y7Nf7R8n~*OiyQUxi+4+SqLOq;j4S7pC7h4H@0xmskMu0&OmvLJl+EEaG>C1hF44|l8reef=X5GPL;Bes$U~dC+fS6>;%?M zv8W_W=fzLKZHY1dGH#QG3^zg(74f}bSKSoq!QgND&WyRup>}9f$$Vxu{dHH_Lp&po3Y^_nA<)x3F$OzBQ<=q%EG z>c>kq!hC6-b)rl~iDF0>+>YLoYsVf&`BYCJ^bOnO%h1i=45t@npZ=6sMKfLP%V z#VURRNj^`TG`pG}>Ah)+Y>6_}TsS!sC*?N^gGo>jMLO{0Vq4-X)mg=^OD?GjJBueL z71TK|JmEZ*6d?Bp^FJmmM&EUy{lK!$;LL)b`#~Y!iln5X2*fd>#w=&1^NoNC0+Z%` z(v%vlgS(is3fN)ayQ%qR-?fZnnB?&u={VNO@={RYGc|aC@^=|*dRq2764f*21EmB- zlC%PFA=f4@Ad@wuGle63C(ge7FvNi*Va3BqFvTH|ayc{LGzWQdvxc1joL7pBihim=tOm_-o5$GC++->Nl&H@j= zLNFt@LZ_cyaP9g^$pn|d>E&P~!_T}Q=ibh4r(Rg6q6A41DP01~C1WCqa3qsDM{U_Q zE3kg0qaRqod&Lv{mXcWV4)in!2G=25T-7OmfssQ>#TIael@Ao_oTY0ug_CfVpc!door0cFA4)F9;ih5~CRwHb6`M zn%SCiz49Jw(0&P^!vl;|^S)mMqrFzg>0FRrq`p|$aGmV>GWLk!`YInp)lM!INMYFi z=+}Li^keJP8N04~^?=iwzATrF?!X0~H=H)N>>D96#0*=SX-7@8swM_crRzTb()3(2 zDc^kUg)AvyH)+PjFo0sm_%TT(gudhq3q(CKWe)R+-FrBK4prw!$y z3tRjPtxmZfWltG_z@hVrgK4Y~OpntW1rlV&$q5BLqNfd?x$bfIX(E{vA}}>}A{O!- z>qA5>7qhD~lObH3Knij#*j{7;9Ji?Up1si|R=y53@;ddO%A{COMMz)+=YDYe=$-Ur**a76oDp0B%Eg zbjJ|FH5kt3tYNJCQ#Ojqfkwe+#w5cD+PA{Vysjx9prD8%eWKK&Zz|&aAN0CtF4kgX zdW_>LdQ3c!%Y}i?by|sxY!$i7x^}!_0L;9=eK7NPT9a+vk zIbGouSOe3|-sqW>h@uPa8|rpM+bwelcoIzIjQ5>=@f?hHeD7HP_o>gMdYyM@+7LTK zi$H+ZlN=9`gz7pve*d8=eAB)1=Mw?06Ms#gHJqXr`WS|kLd%~`o3iljWsEsl8c`zj z;?%@OW2kEgj|Q~_-y$Kh5Iw4Ht+`I<@r7!q!*1KaNqJ{T$f;D4UIh@C@t#YQO9$YU zjLk642CNS%?vZi!1kZfOO-V7KMzXJa_^<-Ga z_CQ%kr~b;<%VH=oq3qfWiy>wF!%NZ6UkpDkPo_J=&#yA;3#LvY*qR^L&$XK@*t5X4 z+_#NkD9choO;Kp`iF|2o4{nuX;%FeOXS-*C$y!@pM5BEmO9fwX#&ohT*c zA`OafO+X9^=0Bubl*6K|k*qsl?T>u88@9{$1l5oK`p<&ju|J^y5KmY_u}rk57z_Ju zkq-SuxC790XQsTDTlQjFy}`xUY;WjKb*HC4X~1x4#gPN1k3!{~0Qj`hJM%V6LM!`m zd8)!d*)cX-APcX7W3Eo&zd#wco0y3;LL7uiXwHVQ>}*-GmHPE|@mqF5C^z&5ulV9x zULGj=9Wt#Z%g!k6hDL*-DXg~Ge+F~h-nQql>ja^RbX|=?wJ*zv?a{VLMCrqZ?%s_U zF&!PvI@7hX$V_){{UFDkQ;Fs8(FL>1=|kDaA|9vn`s_0RE{yV+^wI4&4&x&T#2C3A#BqBNUW%5tf;^Rr{fudP3(=Pt ziH`~E(;^9n|Mdp$S!&G6!P6#J3sopWop59igz-@}j<@sjz7>q7vrOtMm49EyJe z#y|2GU8FkB2MJ&(%MNT{CWwkj$0drJn(iY700bp4Z9DKN+DWQhqfN`16lF&Ud4MQ( z#bFBnmqH8qWS({9K@m1V-c#lV?p*RgpgRY@vv2Z9pr%TYmhunM_SGl{h9ZRRiH%yr z^m^wi?=>5!wo(3JZ-apT;@O|Y@EQ9F54&8>*HIiZBm=ngsI}cYy4=)RTXb^K9rFNv z+Fh(AU!^aksZtC7hR2`V6@kw3IFQ+SB&hPz&Z1G@**p{f48mzZ0%geaOuR)4-zq3* z6rebXYR7XQ#2h@LvSW||cAL&5pc}RMwXDag<(7SE*ZWQ&lv_Dy;9AOuXHv!uDTImKUpWXhC~#a;R^hU$CHi3-lVpDla*G{qjvO zn}3^H;@oO8jg@O?sF?~ra0eXPs6So^aldV!Z~iZhjQ2_Mf@etnIln%ZB0UPQxuY|z|=L0(;_UyrpsA)(H<8W z1NYFYH0wRGrH}euVum3wZ6zB;RS*aGG#K*K2qhIM<-!=33P~hMtME5GvX;PLu)}@H zeiGCqKuER5PA5q)kAUE&4D;%Ygx=GSDiL^nwq3dW1X*gkxkaKk&vl}-wgoqYsp?FR zHU7*%>0e%F1$k;IPLi}5KUel0yE|Xq9a+ga5C8JEV8h2E_jfe0|Kruc?JjOxP`(TH z9EsYx;ZL+RD;{yHz6fNI%O$+$f%*HU{N@*sx{v;x(=(c9wZ;K_E~k`qLVyaaJWyxCux+!>MLx zuxZ?MV~3YYFAP@3syDfC)N=lTnoDiGM}^p8upszzvLIT{PBk-8tLmMtgS9}=)c+BGihi&07-UMpN?eYYqBd&@$4&S; z%spWVc9{CK!xJU)I+4lf(xaDy%ZGRq&K*OPaV}A`h5!H@uxr}l5T`~#)!bn=qMhF@ z-yCd#wf56B6;hogK%Bk#N-~M}QPwoGwnqjCU%af9EnuhxsqSp<_a!^U=HKNU|9ZG5 z1Q<#X(PEQS<%lStI=U6VNr!=kYY;KQYiNaR0oW2*g`29)>7&*!bJi!0-2bJTfQ1)w zQ%s{^b8{gZ#ZAo%kfc3MZ;NKkL!p3yGT5*3X0{ojd_fpUG8hFH6D>OC3_$>f@$&5z zt26hH)OIpiTExkAO)ap6)ez_how^D*ix2OK;r=w$6iA7oFfHMx0ev-v3^~udd_Avh zbz%!}p%d!A?LIm!oSAO6nI4rrO9ogC6*!LV4TrKP>=Pw;gcAGSspNQ?#i){-UBuOq z7fLqQ)D$ec&&VmR+*OP*-^0aK;8R_eVecr0A<=n4-l*<5a{I_4XTsExW7k=#^%>w) znqOI^@Dof&focIV*$-(q1>cXLhrZ1N6XZonOa>Mhv8FaoIZZ$IW=OkLlG8}ZRKwll zn`WA)?Qd2Yg*ivtXw-v1m|Y>dh>%*vB?m+X1jbVMvVxYlAdIZr5r(f4jY-ak*WQmU zV6i#_8?|O8o2hkgdE${Q?d7;|%`}^~W4zvMWw_l9^?Q^Zh*sgyZS9D?3h`$#@(gN~84QfKnR#4z?#?|Z-2#gmrkdt?Q ztR7b7=O5C+ebX>U>rCm?LA~*%@icEL!+^}ZWmoMGRK)7$8Xf6ju8Q+xwC$g6mIpHNk z=Yra^Ci7nP0;YH4|EKz@nVxe_MyFkXcz+MTZ70fQ&-*Z3duIA60lSCH%XFp9VD>=g z?4C-6^jV3kEMvmn&0(LGptz`Z+!}VuY;4xl3Q@QkAud2bl| z^R`C{ThZwWsg?JCPe}O!-cm%v=^u@DeA+%~YWATwYA#A^4r}fYgPNw8a8}Hm_3KWv z#hF7KZjX{al^{Ppl(H_p*rWUpp<#Iz+r7Rela5yMPy`34HKSa`n@>22=x_c`#C-OZ zy|tF-=>EyeL=Jv?5j(^3b;vS1^xiYu5zaqi0Mn2Ef~QH~(393a`1ams#KveYLEHj@ zqrV#xf-R~zN5$;9;_~gjl3F{`uY@^TwN?W(yjTy+iGIM$#UMZWNPwW3hzNhYS0zUm zZOg1o>Y%`N<2XCf;An5Tujd+DQev89ZL^telUZT1Vo@aC&TtZXfA5m8kC2A%A->z= zTiW97y0NuuA9fmPTTj6&YC^6xFNS@?;;=;Gwfv&!e7BEfVjo47M4tPdL!Uif-K zg?-hjuGn`;5->DQtb5#f)Njliovro@Nt4DQatyEDk-)p8X8EkTV}~mZ&d>aKM<0OA zC65E;%4GR{YSRD-O*`D|Vny<7IWAtzNfM229|~p;p(&As@$qoH7n|P11zr1ukIh_7Td=_p`OoEFMK@6INkr;eXe#t~2OH368oE??{tislF63fWrJ5a1N$B zPF>+_i_8-BOl8RsqizoH{AaZ^sjh+#n31-drC9xq8Jn$VfaE`$LunlQZXi&()r~q_ z^!sKe#mUNMy6*rhdnmYHu$e@Rg=P4VQgq)G)f~%mX}6yg<-s%RF~qewy~O>YPD-(F zm`ptFXkCMX!wGnvccLmO8^wdRiv;fDJUO>zs^CcJ*xQA@P#Wi?Fwj)Dao^vFB@`Hb zV|6YaI2ipl#w7iJ9AzcIWSr@W8^Db960X4Wu3{UVv*;0j{_Hzl@jfFX4>@fJKsaHc z(#GRv1JZl&$%Mzlc@%V{9}r%G{>48Fsh+pyHli5&Rg@D{Cxz_ryfA3q0j#UyLy4)e zvFb3AA=X>HUwOqnF%aKARJBAUyiV|L;_)+Qv6RkiibBaW;z6uf2Wrc`My*JG7`X=w=FUQ(*PB`k$S#XfFp)-qn&bR0El8Cm{}tyDy}$ zQ6}awk@Oq*Lfm2cp8dLrr}Rf)E4UISKF5Ht#SEsem*Zc~tL!=7<3g`s+io4;FI&4f zyA$5ZNM!rE{sEUUx2h_~CI^sbnP_9II~=W?X*8$CU2&xz^y5R;yv-7Tue^98)zodFVlD@v>3kojft6e;~!8 zFuhd>TNX)vd<@GI#t$0-kD!=I^h3PlXTTYGY8XPlV?A1hr7%{Y3jZz{9?rODWe@u=dZB+3FkN{1I}r2dbgY=^5+ z2el%8J2f1)$C93>0PvikixjNe$jcr(0wR?Qpn8!^9b8*Q!U0@JMhd?HCy_#ns9fKV0z6pLcF1hFi7iO{L{kL&uFc6cQA zLQo>;kG9(PGZtJn#gi=D$=^>Ao7$g7kDC{)f4sI*2PGO?mxbNNL42dn1H8B(++!Q!s zWeR)OPBG_GGKxh87wGLu+}g_rm#9A)Syk|aBc8;EtgN@4D zL<~X?uvis)IR!RHhhQ|ceSIL&o&dp7aQ?`j+EXCT=+@Fk6SB*`R-8;HS(H7L5@Pej zEJ+>zX#J6heIM3RC^kF|hR^*dAN(N~W~bic*pfpp6p4gLS6F%$F;$1id4UqT$f8bF zJN?^Fs!BphBSC4@Kf-$hSG*(U;v#h0igPn||34YR`CH75sklqNRrh5f(5uW^^@6Pn zjDu#!@jAY1jWS5xa3sGp%(#`?$*{#!yy>>O#?ejeYD1OV;fu7C>}@5;fAAdda*F)Q z&{mpPo^WOir#V7sae4yhsHvw4yck<|^g~-*TQrF}AnU#D`?On= zjs5aO^>vm(ZQKY1g8tQIL9AQa`A%em(7wmt**lcL9;E>S0VHN-q;p)+|`6LM4V96AqumRiJ9_9Yi29OzmEO z;g}D5+bOr!#tufbY>)fa(SUf6!qqi8c#BaxupXOcSoOMJM_f@jE!1K2j~AzL(b)-H z2B#-4q31a~U>~u;!_6{}{wczn8W&{`^P303b+S^0tVH>`78?Nr|AAKKn-N{vXZ)Nj zMdL%#a9Cfu{jWQun7pfx$Gog|Ck+7eL{B(lMqJ}X*fhrDm6_mK-M-`eM-7rus9xBY zUdqH@)BIF*Oj@mOf5*%+_-@-SusD zpkyaVBb(jngSAvDWUD0?mVpZ-MP+=hK_20FomisWN+-An%B&1!|NG2yQ2VCln4`dx zloPVrT=hX{%H~bsHd_8btOXb2TV{W}Nr)L+mB2Ky?33Yeeu3!W!NBq#Hq-k#iwC8M zFMxT-?7tEYm_%%aEKpFbBuBPnhc!~oeM7DAA=hD&;N5!4N5@Wbnr2-=SU(=lK^M+% z1e38x&|I+~8ni_WKny-m!0-a8;I$lX18*RnpPmUysC@V=U+qs5Cir{TY&%`MSxb9V zCz(E1GTOBB7>vyy8zi?+(RAsY5Iofxsgh+ZJ*s;Km1^Mi3@&dC@bW}$nX>5lEKR-4 z6!87dhI`Jhq0;<8FQml36SQ6vfMlC6f}R}o zu_HXS94(4v484Dtb3^G_Y zo4XTzes4mqt1tWn#8%Hs;lup~cd78z5Lf;W2?|=HPY0#ujU+S#R*DU1%lP=sUP#!S z8-zRQWc=yQy-+zVZr&xtkuAq28+-dqqEd10t$TpHmEZ9*pp-Uta#R5ZQ+x&=dQ^)I z(8S|iSn@aT2Mx;XL=5MMuB&$@(B5|1@T+;(H0J0yzYMTTx`sh|g4-?SEs;+#oP!pb z24xR8mAHBu37~)=ysLc|0B*;jO>c$q;vH26b*CLO)Hb$>5i5Xacn8R7<>fiTE^{tg za!pmF3kP@m7M9<`KQs;nf8JE-}Krn%^|SYz?yY)VC`R=4s4_c6+YhB~p@oX+~Br z81(0}8n_O{sL9gm+&g;j% z4a!5GK^2`djoItak`kK+nbC{)P^Qc1I>aJ)69}u=DOj|?(Z9HVE>yHz+fak_{dphVXZlhA$`>hkbXaBF;?XtXyHqW4k-u0L{hPrKI-^!hV) z&5?U31Hcf%RgExS)v0+_Qj5gMZBp*5vymDyyoW_=!ZWCV;>L0^iy^DnB7f*mo(LNF-d9#8pVsIu5ERrT?~lj z5O0#a-uc~mO?u#dqG1^9YDGRKB#EKWny}-sm8y$}tjGB;^yWUGLFsfb;}ey{wO*l- z-WE)oY4b@Tw&L0naDM&2y)lpG5rE3;YWVWn3YEj_H*Qq|@BF>#d@+S#$?hepx(R;} z6GO!2j>&%Cz;KL%w)q(DE!-r4ilyUP+<3~$B(%_UMp_Kc@0;B)gCB8KMWgcG*@S+8 ziBvD195tnwnRU9fvD&@vp2u|5#{fEhY@XzonSgxjqfZ z(p#jF4>+o=m~NmX5b)-}(gAOvX&ob3J1;7TL?7aREiO%{r#DKRXr$G?>ao}~$!EsO z7UUMvDv0;RTExjNEmopZ?7O?tLIa_|#nBud;Et!#DKXyR3C${)Ggh*upYlUVtfs@t zSpJm5qV)XNfIIDAn{?EfGQ00GwK})H%g9b(`!~Q*OMg?&ER@0_DhXy~$88Z?Gc;ga za1qpSgrU!#-N@uNEXQT|MH2EE(XK1&;H;F+_M37cl7HSVQwO;Np0LC@Uv#acL!hvIl{EhI_pjwU8>WU)Dn)*5^RM7qj0zji2%%o5$MRbi zkIGkm{833(h1CZ!+J`@>1<{8l2QsMXx`3ThgKffEyvaVk#is7z$(h&H@yeWMn=K#u z$k~cqJJFD;n_7WeqlC5fV1zjk9Shpj`SqgP+g_Jt9u|4lp~jX?RhJkCWiudRR48X>!|A<+~Vx&9dS@M7ax=r zfQi=(+~R3p1UkC{)mDYyd7dxt)UMV3o@H*fm`FXp}LX1B+#YnGN6PiAZ7Y&PE70X>*fw2?x(3&WX1GA;v< zKYl80{^c~7ZPALoCBOni1r6sO4_5K53yvZEW~ZcnK!osN_Fkjc0ev(z)Ql+hZ{88~ zGSF5JTfzb_-QybM>jmW(8}vg9q2Pm}&yDGIB5p8ouJF=fJK@dV!m?mB6e|}GxQ;8U z$QPs?%btgG+n%9ZTgS1=33|P!rtXyLaI-Ij{ZMQN>8(df?3QtV&VHEwibe}gj>0B} zggmq@VaR?_x@oa?rSEi8(&BKVH8x^aagFb{sJ!X@xB&>_2j><$LM~q#vI_=KUtUit z5p(ANz<7UQ!R9>5Y7E*{nd^|PtkHNz+F+lPKyMA$$}vK}o(5B$fg-Djt+)>%eqB6K z16l7rN?w&gfMZtmK(q*npk(H;K;P*6MEuC6q*MVzNVb2##)l499_fk1rg>L!4aZ!%{VAsnaiNJYbYdI5#&v|rs? zCgr}59dqwK6(E5O2)%T~4zw!F_Ny2}+NASFie$2t$=g{I!#KJ1LA~-)T>bmw5_&)K zoqFFY*~ne0_vKi!Qn3(u2dS>qUmn`+$OdsfBk>xx5eZZxOdYVFdilv0gS_#H05+Hz z^D@)M{CJ;>dAXf_!n;Dc9brwPA{<-4;ndYrb}lcDJ5nk!ZljWCimxa!Sd#RQQn>-VdDYXnZ9OH0u>Y5ZQa3-Yu} zArN_L2niNdhFgnW%ng=uF`;aQtiX}%N1has`q{ftq-kcLAwdU7ih<{mDCh!m>WPW{ zSe5sLe*Fcx3eZVwFw8?*8B7(!Gd9lr6ZO;e;BaR1f1Vnd#bcVv2M9$TYuAi=crX+APiWJY#Hf!(OE%&%4Q$`4<>AgL6bidxHI2xiEL z%&m=Tn9!CQ`%Vv*hXL8mP3YA%dOPcx#7hqp)Ojx}mz0f&v)VRnqJ7TLoAN&>X<8eU zyvE*Cdu#e^#~>`b%60njq*e}hctgK9(+u~HXdmk-hjlsb7FIy1ak>oDBCWuo6Lc&1 z8+TysxR(N%5#5uiu}$~rkT`DUO~J_B7PRBg_cE01%$p&TP+^y6e{jZI-u{52ezr?& zD9S=JSzxETBj~CjORC5Wdf9rAbm?6$98PD}<{__D4Q*NQs(nN_L%f6JGJKjsg1jY1 zd(4ohrh5@PD~q(i5{`yyzjrw2QjnEPo#Q9eD3Sn#$H$VRH1?`E3qD;RT_c!nN|pSGc{IG1mB)at;5fov$<^~bhI&ygx0dPxjxhqsB0y0ToBu# zF^LSuxO@iD**eQ=wERn&C&0N@%yXC9b3q05J)pJPdi?yq~N{)G3YRhl>0vyEq>33R3~sc@Q6_uVgdMB5vj@gZ}S5k+naS+ zR9;qgO2t&TQ93v#(izWFdU#$jx+($0CJ_C=98kNR1#ZhGP(3*bI=Dj7PfJD2z9h&C zWT7UPUJS)H4P3yZp7fq*Nsqy4b$}IPzA>`Pq8XU8+zTSIl>ZB^Ns4gA@vF&(m)MR}$z@qn(@N;z_GzZnV%rmuKS z5aXFzm_eZ%MgLXoizYoarrPk=@;9UjVB`!U>GeeJ_j`(sC> zm<8?{wQ+1o910v?s?=B3GYWs2wC&>0p!dXqi>iCfw?UpPI=RxSE$-Y1KSN4=z}1UG!mYkoV>nM+~@`= zE?bOwZd1;4za2aUCn3$s1751*3jh}P6qFoW#p#p#_wNuc9>=pHtIWt~=h?0s2?Z=E z;DzUd0o2H)hX!6qau8ojRM!*nr5U5AK2M@AG)SUztk2IBjR=yLq>rt ze?q81zBD12BGF|Qi}O`hRj~^@hYb`+Un^0vNSZ7iE{)VO#@@V#w4^|W=!y&FS0St3_K`pO@3xfDK%BHyat8x0OfikL;aD|mG zrNC^Bg@k(j1JWIg3=q~ElyE^cJ zg6_l^K$#Ev+C(9e#o-H#Zs;6%FEkz(9MpAqjJ^C|(X%pI-Ig881bZG+i?;f5FX(j1 z2fjBNcfOOOcpU0Z0cA6TPtILZi>=@lDgvi*+Zah_D9Nqg(1WL91jOH*XII8L2n!tA z%Yy^!ZUvrK*cW#JB9&ker6Nl27>nlv?kQtaZU;xN&UD{lMm3OZe&CU;MMzKU9~JX6 z>?*;M>?dBM=cY3mI|fyYz+>Ns^en!gu<{LL30M=PQ`_Dx{Hvr>wpXl|p(FqMKSD6E%)_&35MaQP=O=Cz_8=Wm zms*Si7}5N6SG1SUqAUj{3X5f`*R!Z%8-fotq|V=;i4^2}`Pq>-6YKpFSP(*%0#(eEr6zI&@G!IipdXy(|=Q z{-8gy!d?Uk|!*z19^_nR--EN&*tS|?AaXayg~rlUgII7H8UMBToCEOGz=fv ztLDWtD(GyoD5IROKQT&%-kwxPSKtNm_+vJ!2Neva9* z2vj)0)=3M)Hz9L zg=B**xM!njY9kuO7{T(7lKztFaePQBUt^6j$zY%GU1YkH=OQtTL?}@`Xp9a3e}59J z#7=27>!P9^qyNRIuRw&7t(&`b$AJ73xBs3nrg(|=qLyVv0Su0veg(>9ip7<~%Ma+^ zg9*51QQTfgA*a46KJ(_5fr*w>5mZOSDL{k2cQyPN5d<)4r(DcvZI%CTCBL?EZbX88 zM@$ffYYt<)08bjp2#X@?J{)lDnJt4|<; z#4336`Kjxn`Ap_?FUWXRFYist;IoP)5ez$Yx_y%M_{~ow%>`9#0A1(hf(xcC-MeJ< zMl~klxW|Id;?Mc)?suBqsfp+G{*YC3bWeaEac$Y?rT(sl+4;qa?RI3l$;)Ef<*8~V zSvF6~pNq@;^62$^yoDHKG5E@Q!oqLP3dUroz@F5})e%h+{XVA>Er^d3w*X|T6I?XK zog1PgA;#k$8+=x)FUd=q=Dsf8uzaJQTDY0uKBOeSJ-9x;$m|fQ+xh9O$&QY8b?Cp0 zQE*#fx8G~w05ywj)e?+ox!AT~Xg8=JYb$zWs%^cO66bpRKM_dch#UT-RPWPJW4+TGsGl)Xrs>-N3hN&9j*gH;hu`KR4=|J zRnTsWU9FV`@=;r2oakALQP~mmlJ0Rjhv0S)5z?`)LQeN{&#OJE7ZdR#yW-@TmyNhg zr`55Fzup=fc<4C{{J8Aw{WkDBaU7k{5kqj!b@=q)C~B=0b`G>ztun>V*jd(g*UkD@ zChgDX?7rvmE>ui_eaZEY)@s6gKF71JBh@Z@Pvttfib0U4ol%P5vc{oLNbHou*Es`y zA6WHWDx4;boF;Zfc1dlkddKFi>I}79qU&0HjaooP*}PoiV)gh!}+BtD8C(hCF0P4Cnsg6%dXe01!>$RX@zh%BadD z8zHh;H2^*D*4NrZ*7thZ5z5xPtoTX;)4U`-q5`&A>nM!<)zRSbY1s>X=$UatZY&J)3|vV+-4}dnv#2hYAsd-|1 zmvbmNb-wJvZV4wTHKz3RvGT*}6OW8v4y*8_=M=8zyRvi46kN-Ga9^hJDsv3CPyE*R z0ZQhiV3Wj)55N^u_XwWU2mhH?$TU1ob|-Bu5Z^^S*fmg-Y*xQ7!%5^cGSZM>iD3G|E_2~zJh-n!JL8;U?Bx-$9UtWNGkPdPUrt`{l+0_77<%E zKN>;Zz{{x@0K*@j<%z7tgF&$UEQ_Qtx}QsZ41vN3Bu4{(h$+)zBRJOqX#go_S7(vN zFM%&@vpayEDnBjv=KIo&`@}G1aZ+sFkefHV;`iz9)*O7&f4d-9`A>ntY}N|@L&Du= zLPeoF6o$xwYj3sN8-_*Y(z1PN0?K{KDBuBGS4?s!RW+MGcg2EvtX3$yunIJDAd~Rt z!Ji6K(@4i~K(K95TAQ%*L*gnzw+iF#L;SlVnqZmPS!DN4dcaC@sILxLM&qdZ8GH%U z%^kA1Cf>(prt9)ND@+Ot01oRQq8Dhpn(w5;RaV1DFGlAEzVo&|DyqL=Tgs1TrkC(3 zsB)RbuIqb`n6I3IN;84LE{iy5GaK{aR4jLjO&0Lf8$jH~jFD*|T8lAUy^ zs3b$lXue!Tr|r`kQe^Qyj1T&i5yoNsK=$_tp1(;T!}z(I!|xT`ul92rbq2Xin6#FN zKCa4#?-0TsT7WRm-&av3Z@Q||hwh&Zl~|Vb^K3*EC}UiG$5&6Qu%WK_-sZs2f;E=d zTRfvxNw-z#J)^>o!HF7gtzJ|mKh<=DgU}It;jdM(NXLWL{vY)pSbe)VDQcY=+_4Pj z02u;Zd1_FDVYIQ*^d!gZ!OhIr^j1aMTk+cfc{ZKIc24onA^yZp7!tBCb)PTX15j6w zKku$h_@k$8qHhmJHR|h-mW9*~fN<)`k^N$!aLV6L#-=)qJgS(51+?pC_!Ybjb5)b^ z4MI+hdvuo>o^EVRb@dZ!-@OyY-)1PSMMMN#NfSSvi|NH_aO~hGS-I^z!a$KXZa-8lX=xMaspe}WT2h-r#}JDtoIPsfu0bI z-LUc^eM$mG1Bo!0Q0Aa~b%Ai_1W8Qe0ZdhG5}5U7CRB4pFfA&xCD98`Elb`gQ^h+b z5Iiv7$FK-J42i`h*iDfQ_DE|78rBAJIXp=U(Gw5!A7e0D4Q1b({iKxp`G(J@3pp6^ ziIe`r;Jn~s^|H$+BD581)3-+}4}K`Z{ewf@xe%(J`Han7=P5LtGW|U3bEkh7GW8Z{ zSPs*y0|B)zxb6?!<3s*3nq20@-km(b($kUq6Ut^-nbDyO&?LPeBtOXFW-c~evu zcq0pSL#sxLGvM78MQ`#sr#a0Iwj`!R)7@+FM?zrVoUiDCXBYB_^R3i+jCo3}^lJ3T zAbvx9Sgll!co_<-#59Vrw~|PpTZhBSg1*#|35>Jj#QFwUX85C;8k44Ip#i`k$f1RM z;+cl&pEs6nisl< zO?wDL9Q4HC+EM9}q&~LNvn|K zX}}jJ?>Hw{&+Set{8vGPD_c()w zpjCYFGojyAi~iM-)?+S()g3zD5yI4sZTP zcV}BLB2QS4zeLkvXTwsIy{*>Qw3iCyBy7y}KEw@_tmpS)`Pn^>z0Zc@jd9Wsz0w8| zj$e2=T+UT#V4X?W_5zvZceVNOy?DDKqE1eSd4~iGdAS;vBxdK8sd-d|?&aNBxM7sk zH86ajQ9}rLS3y2z8iqH3WqhYZ$adU0!PT?{61SU)Xd*Yz!)j%tLG-sKqs7?WE2=S- z(RO?|uqElaq`0OGP)M7()GR}bAh=WunefQIuVT0hBNaTWAYx!XxROqx6)bw`1i$v zq`u-5c5ou=icWn-(N%3?awC2LjIwjN=f46Vy2W_KwnSJ%y@jS3L9e2h0oLW~r--C+ zy^EoITC3fM?C|~`@aWO8ZuSxui!FnKJe#tg#?6iFUjhUg4d^BB0PirjdrY{g&#*-w z8Y3{NEYo(w^vgN8bCn(xDhDwxzZfGI13B=hGYb9sLV_LbpaE%dK{5g1?62LJu^k_P zC$=})u`8`&nN=)*i#=g8yOPaWu~cmuzQSl8F@RBz&0HH}{jw&eahXsTWMl*1c!l z6V$yZ3>qs??e3;(U7y@=j6|!z;Y5oTmN{kMLBh$H1(-Tkl27&BfwTf39P$i1kW^QF z#&ufXvoNVCaaw6y&#!XfKnlqrgZcnrwOEkhF2jc~*<>$3bQAOL4?MC_*@(*Pl(&SrUOwo0B!-2&Q;Z{`SI$^n^OwNE7y99oqt zJP(w!hdTGEU8)RJn&B#b8B%l?Xk@P8^vTDPJ#jdNLz9TYwcem3wf2{%hf-8wRe2@K zXy)I|!<%%Zvo%44-|y7h{>TY%95tjgePFLp2Xo!?qyrIzv}zBAulc9mgNS3pl0N2a z*#!>I)j0%dAdmn~BrTwSS!VDbro7S$$ItP$l83kRcXLCgd^j7o@qM(FrkH%K3k%Cc z+jYz4Tt4kIrfrTn{WMHPvUuSV8J4=njUl1m8@*t4)IpD~;xhinO;)FqDEPNa*b0bf zv~l^$!a=6<*Bj?$fLJzp1Zb|FzI6{q^fZ!96`Tv8A)Xv5mqp% zo&}n|VY>bU53q~RHi){RJP^hUQEGxF;N8Jcp4^NhXACn_ubsTG_(>eUVms`FxvQ3v zvR(lhvwNY>9c5eJf20||iSG0WaWC79>zve6RL)nE)(Sqz0wru}Yqf{M%%4_&%gU^M zQw)fSZR$8K_PX?z`|RS5)b+MM2|yQFwK=w4dYsjh>n>5n+ZF_Z$EJXr{O#_0F&olF znvCcG8)oaZbN&0mXcJ(*<5?*yn5g?@cKj7qf`4HTQJyW^E8N3RqJ>-Mh_Ehs2Kt#H z%y0NYUYDl2CJ*IfQwcjz{c~ZctUN{eC-9qYKn27wI>e@LH$a~4M_ZBY%?LX z4mN@swOQCj^Pn5`$-U}H3lFaCo#02$?Hazt=!8TH#Z|m@D%~l*mU~8<+WC>yJx0L# zIp}RC9*RvdSu8uf+QU)v-5G|`CQ-l^ecKDjwM|&#RR9oiu7Mq}WA1VYQOH2BXmdJt zUyxLRKT^#wU!cfzwq`Es9uq9>U?KoqEDG6N>b-4)!5-n{U8q*Qa+&{t zzvN=z)Lh{V_>4;(9$8qF7rgMzN8)Bd&>y1IFz5o)7wJVXiBk&q327M5Byq!F6jf*< zxtkV1uV(`n*SmTH;QNiEfa1bwkmv>zsfLVH=6;dVP>6It(sla!@@cFoEbY|{b(00@ zMRZ@gD*6xv#6pVLkWNy?T2Z-#rOmnlIY$s|JUHxX^M~o^#zRN2<2c~yRzZSlRsPVi z*F0PZ(<=eY?Vgp>>;xu%p}53;7?r!Q4hEAyP`WvtY1F=-h(R|lnEKhmFSQFHAY(h5 z*tx;M^7N*>@NCobMnu`2E0<)9L|fEM+^lEK$OuBk4Ks)62D$FgNzTL<7d2^FOZ`pD zLJI^9FC-p#P4+cPST%d{4IAMZjWAeNmCyDg2+M|d#HjS3hp7`!k`kmN%jufQjb{_D z-sdFsO~5Y0G=bjeaZFyrUBgJdZE1ibHwaD=P}~0=SPDB7GI;O)`WKMM3A%|Egwv9~ zm+V~9;xGiEL2+}*b2v{hhZ6rbn-UgU_1HJ_^?eirG9-`xTmF0=b`^r?8+{yB(Qgon z0jYm^gTj|}4mT330t(Z1z6&+67n=J)UPyy%{FyP~Eh7hFHW4yK&0Vi~B3DB{W>6xQR7iw7#RA9J)Q@^*G-4hqw>~AesgU z2cRxXTLTQ2#<_x(7n_va*hWwWOy}T zkcg*rsddsD#^0}SJJmn@vj=SnScB&rPOP;9WG5M}A>X-~4ssEc%)qP>%D;m`%bT8# z1`}pn=)+xHn>BSSx!#;#T|VKdb5yS3sbl#hBi?qj%YuUen27fBl)L;dULLy^ zpLt^NKGajD#yL0B-f9196d1sJ{qv)RE6P4zk*lB7LbNKR<6dLn^FWI6BhGZAh52@K zt;SwgmSTvI014i1_uGDYoGk7<0Ufe0{4_thTP5~IOq7%e#M0`X;XS|Rnrt%(Lm>@B9p_LTnBcVG!QhN;S^S3xtvUiDgS ze4m^+s=%iwRAIh;SyW2SZ&X$>rEkIe2;u^|7tuCLB`V=y^WMDueFFy(eO}ZmfI&yV z1TmzF5Gm`To0`XU4_@L2qgyh1-i7*4*)i9OK&P*L*72(G{v6i+4KFm(i7@&%!|1%rCKsooS{JBpz}D}fTo4won1p#QiJq}v}7QCVFmLI z!8$~&)49v6{IKG)!6=?|+V~!ll3@B{DW*F(1t=oo8rdHcB4|$2huhKF;J68uy+*ge z7*)nn0f4{e$93cwd2HyF#AT&H_o>nCYN5;sq~^_?qLvA~CUaR)u`J-}&27Vl&M2#G?MzL7*Cd)H`knaj^*3?GtmZqM;1}Dz zSu~X)+_B4`T8Qu8`*GW+n_OcmHSwI<%T>pH9kLHN+Mt*%2SX$$30_?Kf(sR`316p@ zpy^YQT}XMK0{uO)74%&1dG0fXnJcW&!_kU++5G{N+7kKKC=p0g^MG}Q>P8rXw6^+? z`mC<8*t{X*I7%TEa5#S$bm5CuT;=LQu)Bw$u4BsFMxbjLx2HQtdcE^7!4Y&DgNMJ1 zFvqiS=aBs(wB2b5vCjKKM#~741LOPtMr~fMm0HaxXciob021M>*M-SaTj8im>Nw#F zIR*mLE%W2Tm4)Ip3rdPtoh^9m8?3FrQY|#-W}j6u!G|!uA>Qs_K^bg8e)}DY_nwXb zmGF2ZIDHm7bD1#>bQNxy^2u3VB*LN%BiNIII@&iFWxB_b_q>z%Zy7kMp5$d46CBK~ zC848GgP@kYF!+ZJhiCbQG~C2sdhH7N_ky4$_^RRaf(%T~*|_9bQrrZaa*E**y8A zC6#=Gs@N6`5}irDLQjdZ+1^H`tKUoH<%0F8@;AQg?*2!x<+45WX8qR|kc%!el)~2lSK76+K?Q7d zqT;xyJ+K+#bLIxaPM$?kATJ7UyKqHU3Yy%Dv(~u{*-JD+c#rw#CaLY7FUUtwK(~F) z{#&;WsYz7;@<(~_D$cDCNml2N&d<&gp(Fw71JV8&->?JR!zMUHIHkS#G?r z{Lh3v0tWgyb|DlD(pMIE6gx1_?;M24=kB(EC+;CI$c;d3V{rk@3!`= z@XpL00klGiVFF`u(}8aUxn!DOIo%6hgPeZ(lH%!sZQnrDnhU>pWIb8R%gbYZjU<8E zEN$yl0M1cTRfe_x5++9h++eD8wM@K4>t$pJqPi+oVNb05lnZm++d2wm&mt@iA-_hU zeX%%^cg5`fkO*syt;z)W<&Wst^KqzPd&5OJtA~`ysyf_e5WyXL2<-n07;BXC?^?Pw z0hs@MK~mx3)2)I+p!=xT-23ydP&8tmBJawu*~ckr=j)g9p-u0%zo7Az1BO}1$&gR$bDJfy z^}U6S)kTz|E>qn4+ihFHYE-wPo2C)L;`U;lT4q(%BRxTQi#j?y1dPA#bt9fcgrZih z*ae?QA>BX^K*$+LHdU*Biu9D)^DK@h$^2@$0%ShqS<4yLqP9-qHKN*r+D|jH#%4!O zfj#SilF;Wqy zqGTS^3*p~8aNfw>1T=7Y*fevVm@+3~D!>7SZu!r!5nHMPO)Y{CG7*>0Y%mE0kl50# zlU`VTA!N}JYO;1w9$v;pJUKAc)dh>Gg<<8G=chtPFYnba3S-WO+|Q(pyqIp5<2sP@ zlG&*pm*we5J!z67X_yUKcqcTKaoy4>U*6^EDKbk-=>(t4&pcYGymJw=RZ8dz2j3Xr zd|np2)Tq+9>FZ>>qFp~ncTt>_kdMF{G~|pq5$R^OBYDxjSX@N@g|>^0smLEcSyF_LD+OM1*6^L zewq8L^w-QTH58eoXwyggj75o>mYhT6PQVHg@!|?eFwae}C#5=w_u^Q#lqJYS!wjU| zH63QbJTQ)4N0%Kj@OI{rET=Y23HFpro#3~15GwctjrY)Co3&HdFw`%v>A_iqt|=M< z9fN>b9-&Pm8Unu`n_WiHj5|1UkDZ)5u%QG*d@oc%RX)g>+?OHLM#N`0KhNbvw9_q^ zbS;JwPnmj>;)h9O(AJ3vB$eNRbOWD!p-|6Tf_j_h@NmX|e!r1vkF78+!OWDB*#=2& z!?iv@vyqg`)`wwNp%+?uIB%p^M-uBWiC)lL+mwezMW7@=QxZ*S9G*Op7%3{fZiS;W zegi$K)iq;fD)*GFe9l21$ z$JKnfZgRQMzgm6cVRY^Pi+m@Uz*6!OO+~_%u31)_FO3~UfOaRvP~3TCjofWLUYu?9wygz2OI!Hk)&5Hu6`<1MI#%=dif2d#XIzr*VvLTg`s z*)&@uflHHnF6IHkFstKDRYU@)gMzphUhiKXckrsV1LW5F5P!@|`Y* zba&!)o*T)~w}u3~Qo7J`7n&cweA9C;FNnjkru9f!`50!ly3~?A7L+Bu1#P)!9Cv6D z7(e_}G*apik@(r^a;15!$hw=Ra3-|2GZ4%Z$82;jL zlljB?&aI9t0NM2M-WN=StMfFg)~DnIa+*CHR%6!~O20$?zG3E`PR+NpSo++re=K}x zd8Zz~uOsJ@q+h=j8oQFX*Ul;d1}oLW--w(4s_`g0Q$Lx11dLJ*CVoi3dVeMm ztYV)%(D8QY*wY3c76;@7vq$?bLlY)S)4nFx1^Fo#SqvOeDtyKqo`{e^imxeD@bs8K6-A zsfsLOVUv7S`+ujnrEZgmDyGE4J0(R+fvUGx_CVN^#Q#@f-ZPQfPlNpA%{Qem0PhRk zh`?mTW>vZiq+R$_r>*6Vy=mX&BS#)Zk!HdRO&RB5EWi;SR+A7G1!nEzpI5e+e%oc& zJE=AkXNTOam?h$*36AiI7synU?F}-9neliP{>$brfym?d5*3KL5l1=>Ntc#Wtdu$>3OKES@s{*p+rio?>prx7?X{@d-X|V|~^ads5~4@oVUw;TU3v z{8VxixZkja($BsCw_zNsWuf=Op_PXd8%tk~8CjfCQHV;s93;a z9X^^|0h3{NWtFP>8bsgm?AH=8CuN;G3WD&U?g1Ue631(wMRfvx19xlRdJI~Y%#4pV ze{!0X-#dFOw0XKf5`IqF1KK?FyRwobUpGPG4z=Ctc9ZW*Qj!QMr>s^AzCr&g%0TI* z#Xe;arN`0FoLS@!W@HxDqWL~M{r5swHhlT^_~H$1%MG2mYyPVhk$xk(8P7%&UP zn`oFo>f5*wHeeDrFP}3w&tX7yAJTOUhM&C!{$d{T7=;Woh&8b%Z>7t5{=CKWam|DOt9J561t>Frj*&$ zY=XC=+3+IX0gqwKVEXdnn)RNceA;IPT*1>Rkd)4@|7m`2*$2nY+DOBb&~>d0h-m0 z9kw|Ku<5=F0VpBh$FkZ;xs)JGTklS}s%u0z569DDC5~NkKWvF8e3OxNDz=giQo>NV z`IT(iZQEJgDOJ6tm5h}3Q%1m<4bwTG)etyl(tBUlf!{H6S=-^-xo|p)AbTi7GJ&X9 z*dpASmS$GFOutTzU{+|0?aD)Mt{qS*@@ zIBaJ|3liTquEzCBt3;w1Ue(B0<@RGl7dAf8^S1=d5L^GNIzlB*hAk7&{b=-l_|X?v z4d8*Eu9CT#k8o7ri3d1$&j-I_#DCo$b7EWbk_^Wz^F z*+@`$|WYZcFk(QtSsjtTlm)5+(L@~*XJihMsvy6{2J7srzNU`j-N*K-| zD!`z$Tj<(vA!)BddLzmeHX^ZcNlUS=Rfj-TYBkMD5*Tr=PZ!F3eMV$F%uB&}fTDx@ z*x1rQ>D`|}u|nBzm909*b;1cYPDAnNh!$0q5Y2wWWmy`2YhlcyS?tnrM9DiusC^lz zmxjUj7Q+OhONIM)dmB*wqCGNT4=F*}^OJ@G37*)->Oiv;_$}?BD+eYYk`uIgO{IVx z>;tV<GJ_wpp^1G)^srpsnhr|5_CYIw|N71V$h9tF z>Hg7KX#C2QI8?QSS&K=-LEeu0hA38!E8#`jVOww@sryu5%h3e)4jwO`0h7g*T+ZPi ztrqZJ%&TuP<8Oh0?C*)_)^!gJ2~Mc}J)}+mT56gTj}R4W?ltUM4MwJIa}bBDFNP7W zGBBdietJ!`mHq~5N9}&8NBe8zOpU;)Lw&Pvm0o?!F89}>OEdtjTILOMlIT0EOWgeg zli=*m8gnCV>I@JlYOOH+=Jh`oeFM9lfdb1obv*vWFjS))P(SZS@%M^p03@h!Z{tFn=#{hLDk$4+p2}jCqN0u zW*uepA}fKpaCidC{SkW)3cOKFdu~>Z7rt!2+A3tUQtIGVnssa*INlP|h1JZ4l3rB= zxN~HnXWT#*&I!cp4uQ?t?KvgTx|o&05V+Pr6iT8UBm|b^QZ%3$h zmvX~Yh)h?;fQZ;KrR?1yDV!+r6q}cuk*P&aNW%PnBL)p=Jr5yReZ1W5x1#vso@zv`?+FY+D9x+_;GPzJ zJA>ARYe&SI&H$Nb^$!P0`@pa8?mer1?c%G<4CvQBwMw?Sjv5Ql+a9oslSV854YD$S zPRRbcoXeq$07*c$zm==VdYie7@72$}tvayLw8D37!{?q_9njWH;Q@Qo9&pKZZEC?#AvK@y z>t|qBu~A?J+-?ky zV7=x7K&g#6QlK-@t_zs;)1q4pzA=_A+aXjXFOUfT@W;k|GfB#w91-g%3>aEINmea*gL>VbPoia^}DTvp01M|Hx`%2AV~x~n7)TtQ0tU#FHzM^ z!$+&uhLu;ld#5qnG=O6k)d}LPnq}+}km}lT=EyD+Ly5Q+%3X*&%=HY;OONO=_;D}a zL0DPY%TnA&697T2B&=yvN+Gm|v$Shj)@VAKbeS0dY`Fd0LoGv`c~IC%k4X*$T_0)R z7uGiE&+rf|q zf$YBPHH)~l@4gdjvq~vG9L-8T4V3Jru z0|N)H%yyt1Kt*3xfe%#DNHgw3D`FUoQ6zqSofUF+CTooD@tT}f8q)WV#g+2KzCb>h z^{*ZiVP>6A`n>1;>v-muc~agJ)Im*(Xe9^XORnsJnoFnM1>i;8A7#zw6LQiMvH@}N z>{6bOk(@oHtdEQ@K&duH=A9v8u7x~sIG9131JbA?b>Y$)B<(V*sM;Q6x5s87x2*Np z;g+@m$(>W z$Nr%`i1rxdfi?Y&+fa2}UIwzeQpyzv3FNPa`TjZg5%1UJ=GoL%V|Yz8@F#Row$L*U z|3c-LD&XJS021kj9ifgU*Co^_+cwf@`83l$Cl{%8RG6!!wJ-}6so^tmaGx_>o^D!^ zywWZ%xMc!hk6}Scj#Vk=%BkNg7Qq^-RwCcqQkwYLwV6%D*Yl>KlRec^r)j! z?0Ke4ha~f0**>>|s$z0|&#-Ejle*Huo816AvB*Fotytce>%_%!k`WzUQp*doC)= zfpi>($WZ{zSTAS+{dVsQge1vQE~-BvEn$B}^Jy7TLvgM3$MX(^8mCIyI!+vIsW}(d z0uuxT>rDgc0-CvIe>E%xL)&}P(KzfQXtXOsH2G$u2wHnlhom^uluPc}SFkg8F5Rcl zj13;M0#9H^$z`&G&r^r7a(P$}fjNGBBC#b^_3lIlwTtUgRnkoA)eL;Ly<$@3Aj)~; zmzk2cLLi6c`U}y?G`D7ITUS7X8Z}yqlLn8`BWupwTXpu6o-;S=jlwnQYpTB-zk45i zY^vFXC*@lGjM)00*y!>PQJ|S;Nj33(WvW62yL47a_NkDaU7*`I$q>UVvWf$i0yo2% zhfephUtV!>Rk){0s74y`zuVaDv@UjRIXL+yVd-N2Tj|GIIh1kp+465?p>I@$OB8Yk6-GsJZ>4(E#H-gU@dF`XbSk|H|AFeum|#ypFesAiQUH8Mj1X>l^zQ({6o>Uem3ZTl>4X=G{0fYgu0 zb)qCUx-%Jfxi61qWpG&~Wog|>4Z<4`EqVz5U4)l0)FEwbe}bE`87Sd*2|oxg_DUaN zabVaW=EC8qP3LEDnD9Jq(wwj#(&o5oLyNUgZ{VPbU-dvJ4daiP2Hh8QUe~Is`Jxgq z1dZwkkDPsPG^QSKoNY;zd$zZe)VN>*rNgmE&7rxU>QE^9-Aj>_YJ?r3A*s^s0tbi- znj0q_0%)jDDaZWUowwHTRGtT9z|%&eL3nr0jY`?PgT!j|n5_?ks!l}#FYsl-2pO+F zI)+Y!QFE%XE|H%d-{cX9w?Fc)JRn>m()}fuABr)q)A$^bvK4|8_<4w}8E7>BP?VbTC$QZlG z3@c2TcH{;n^4|%N*P;lOFhc)=^>CMXS<>A}Gb^w?U7o54*Zh(h-jERR$%GPc17jmf zF6lHnu}T=fXpVUF#kerq%DWjs9L*$kkU!035Nlku4m|Wu^*B`o`uP60zCt^%S9Iz> zWFria$4SeXzOE$P`l^cn7q@{Gxbmo;0=bmu>eR2e>WeD=lT&L0t0Hf;AAbEW-~NnB z8VwIj@MVcIeaOwISJCdnO_AiEu;NL^iXn?FqUg`=Ywe)dUPL(RUu*Hj4 z#cXXo=W>CEBK?XQTAb3mtKG_9noKpkEJ}t9^s_>imTJA7xQCWSPdK3E40Rfsc$Em` z`iAy%@9Ybd^+9V&rBx;080=2a(-FVoFZg6TY&2P8j9Z%?SnhHq@b3h5X=#3b;g(|i z1ku!Nb0QMUt(NAst{!*#@l@tO*_#qhoeA7Barb1}Cy4$J6f_F+UqoJ$9#5;TJWeS$ zlO%6Lpf<=qTFg&u>v1ZDfFU@EuS_w)cS@8=x{=^Jgqm@LQ!dnb?JT>K`?9f5q-x@}-HnZ=w^*cYWI>va7i^eRCviwA5T#|Acj$fI;I!B!gD zjnsfX1%(W2Z*htSEuEEL%1awfiLWKO9EvAGjs%GRVULT*9_%Q z+ps)GU9p|hy~`F7rQJdl6*he}34mE2va^dL>I`;)))w5LEN0tqXo*tvc5|41` znxvfnoeNY$TZ`^jmeYjGQ(_LR5K>*t+)rtG(gAQ!HF%OV zTdGq4w#8lvXNu1AnR1q0(db-{x-ulj^fvqg?|6(+kJ~$@%QBm2Xz*y?P|Q*0b;^N*vC*Rg zY^wH?l13OD9NVb_V~%&{-d&R zo&6{393+dN>`|Pl{3_UEuUCN#eeL6wQt{flpw|%!f-+a7RDthKp|3!DR2}I^Q&sFU z?Ap82ZbJn(Tt-$QLlB>13Bp+ZyqWCi0qfV%)pn*Ft-zQv;HXejR(&>ZN-bp%Ro^_y zut-K3@Pmu}94H(z{et5j>FS`10CqPoBHmAnc@P)jUHT&+=$748VGHpYuSe&k0UK=7 zJ?nwnUqZ08+&dE)gn81N2^{#nL&IHuJiJs}s@=;iD!3oe5n2tfVO>a3!5z8ZtjoSv zwD4XB87VCkDBO9{T=%MMVbNQT^S?7Ja&gz+Yz;?Ez_ax~Y%h2+-j$WT+i~{5j^zD2 z!D`c%_S=>rd@yENAvj_5n0JJY#@~`odMocv$Yx-;;eNV7p9JzymYf=@l;AqBMmlN* z6kJ6>H^JJDC|7u7T^5_prjPXL<^V{dJbUbw z6{?eOj|wY@i0LO?yiHaNcW6EtozgaFi1r=U0e>y01joMp;xEU)=Mxt&q-c&BcS^%= zwMAA62|yQ$Q}%BFvYkyYCg6*XTCm&zpHDkQXME-pPNcK`8O^_^8KgPH4r#+*+HZkC z3LKO&2cec&m^rBq7xv&kUT@V(P&WU{XwX-UmKuue+F-(GT}}KKWaEv_JhrdMWj>&mO=0D!pO1v$Wta}yZwg}V$Dsf>D-4XA%+ zgbMSeU06NG$%IUoVJ_kp8Lu_%1D1<}C+<#8}vlnUur?&Y+8F#haYw?CQv^aN~#~#Ns5iV6b%&fl58ob31Yh z+GnaA{4q1eubw>K1JbRxM?hY^L&(;6WrFU>Z#59;XtSYTPNe(&9=NUV;k~Ril%X!R zvK@TP?DN?XI`H~2QjvldSvUjvxavNOC->;GrqS=(0I=wiNKVfcgK$0)Z=@p##S@+G zFx(`3LzqT6-FIvUhmun$`C`EOqAH}hJ^~@X{;veB3aOv79zA z{KR+lAP<4OrK+PHn!xK-2aQYOu=~1c4bS*6lwso*Glste^xsZlm+20q1QCdA@R7`T zY1I_tbZRS}0}3t#S2;qxW+CHn5P5C6Kl-KY14|%VDT|7UvbvFs+Wh=#xi+)&CiCn# z5OSQ|M}sUnq=&LDw(dnZh;&}msF2E_Nw;Aoy@E;}n0-D>iFUR7bPwq^lcojv882Nj z- z$Bta;RG=p-6~Gh%99-a+R;IqkSLd{7Kdl%8`$N8b?hGW28`S5?i_T6oHESOgv4Q9UHa(J{cd_R6r;eMJe`E0S@ znpGN-m)hInD5vugvWI+<4n<|dPsebo=}RJ@ZwnU-NjK{SEHU}=kY0DOw9GQ$;|BMk zWmq5EuD^PCKLrAV_bE`!Iif>J_VV5#Ew(|{hlt--cr`SqBiR~@P-$w zgh3+9ND<%StTcz&2Hj+ZAI#$to=gIq^Y--5me?Wn)RdiINcid z>W}TqU}%z*dZCot#&MB`U?N_1k2Trp9@O=&apYwQ^HFkZA6xc(+rcr!rfgB;koHs& zfr`9y?JwAUcBn;kqC$kN{lKoNAvc+T<^)#t*?b#Iitg*b=-og6h@#kJej2ejn`7i^ zfP}!XM$W*ypoeBq0Kw4PEKP-1;6f|gC-@*LFA!&(({NnRLz+1Sas|A)^T$>bI68tb zpA{+i)=T7yvJC_!Dd#-=7HB4!N^Ky)D}4d~1T?&pZyp{4lTL+qBiy?rD070b)GQ!A z{VfdDjryGPA4D=vK+e97UKEiXcBkXX>PhHK1shq0%WU+r`wq6`jY{K(096VZHy@Fq zytX9j1Y7f~NaOo+=OE_A@{ELZOf*EV9Jy)5k*#Il@o|7&&`_5evt~FiS61+>DbP|J z*o}PgG9)pe!p_m448!jwIivWC>;*1;*;km=)C36}xWn%Ujxj=_oK*U^m@4=ZoC14^ z9&vLs2tLgaWE*E2LetgU{@a_%vUN`>WK>0EoiZg8pUpfc)rY}x=liK~3b=xdEjmgl ztRs+Cs01`BLQyXEL=lak44cj+^+*y=!!2Dy);zA&M&TE7FA5Hv?`KJ6G z?pw6Bj3Z!LqfmoH;g}mu;z zilUlfX=jlRpGDCRKwAZ82JsH~sLLk+bfk^9j}PbJlWA(|fJi2Imt#xSSNyH9^oy~y z-A?o7f}v`moR|PtV8lOR{DS?O9^Mhg5sqXI6lfFy!4V)1|3nWBFU=ORfU$K)jR1dJ zXHkdF*H}jb9Zqj4HGKB>uBdAw+zCPiI;l8UWR3zljdtm}#@I@UgSGaLVI#>y2(6bh zzlq1{$y$qSv5z{L;ueKD<=h1(uXeUeEir)gC6^36qlpZ&K*_ilw$iKqb4dyZJ)iY; zRF$$1(8Dn|2}c`u@p2z7*SS{w(6v7YRuI03h88q9UBlc#KS8%g87{iru7$rrZl*`6 zqov5%{`cp_%U^qyVK@&XL1u8dBcO=BZR=+rNl(-aa1F81Pqr_y{bcHzDAcH{%R2Y} z5GXYHUnmF!4j5Ts<-YO=P)}|nO4dWlCd}{F!pT4pa!Pap0NwTF4Vn|KpjeECiDD<2 zUb&7ZX4WZ^X>0;ldX5ki+8YSfd4*WwKW9yv)|_=Gycf!3Pg=F>71IzaVPV~`nzr_?*JHsA+|}Z4%|P2^lV4Oq%rvAw*4y)7UH8TB)Y=t ze4WbDw`&m=;dWO2a!=HGzw!oU^5rp<5!#zr?=GZqz^InoW=GSGjF?tf z)chV!VTh``OqlT~Gp{nqmKtf`!f5_L9(EUh|GX@eG3ha&-IC>7~@JGjK9U>T*teR~rWlbh@7yZy@xeatJslR~FMu zS39yb(WsG)6>*e)h<>`bHN9Lk(eWBaF>hCNUtC&-&nC6CA5q&(v~1@Q}zwXw=-+eSP%i@w}k+lHZI>?uQmbfiiW~!rTji>m`$I&WPr2H z+BeSQ)#pUwb&6&vrk;_C5sf+yH4#=W=Pv%pqEEBIcdiwWZ<_qE>iq;t!PENNq>%<# zxtfzDgRX(d9U42R5kKdH*HJ6i+o){lpq(W=bwfWfI?G>@W7M6$`)b>(D_+SLm2|aC zqz&DoS*M}5lN4}cz^;$c% zdw4Xwef6-AYSzXQEW!9w1;FaYI0C%wPwH0lNuJ;E8saLScDJm`zme4UBcpBFD|Tdn z17dmxN#oTWR`{suG_;OtC*QWL`Cr(S@`b#J8o2v*G9M{R6Umeh9Zm2cA;=_lYyM)^ zNDKmT>JP;|bJi#EJ<)FZHQaLl3yR(#3Mk-y0oqJ5B&kCP0aypHf;0R&krxO?p=TDR zk@=DAeW_-|?XTx~WZtjwD28fdqUCM2Tj5((GU+~zN^Ih&)ib0x+34FuvtgONv%Y)k z%=N$`>CgQC0xr)w6_L}+`N~6-EHk_vdHLb_I%uXfR2_YtFQ;TG0YXf|2dK3BjlWZ$ zZ%y`!W1 z%|I;){?5TLg@4SlHR?0-;mN;YbV1{#wKbferUK!M&!nzi8SZek)j7WIm%KpJM?X4W z^8ep&nNaDkn>Ye0Ra^;{?kG{5miqb%;glcso3_2R0&xlYa~iTBoGy3T%`e<2#ftU`QLLX^oOI>6-gT0se>WJUn8#k&3m% z6JpM&6nWh}yX`%z7v| zDvS8SkTBbQ&}$qe-6@i(R(U~L)aKz-`@pXE%25eX-=&L6dY*K?4>N;vI~G+*;y&ZA zj>gIhR6WpK9ADenCMuG{&={BJ80Y6#Re3TjF2F9SuRAHajpxAMU_wmh1b70o99{0S zDS5JG0$H&x<0^VnMQ-`(~jx2_al6g-x}8#bEfrSfovL zz1hQElULNx{C>Mbp*Oy(l4j8YyYE)Ryy~$+G`QqZI`7*V7-Uv|Nlnq@vo%M#FP{;K z8NhDzknxM_tA1Z7XX-tg9iS_ZFTD>qbcH${eXB#(U2$cK%1b0%`FwP)lpQr$;!6iz#iV5cl0dG{m zOU}C8z!d6bClgGo+W=Mr8(M7UeYNxJNHwIz*o7*oJIap5ksW#hNa@H;iQ=#PcOFYE zdJ6{xrh%VYCT0#z|AKKYRj9wA1DLi@{;Q#!{MMwQ_;}8j*AXpbWa2c3OMe%m6pdvJ zXFUEfAlL=Q1UFsci8OZC8*XiZsq-;&Gktmq#AJ7BE8wtm5fvfsopu6=i@@=K zkft^tjj&|CnQ=-!m2a~u`vLnr&K5#eL3j@av5}V6*tS8cP2+|E19Fb8!%nNkwT2Jz zQOJEOSXm2$wmPBun9;khMS6rR%4p~T>8^g%SdNmKXs;&w-XvWAVv?z2Bn?&j*X2r> z4^PXTVlZ%`SllaVDj!Qw(w>%I$vM*{<6}xOa=|imt4E$@GBDR+o|ezkc)zERHfisxO5b`cNmXu3Y>5r+$(2rdBNXa#_VHI7Nn> zT1TSd*!4DOz5e8HD(kvYI5B>Nm-)H4AEz3lti#~WB{XL>2QJ4Uwq~=DYRZN(FURx` zFFs|}ADdT4dz@>H^2x0@a%T?i?X+0BuuuA|fxo%#vk`iMftj%3KGswet0LN(vx{6J zLo$X#@_Ej({-mwy^e^?zCP=C`Z6JQN1Qfj zqpMOiE_HY-ZZ{b{<(#p$iW)tyD(_Kysmfa}t(n{Yd(+}y1FDm#qQ?1j!WK2}j@iwF z@2Qy zTtzPfAkB=j> zZ?1tfy}5RDf}BMelqPP?({n8JQ4O+^7;>`z{l|Z|;ftRUak$8JmYgR1k!nl}0n0#6 z5J_oCr8Uz$uGZ$c74x=i;I6fj|!nb5C9gNJ)?Ugj8*B)&`7Ov zF8z&$iiM_980W2|X-I0@&RXFB@L)ORYkyFF533hC3L4P$Yy|-{w@js*@lzYkJkAJ` z7V`|!!W!uUZ{l2rRV3k3Z6YvC35BCypOU#UPI77-He zLPHuG?o02ohKNf=TOO$BKc<&GZ6-sEG>cxwbEE!Uf%2(gg1Pa>Zk7}IXQ(R$mk3(f zUy`2oeWGjS+TtWy$IDzJRULiJt0}N;&2dy}^z60L!r;FXNLo^g_avf%{}6k23D^5~ z6o0dTo&EtXnoA@wc5V_cmq6%}A-W%69*CsZQMA^9(8sO3*81{~3Q}x>9K_SbHS)EZ zAvNEJ?T^563m5()3BwBwWdDQ1iwY2{1kn>uzL_*q;%HDlq1@adb~dVVht>+Xz9?<; z5*WW@SL94(i24q8?cHMEo4hw>Ab1&s&ngniX`6XvMpXBXofxX7{!kC3?1bo! zD~b;u4}?bgs6nM(^N(hNXp`dxx4yq2^ahOT`d}Tsl757Y8EL1E!Jx3c!GUR)!pW#m z7L?W4Ou^#0kTFNkZeLg9R76-{lj`H#GVm;A*Xa|(s7(2iG4+fgwAlY$?|i;YHl^R| znJcoC6n*SIwd#5tuMJ+aKUoBGYO9UfH=2?svo$oA#@7{G0|w)PW16VusetLVw1GE1 zaxr|Y6fy_MXyTeosOY_QHKc#4nmKUo=@5qm$=AWFJC7Enp<@~KZW%z6r>*x)NW#UO zksYruOVR}b0Qju3m)Y3^jvybnl`v?G$AX`?Q^!`LJlFp3Y-j(@) z4QE*RAv@b5DNiQoiS}hK%__+69BC6U1s7sLteM^?CDjV}mT_KD?`_WgHN;J1byRwJ zXUUAAAit!W3yhGVO)tly8JAs*{_Il&QK2=eYx(3*BDcEcnhD&{O zVQ)yv>-KT)q7HN(e6SN&L~)-1GLBe^3rqb=ZknDCe5p#Yt-(gfVV37cHpB{o9%-e+1wdl1V?8eaL?=SZCI;jn?W|B#pYwmBb7H^`Evv1Wi;TzLe#pU5 zI7-gvP21Q$SZ=@lnzaabQYL` zN+W72$Q4V^SCRSzAqj1%XnDnynT2PccFaj4q`NY;HwC!g0uHeJfcm7EW`5=Q3)W6f zfqldRwJG-(^5~K&1t`(XwnQb)jUpeJQrti;{A6h{F87Dx(?8c0&$@$a)_xea!e`F$ zuoaoqsHFQfN4pOOJZv#wLdx*y@rOK_6*4iF%5!>RFktqmw<2wq-0A{vzs>NHeGZ~3 zwUsg*h8Ea=;Ke_h*cJ1XcmofGyL78Z@Ksw5`@3v`;d92Tbbm79?wh zDZ$OepusNqaD>AJ-#l$ETeWw9b09oXDy^>lQ9mvI;EY7vP&Y7^N`k$z26!Fi1C`gh zDb2-#RKHe{ZXUSJCLW%B5qbz4nWhE%3P+|)lMAfFH80$hL<1Y3 z&WPQ!P$)mMX>@3>|G(BsssTvobec}a71zhe)p=WD(WgjJULmJ$vukwyyon2hPl+dJ z!B4;Fxk#FcN*T7jT|#idxmHK0Q;&;OC2D1bQc)BOJ=Hh{ujOC~Tu&^KX0U{_(`gUH z+<&VlAfTL>qczh!qCtz?2J7dz2Ykc|inK6oN;`@<<+ziZ$Ye}95%?JclxCGVI(#wp zF5i!6W}&!ibHV4ubQTDUtvzX6Ik0n^pNXVKF>`p(M^Vn$lD$;*AbgJG$|(Tg>vo_Q2Ubd_d|((% zKcJ-{4UP0SghF*)HjM7PNBu^yB9sm*{{*cG?z14~a<`fpY1%o^~yZxBrm$0*VJrtYg zI?(w$-PjA@n;u*M^l&-Gl#8-(=r-@^i}|wMtpP|<{v?^-W5Be~q!&Ar&`75c=j)W@ z+MRS+xmzf)%8enU{Npjpk<0^E`i5h+^(Jv6^v&GmD!*2~t@}q((b-Ltj`980Ul>Wg zSS?Ai#>hX;94yn{RYd*!N*LHiAb?5sdoo@@_YAm^AH3nG2^$JmoDaA6O@l-tjvd5o z0>k4-TxW==YS9Ek*lTrzeq+0P108jYe%yfzBmmGRO=2G&9SsvQRlsEfhIBR+gII?} zKIBr|7wuxz${^q{mBV(8M%pr(zy{NQBt+1fA1Pg1WR-Yb;QvT%`lsnmT1r|`XQ%rZ zp2JGf6Uf37lw--B_n&ObvVN^2+^BeYM*6zP7yWQymvE=ixP&1!M_snDBy1^nnr@AH zm&4xP$T~HVN)`=Lo{0?Up(oognaurJz;ef{m~pcN-MYe+(>~-UJkwj+td+%7GAqy3 z(%H#pFO&`#KEOOZZKQwJG2wp4&uk$Ot99%?y)UA2Pj#74R*1PUUbA7KfmBaoHV!O( z8Nzj!`eVPH&b}x)-16D`_>5JhV7=rXic~idIl_9QeJ~u9(J5+nk-f`0K*6%PY^1zy zjVUq_!4QZ!34;%6zGz;*mt9{QIDRvZ1LN;?bM0I28E+$Qc!bFTd{ym|8ODHB)Hl3p z)T8`ApuQo^{SE~<+!>d`b^u&|$bqKggGO2r`xvz*ko8*Zgtn2&1#Pscv18v3pt{$pQa6LWL zsC(Br0L9vGh=X0X0X~Q^%o`|*u>q(OOX;@4%!K<{sL9z8V*)CXX#rU-!2Fd75FJ`H zf-r-KmI>8!#QP|}F}i{wmi(n#4J=^N6@S9J*c{^a@k?Xd5mS6Gci*^-iyhQ3%AAPSNH)tz{FqbQB znHDcrcBeI$fQX&|ZWNTc!7L1hfUzdf@t>F{fR_Ti^!V!`4I6@7ldiiWH?~F}sm%#L z4}qrzq&;n+2;Y)|BeaAR0P#~O_Lp@G5xLbUg za-zrrKvRpB)ZT6D5cW|V#QF8c4?T+GhG%BSR&VCSEiu{a;}q|R>a*d@)QgPiRLn}h z&ph(Q)gQb8Qv3x@TScn;S7 zh4)q5Ot7p3&BV<#pf%-got}BzN222LyNG3;2reks_{_s3IoyHU6d>D|>k?_K9ws<# znpX7%IZpgH-y0EtUwB4X+ z;!MlVq~WPZYAi)7P`1;(v;?z)MA;^x7|Y;@GSU3?%)!|*E>;XLz*tC@Wx9I1;-(*i z+Q|aG8TocloA?{azkq(c=xNJ}y;P`cmxOh&m8@iLQU!4N{rnN zjT4L_VFYN17&13Y=a`NJKGA`VdbviIj-1DiNGvmVw=7OxxKjI{(XiZH1Y>`8m~9a= zk@#IaVt%b0ZRwX5@ob<6eU+AC&}lT{Mm#aQCx5)Vx1-4Fjm52KxR0)$<1S_>@?-Eb zz!K1}jHk_ad0W7lVjTAFo!2=&Qf&rRO+O7k`xG(vCX{50`e2!4uQ5&}Ba=fM{P7q> zL=6;$!??cK*N(k61x0w*VzJ!)iXYDM6#&Q!&uSAjFxvwO>;t_+&^!RyfCTn+Rv|*W z!il?{Xiwt?l!EqzMy``9Om{F|dMeZI9Whgyq!t%!v2M;#r`Av~ErscSZIpP{^>^E! z_j?Bu$0Xh?rzNwh)_=FqQ4F&O=w`Htl_ z8I;17x77-NhLc8QNUS1ugzVI!Xh*#&X#sW6-wjlpixu9~6jMx9lKUN=+BG{MjO?nYZCe zU;QZ=8wK-TAB{gQI-vH@ZfW)zp&hS~I}exo#$!g_0fMtH0I_VAl+l9KZGjJj1lg?G z9}N#&1|a0FoWNLZoIASLCvN0|*~%HD(#^4{O#TwXF2` zd6GC`f?d2jDhJy@`MX$O+^kSXxJ0CxXzgH85A__&PJBv>qunfMN#~NoB{QxX*ccGv z4&xWU%{F#TKTcMTaw(uV%967GxG0r(qDD}lPihDIS0cXfY>WXRd1dj=&FQLas1Tal zOudg!X@>KHJnNm6F|c{VLwYguyNZY}r$V14<( zYA(6*CM2w_h(uouh9VDOA~{SEO|N@pZ(uIAO-XI@5A>8eN!X>F|D@yN@s7Fn?e(vq zH0Q=0gVzT=7}H;bdh32hS=5@ z_Dx*{R|SvyO3=QG2N_AgszbWLSyMp}RP_xWhxvkRSZ z>7nL|_4{wI7VKp+)}YCi^59mk;LiPf0A7S3ww!awcJ9Vp+E?bTtZMm>@8i@<0*4!q z9y|Y&{IZoolaAd34QD_Vd+n%iqx0%zk*Jik0XY`blMGL*a0G4vr6@m{Hv<1)Em*5H zhXA&>ZUmQ0bq(OK=123wHGY-83C#X*N^1siCum?adsxUBOvdoa#OeLz0#XXC)ja``euuOuwL21rKuVsxpCbgge8OY~dRpvzxe?uG=9n&|1 zxD$_TU5|)6+=uvSns8l*a%pg9!WOZtu!WZj|66+J<)2rtWz6&=%&vTLdT4Zu8W5m15#!^?Mur`RqPt zr^Y^I4_oHHN1$myszb+2f8}E3Rv=*#gB_7?Ytqd{YOMD^RN66CsVXwjeazZ^|MeVi ztXII4gGo_qZQ@b8T?7l-dQGt*G|P#NAdqmIick8oru+^iI2e#}jV!a%5 z5%yOGAqc;8U;M|0RMP=dEJa)ky>2+K1c_Ob0x6)hlc|hLkC9lOZ1G)9lq0=y)(hX; zPkVTpTOIV3e$8t)vkj?Cj8P0vF@w)5PA_uXRoNm=1H=*Nv1g7Q0@|XlOj2)|Kkv7{ zb}q(=-~z5!v1ici8YacNhCKkOp(%M3q)~8HA+x27cNA`(^0(kr{xz=8#bSIseQp2L zIU{|l@nKJ&sb=MAGe~tf^g~If&J~3BDuys!Z?oO?E8=?{CtDP5r@shp7uibmLxf9F zM*f@!@Jz$644H*80R=pfgwRf3K6)T~P+5VLRTzNJ*Ga3^1#|r8iAg3tP9wwKtD*_Jp&MiQs{A zgSX>f1H>d@+rt@gniX%_;DvV}jHNQ3%4Vg=AFdo8?(*5xy3n>rEZN8^3&dCA!5ygK z>g$%DU=tmznTD<3>EfhNI3P4)l8Sp_aTB4$r`7fDZ0mh3A1NjAV9OnFBkM+*?v%2x1BmelzHH&->?K-sa zz=nkD8%i;n#tZuGzqdTWR&z%C4bH8qWZEvEG2CLHtlsVks4f##-_E8Kl{2eoldPz3 zOyZqcOGShg4l6Hz5`U`CjLoelo)!iM<(dZrt%MeMR$7X#hXm>qVlXWOZBp2$Wh;jf zmjvKp9S0DcZH2RRB1!5xSOv({-*kl*XpYG)t;LDy@)_Kp#Zx-=Ld4pY4&WGZ6o<-A zq-xx87yzH+cDsLZFlT%Yh8gyCss{Kbr`pn+k&hE0x62Uv7M<9FkfZ5;5y@W+v;0>F z3--WY#0X_M@Jv3M0{1O)?;#;N@s+aFG;3d zM=-bWUobqry$-$W#(er)vZ2ti8FYS9$j*8z1$MPhyVu&JaM%rAVp1>6i6<4(laQib z7FEJZ**Ueyjc@cZ+hPrh%f5a?nLp^SFGlO=u^ry<1$)oal?S@!a>AwQIL=ccb|f(c z&q<0ZA}LwIO`KslvsM5CIWY+?i@myxxKuL=O^&P(!Fvm}RELi=>e z{t=CG`gOgUiV(ocW^Yx{+_GB)Nb2Tp#TkkL+wH#1`|BZ0#8tl-h{|H=SdTHsf5)X9 zk{_f`jk53+QS#<(4B%|VG3lDXTa2M}xfQhZym_oqh%kGO@juaCu1vi% zyp0Dqxp`K9lK7J^{2*?)sFwT69Sog?BizSMqJTnUoj zbE_L&!40oK<+&*ii8Cct1Ow|WxpKQ;Ii$H{12)Fu}j z!7nk>T$f|kkU)0t#QYla20Zrt?F&gLdI`xn=vYGARM}?V*;<9;563GoPx~0j69GF1 z3UeQjazqAKbd%3j>VWlN$&P_hM7M}y6JDKv;OlMw(vK)}EF#qT#o{VgWE zz(7aRb;Vy>{(HU~PkbHUK8%f{qBot73ZECZxm9_iApp1YJRdvbS{OS@n$nFT<ppyh(dY?-N)a zg^kk$Sdlza-?q-K3oE7j%CRnH>W9O5TufIg==l|tqqgJr?`oEPP)Zst(~}*sN5HOJ zNEu1CF-SxM9Q|gTgI*O9ZT~)C$ML78TCs&5C}OhE?!?>!5-Q?Ay2nfiCgN*CMvtR@ zP;}PVAjy;>gG(##25FN?df10 zIQ*II=#rr*bkv*0rByFkuzT#*$haX->&C;|bBsA^ijSK%pX9>#IinKyjo`hONE(tt zo^~x%J7EHC=8!ocAeT~ItHTdRPqM;REDPvayjFXg_3orFuWzrFELzGp66ezRlUyIfmf@I4Y*XQ#a zmy1ZT2BZV`5@8(S0Abs39VwdeIIR_mkQPK4lNQFlce&6Vx*75(WkH=IDGbZ%O(o{k zB{#X!*Z8gQnBK?rK&~H`Z7QPdB^qd1)rHUrZ10aDPaP=c9hF<}sGkn5INOl5#Gm&MKfOXt8`Uqn2iH6AKw}mYkpa}F> zOlj5hsh&pY)R`lO1mR4|J2Re=9NlON$=DG&CF)^XOpItEYq)#(OY6N-eNCu-`&j&= z%-~u8tE_6cgao*eOP8c4#s$f45~mP*Wd_7vnZzUE5yAf`+~L0G3o>;Egme`vm}eap ztell4I-8D`T<+CCTfQre_v*J>>VN29<(e^K>{^JH$r)gvx8x_iL^0W90i%e)dx>vv z4vS3yK`VeNdOJkg4o`Px3*Og$MUAGZZUhe?s@`^OP*%-lMRad#egGntMA?ls;|I6etu9J;|@71S~qMd$xXz?;r95AG?e3mEm1 z1+}S0>o?kmb%(4Ga38CuTgpqq6XO^D5+2s?A*t8Y+kJzM9j! zy{{f;q@F~^XF^8LFqC8*2o>{GnnZu}7icMIj)Vwocq4z2=QYp4PW*oJa0o!_iULl| zB%Q`ecv@0gJ2SbrLj@o!ROWWbzvsqDvyVb;~9zd}!ko(&`p>peN;f5Cf^ z0IEl=Ir@;g)zUz}z$%e-lhXjio0zzQ#Z|31^{5#9U>Yx^=68$%b*w0#ITOd(3KEu? z#b)U|k6i+Z0tk}Z%JNGj-q>}8XU8U2Xqyp&=Ro1Pyd0N64oNBE+DOALxb9NzMnl=E z=z(#bm8N@dg9_&SU^)9_CloVh&T)|?70tcEdim5JC7uVT-dO%R5dGLGMJ(Fl$Pz*^ zc=P+Vjx3q_6*P0%XruUq_|fUcR8t!Xoth+#A zW*jdhv-H}SSDP;MG`%>Qf6&{vXOA1^jJag#R>-BU)kI_fI02Im@n_Ru6*O!&%0 z_>POBYgfN-)7UAmaS0vkwM-ChMP|CI_GN?0>!lyU6rIqJdU{@KS6 zyrDrgUp2X1noh_TkJ}NFd|C;K#seXprTQa+_6*AasdZp!R}DQ1 z9L&%Sinzzm)Y{sc(gV#9sRWKDH7;XaH~Arz!Q!^n93;B80i^nfEr(Az+H*Lg+;<~3 z;F|WlS*~R|0OP+V*~MUUp3)3y`68R*qL?W zC6b`JvY+qF3&_gu=4*-LSidGO;8ldaJHkJSz)P-3qgeMrWn=-KL7Z_xUJGT4Szl`p zW>w%%;`zbgrb9U_pldzsTAQL>eODHPM!i|f<6*rTC}EXd++CFYjjt`g)*RhGL!5HmcIh4ZlHcGRwiVZT=PiYQ+hX1_8J z#fT$p-CD-5wvUT^r1&2R+ru;{EAF>>ycFFNV22;;@ZDj|pd{(y_=P-eey#L(d~A#+ zW&2JM^AnjxKw4O+kO0y{6vZn7s4&s+wq&T5*O5i*Sy#8XE(S$^^cGiDhC<3{(3ljH z;k^R~C9>7vFt2{L?y+$6k(PWPYy5xMnvT$1jt_b`Si-9m^0gq|bUob8ivzQEIBx6m ziv;H=E)(ASH9M!x=bjZn@Wfy3_POS2ocE#s`8W;Rkve*v6Msvml=^jxDb6w^x^5Yd zC3I!=VBErq8H}m9;L-lWs(s^~6x6O!Qa8RK0^zvnfJ|C)JhqH0aW>-^ZytGd(85c& z47?_9rM{pbJNk)|FBS3H-lyhIKV=DSW5fB~uY$#jTD4sEZE?R$F)a(rmJnT+OgDQy zQy<@%2AQ|yM-|%~;}U*~CAxZWYUy(1BVe~xet*Y)Qq*0tR{{XKV=0ALRgsg_Kbl~o z!qk(T_-fV;W&4|yEwa`b6M8wOQd!QYULx+;o=o*grcp$(et3BJ92b33Q3WZSmTG+H z4318G@s?+t2-!jaBKD`WfM`bgx)zVQCqpYN%Keda7mX2!rk9@q zJ1Wi5*Edq+E$IoA<$3BuLZzDE4!A{6heFCCYXV`@bMcMi<(QIh;!Mg*dxtTPSSN~s z)LQ3fjJml#|1Pcgg%TIcXC`sKmZaOUz~xHGI@mpN^soXy{<@Ft(6b3=qr2!rrC#O* zvsi8f*EcXCJk;cjCrROqP=8YQSZA{SK8&B??ya#!Gf)1whMi3VQZEc0Iw#OCF9Ym5 zT(cVItr{q)X?=iubEV<`wpmQ_a~3gCJOgPPqR!M*3d)^HhcP>R6}+i5e}05tleA!K z1p@F{jSq>i9@XRvspbQjQOxfxmcme?@C#NxNtFeRDt2bsvzjj zi;a>NgH(fq$pFp;ekfp4aPG$cj*fT686>H~RUiUl-n6}j7wW3snXluM!!6H)Waz~ZJeW$2%O`JDHrI94=&c=@uyN4!wp~}iXM~S2l)^RXv$ovcs zwXqctPlIqOutWBpN|uOk&ek_|>Z!9&P#SJSht078G~J21%D!eVGbyf};Xy~I90*>b zNw;LQD%=YRzd6JKb4R(Jnv;gq$*MRu4QD&}%v zi(XAJQ5+WT{i{1ZCtM1adzRwYxz0ClYy_*M*&J7WzVJM?TMQa&Ue zt}4flLSylslArpcONVp7u^OzoTU0w_D0?NHVR53N2XEF&WZ`v?LPZD>X2*Y#Y~HrZ zCrYT^bz7O)wSgwdVC>5)#wM7~5h1|O#DsLRnHQ)eU>mb+N1{>PV0x!!nWeFxsRu7P zK0bV+scq302nURBN9u?G5Xj8>ObxTWA;#U8lOTL3DNbHdHIIyOnLq28R^{M?3$2vIkY^5dA9qJ^?pQo;56|h_*b?9Kkx^! znM%(bVDMU5KhP*ORYAc8FYvHyE(e(2=S0PxChhloSg(4zT`J0*LjpCxSMvT&MBzJV z%wn@y+{UJZ+cAJ>{q;9Y6B^DKE3s_?4_lUNS>cxP9g%{SwS76xE9iz1luhR=kndbf zH`v{pF}{sO;DE&xMD?+Uo2`R1kJx6)4)M_ljl>&$xj9rot%4FoZf_tYn&7KViMkVN z50VEw#a@8tq7D+p+t5p`Z!H>xDVI}5j7`LZOCUI=5Os?8IOMOZB*o)6W5zNZWCNWY zf^TPEGoAe4cVDp33_U2QC>GhQs)7qy} z64>&HE;jVVXhYM@w2#fn=EZf?z{RTV%F-2u(Q|Szr_suvu%bweiLCumzrtvhSC&3P zuNkP(2d9V7dzROSPxeP&urpHmZe24rzf)f%uIyaoWNir9BUIUBJ0kFr&y)US+|JX7 z>j+*RLdYuayD5nDpRF3y%*3BF68y`ary8aJnSs!1Y%2E^-nSS0DZt=-2QLLmP%EEW z8aIa!9vPxR1qEL28J^-WgvVM^m)m3AiY29d1hS@Dy$Iie|iUcYuMZh%0FI?DL?5M_+8Nywyl|jCknkzcD2R#F>?VRk~$_HyVb=PD> zs6@rwtW?K-=f6MIE+SmkjM`A*u|{z8Cf8oSzW_-E{>VttZ+xoZ&i55VxSOB^=ue$* zFip9oxkkF(Vws<3=GxBqjRT zk1)*dwSS1-I^)Z|@WV3Tnv9k|yaJ7cS-(9@YIBYHA!?_`fYy<@A6Dny+`NBSKsWqK zC<3aC{B=elW`%h>mQdb|1um&ES5#x{fJ$8)-2P_?TK-_e@liuqKgUGcm^~*%1-a9+ z=<_6a0>hLT$6j}SQc*h@CW;`+$PEvK2Dn}@;S^_hW4aN;$DH<&fUEK}5Xf&sT_RwW zE4DDVJBx+tK&N^RG%;J{522UJsX;Mh?rz}|Oq?-QQ};I3FXM8drd^5I`3_cF{Nttq zu3W)bXU-2EDz<(tJbx!8e6j!-DASWLCsw!aSV=G0TW$7FET&wBlsl3M_}}D8RMwE+ zV4!8TfMdu>tv|0Z5>OUo7e}I7uvN##SD(dxFXz{`0vtmQgyV%Kv)oQ3stY&0_rSPD z;YVODsH4&F;XQrgl!T+Y-eoYezQ2UIx%*-e7AI`kgT2lM7vBq6Zw^%dHh8G*iq|&t zm24D2>kmDh0IG37|T&?gL&N9ODOU(ew{+7pk(VZeaK= zXbu=en0IoPA0e319`pbtTPU>|0Gg>8Z!tpzJMEg^Pk|aPi$kxtyfH0OrTUw4kEvQc zaU_p4y0{uWu$R?cCpp<Ixgqa_Iw#gwUDnVmta_Q2q-Zu?nkpO_q)y13wzme@ugkSvZdTiow;M0Tiu&r;kJuT zX&(G7>qvK~oHl|G3^~APKj9i!pP|XHiRWEqGUc_KRlvf1ZYPY#dh=pTRvnejtauD;KNfJA?)WVZtzqd zWg7RD5|JQ-!+2BRk--j2J(CqC z3)WykGKGji%u$KL7k+!LJSZ;dt>pCsDJR|;lin^dDjNN~0eFokfttkCet!tG%0|-s z)m^Q@{(an4VOE_|brUByj!7$v+VSS`f_jNZCKdV;Sx{<5*v3!qg?7r0Z|eYDVq(Qbdv_SI~w-j=z^%4fj4 z=f&uKz;vha30TY7=Len&PmN3N|4!@N2NBfZHVhv4@_1O(DPfkTRJQLMAS7LOOGDJ|{SdBNc-eYKgM>J{8!Y-5-S-5h7le#&p5mHrWN$NTO(HX9*eMC1`QLnR=eqlg43rk zAKeJ7Y~r}hE}q$8k&nrHg*jI3&%H2B*(`~Ah>Ru~hf6^W`hqGYDwUqb!L4vj;#>b! zWBQEcOdnr)EJdR~)Z*rY9EC3JC{n;VelkWe%;2Gt)2z_V7ob z|L+8JRajlN+}Z6DeEu!9;pdp`CJ^(fVj*l82E?AE47~8`Ac0VooU)PTv2p|;HKbF1 z_QHTk4((_RSKrDS)zl1a`K^A@itazuE)?(Cm5)v!`UQIXUvnJKs||$IyHb?PZ_pBI z8LrUzeRIj1tfb{^!Jx7F1Jo0v@~Q8p>Qi~=k|~dfsng7ey>pN#c<^^yf1=z)$rt3wk?*3XzH=wKCvXma>CBN0|tBC92rW2C`25kJ=4{}_K}6; zWF$Q4;6?g%D2^0pfnQfj@k~I>e_zRTzm{3-HKdj%axM%dv1I#%`|kBbq8I0(f^u5?_}{QW3^asG2Y zG;q_8(F#g+MxT^kWj~!H`AUo8B1qJj@aLsL-3q?`85&y{#C5#>6C=8T&s^}R$sQ7WT! zZM8?Yi>Oq|e77`o8cGz?79hX$Ay&+F65?i_jo`Hq^xGRXFAN!zIbwGy?bk^QO!cl$`+8pg}qdKUJBwWMbBm$V8bkH2&w*!wA8+d1U!K0Cm_ zQoEXSnIZF!M#hi3!$13n@%RPy{PPv#Q9r8+hS|u7_QQDbfyhjtGI!& zyxH8W9{kyd0{NzpfT&pAHOPkyj17t7ulp5hwMGPIbdwvnh?Vp~YFcb<2z|!zu)YcOsc8inecIWNeRv2fsuBUx~s;F;dd0C5RiS90zGz^G=_RA} zs_)UyW|jvm4^}}4hX~q&T(`n3)hS~Vv@`WIpW8O>oj;mELd~3{;JWnjkL9rw6hEn+ z6G`0SWJ7c%uzL2Hh}6hU4-dnWL-Hwtrp=;(yili!Ak@`x;OwD!ArVDe4Uil;c79ke zLvgX3&|CdE$>x~}jI%r)dMce&U<$LOUu4GL&Oadx99M?%h-OJ%dPB$q{f@?ej>L*)ryUL5n0cicRq}m=rRm-1>k}yc#8#J z8i#$=s&QT2VXJG7F0BgrhOj-7W21ro@o^y}RpiB_v93T3{G9cZ|4yLipSO+T?Q_$qmf5 z-2mXCuX5)31GOKU+Q%q9_Eje!;{N4UlY)vMP5Wf_jy%uQps0am{5hvdN`z^}-^~&| zFE0HVDsan@ujTv(Bm_rUsi~8`UI&&`b~!Z8_+s%$MB6ngg2{2iBX2j7$Yp%>FH1c$72gDDXL;1aA0?> zJaF?bA*Pn!xxGQKbcX9vKqE2V7~+hGG<=95 zZKf!=WT?pe@laLKrd%^Tl4*;Uqa+;veZ<=`zwi{Ou-<)b7vz{;|bI6EdlcdQgiPxq2he>~ojYxgg>|8q|{FBnQbC8!_%xWzjp> zaq51bOrKBsM%=>|;q=^Me9w4I)tc1@T?%jMv!(2eFp*GROsq5M-Ukt1;NOM&S=h(5 ziMuPJN<_5uq2IrSA_c5#u2A7L{LSPp%!fot76=>UKxqB7XhdT@kLBU4lo;3{uV zwGS|tbc|s>^IWPYD`+qrRRrDUxxD-1p30jMGOr0jhF3>0TI#A}HLoGw&LH~#!FCaK ze=q-L^>Y&{6aoF3ur9|0bQ-BIQco#G1-+a{YT4>jJ0y8%~CA?|!?x1jEg2ZNaQ?G9`WvB1>6Axk?uK++qJ<2i7JRgy3OUg4Nvmmni4Baa8-+jZl1=( z)i<{xP)3--gx2lgm;NnJw5Zu;enl>+`$LSol$fC!#CQLjA)JW`%?ig9`2%xZ1OmAW zS*~ce%0kIM>n?kHc;QQc4_=JK|NJyW37@lry91CPxcQxP+z!@uWy)L&0nnbiYqxfE ziLw8Fk*Q-fZ@H+MIyJ5*$4)7ft^eD zFdgN@DeEe+>13J9WWuW5GIEC=j4_{I7|zB@4q6^Sv%fhZh|Fm(J0A(9SU}_R_`QHI zQbmbqR@d`6Gz4s3V1BK5i4n%ewdhOHtmbYvO|#$I#Q8;Ummn_*5DwlA=TVdM$~drK z2gZZdyTpQvm!o`MO18s1O7W0wPE&H4<|@I&e41~ShYHcC8QZ|?mN?ZDrHvsq4X%&k z1D-Q5>EyZc^*=^edn0?5xqFJAN|XJSCK|2#wP=kBYb5GKEyx2EZRH_mqJ-`>UZ50p zG*`C3(8iCWYk)J)H=SjC`JT#=A_l@ny79o&o(n|vu=m-_zTYtI^CP$}ON!E6DV7s< z=%YV|P)?N-1)USTW%$WBdB!7tJ3#euT9S2H0JXwqtXTYycBU(IepBt3Z45Lp`dEzy zB))jA0m+H?jckt_L(Dy6Jpw%xOLa@r%)nysh*skwUDj@wMr>{G+6pf2s=qqZoY&Bk zhMGymq?K5Idd4>m-sGvX(P{EMzJDO211r%7lu+DveW$_#fS$du8S12v$y%Z5zxSHi z)+)ZB&c{7&1F;gz8orCYO9jHZdZNcrvewZQOq<#8-tB!RTFX@)`>%q-U$Zkf&<0Rs z2bsV+X%hKbngxN*HfPB5{s1H9a4O#?sIPbX9!_js7!-90A98Q9va`49iR#1aZ{V)Q zMD!O1b#28poK9Qr@b(9X%o9Skfwx4AgRc6x6?9PBmrL2wRnxkaVQFhxbI3(e2cJQD5bCfS3{J+u zm!D9zYgpC7?GKG5jTm6)OZlhs&U+i8Fba!0RgRLsvLY8zD>sYGy1>=>%I_gJfus0Q1Wve#3d+{r%X`q=s_ytJT7$fs}Oi&uP{|?FC5z99DII(1t%TNJn{}g)W%IYZ?EQ}iZ#d|69=6y zGc3=^2k(GE(TK5JV3dkaJ?&S@$*q10>w;~Y7_Gz{0`+Sf>qIsSIOnI%A@1;&&L=%} zH*vVq;vKe$$nRSqy9VR<>M@kt?TV=a`Xnd*lq7q7X1z3CXFl_z9BT$Ln@QA6%@JRp zVpYg_9C)c}6RXj=@JznKzzFuZIFiF^(HzVIgmZL*U6`XpoyR)i=bcN6mU}1XEINBh z7_;ad;H}Ip1?PnVGL8JPj{)$L(R~sYC;V-oH<}b$4#_|tY97<8ar8hQ8TZA&1H!Fo z-Xhnz3qEW{TSW7K%ZI7RNRal;AbqxikyI-ta66O1f`|_i$E29n^W{^_)mibIJVb;6 zZa%3(Y0|x~src*?oDy6MEl0Tf0qZS)N`djbIt|V6&yisRf6z0Z0&-7p-6$SDcMvll^9cNjBBi_qCB>rUp#s6|^B%G3Dt$WV-mGoct*mniQT{o|Zm;17H1p@q zdS@hk9aZf}T1D7APCAlM$k*r5rd4&T+4@Y>%o$`~nbum__V%#;S+m$cDVS-&6idMY zr|w=Ht#VMhp5B4W({1?vq#NOeUIY>rL2ZNRI;4Kne@oWsf__$4;D%3g=n|q;%PDpY z_G4#%5ZpV)x7qkfRQ}>}$jQ#EUhjY(%gH$*;+5ut+r>LBHqSLkCNpP)z(Zc6T1RLa zBDl8l!&x^L_gkgbt2fxOB@mOz5EVM&EtR%#;$&il_4?Ijt%ku$-2#?_xePsh;-B57 zw%znn3wEqWJtBIHn?BgZuXQLi+%iDsGP4D%5c7AL=vUJw!Gz}rGsi(F#3Ks6*{tDhr@Wu0c@W4_r|BKtjNcST28v#UIl zr(610J)xs!dC;RYQ#&CX?Z5d9+Lq$jGE-d0LAislr%BGM_!W_HuW)gFx3M%xgAXg) zMbb-&qu1cZoLH#*5wJK=>rGxRSsV0yRRS;R;m$bp|0m=>o;P*zZS3r#(JUnZ=y=Y| z%fQdWpJ5tcjF)b&OLs1sxawhMW#La&qfYvDFVoCE(bRt^xLL9`q`~Hy+HfL9>%JNF zy$yNX-P>AarU%~$Z)te1IpC5CE{%k__-D3hH2auSPnM<({JM>PVMlRIY01W`HlrUg zV1dCRcjyer7`qMySs0ow7Ny{RrbA|!Yv94?9H`{AE4@^Fx|o=_@W=>c6`%UT`Mt1L z0^;+==C7>sT*{;9P4BLgmgrAnKa{eDf2{6UcFi4c_0g48NIqeFHEc>?QNY^K|skFs+N?l=qIaO^a|r~c{YK3kb{X7 ziFppgaIg_mPxx00&{}Kcqj}_E8xk+bfyq+QhW7(6b2A22#*6oJ?aXB|kmbBLT3kF3 zQUsK21eU?j_H=y`LpA+h1XAgI)knZOJS`o znZb&&u?adsT-5Bale%BkW`!o|1MMjoc_N@Qe9babjMm_9efy+LAZZ(~X?K9@ci}Ip35Up*?yKFdWf`@ z^sk=J*SDd|L@VL(pO*yUpWsb-UENUx+P2e&KsSgX#OG{kz3bv2=l&yvE$Y`vFenld z7A6ez&0t1K{dBg&mDGsC{zZRg0lp!gkECKoH4y4o>Nw)o2dPW;TOgJO)DfP2H9np*oH9n{i491*6*_(^3L_H^2v$M0(0D|9UoN;oTud*!tC566pDedk9BKSW znWsCgVw!FuKd}>*{_2T`3!&cN-HI^}YB&Fzs=Q$Zy^^NN!=U(WMgy{LvP0gld*-gM zm?0SwD1!-oAoG>uJjSGUYuVYJFJbT+WO{5j$diN@14Hc6IDKxV)^spQ0|ZD<}!s>}WR%n(=#rcHJDY zWmDUNrd+Vg7`mu>mqMkKooc~OmA1NS!UG+EoSc!7gCh0ogIuG7T8NQCx2cl6xe6;7 z-2M7$L?&f?-cyEz>msPq5}aw$Xo7pV2RK z*p2y8^o&EO$xn{ia_3edwTDNZ#O*{7f97+_fY=A zbMzi>mjLt3Ktfq#=G#tlsm_0Cb-}XD)p&z<-tRs|SqrTK)U4k8eAPNv4T*V|Uzqu( zH6$L`oX)h*7WI><1)xx>Zok$Gxv^5Ph2eG@6(Q};2zAZ0h`zn1n`Ej%etAUYYpE29 zINCXJk}F-y>ow6E_RdtROzO_iLz>lh%+vrv3aj zD|9anoW-CWu&&8-C~Ft;@Z!~Yhw$Y8o5P@txwr$F)PtV7fJMf@S+(8&+#frK0nWTR z@r=;i#qleoIFTRdo67|no1B7YgPZ2|zmaN>u&M5@a1PC;b${Er(dS*k-1F~LmI;g^ z1MY`3a0w^f;PUK%ktuTMkrw423!kD5>IhvH#YN8`dT|6iK7SC~)kQ!ClFXx^P)nMN zYDqd5A&8rOL~4bx<#No7ILT76LT4q!%1ydK%k1*dTApY9@E>%EQD}xdO-wz$YZt-h z6UNo*(uuq;`1>E60jW!x{(~F?*U}s>bjc0^L&LLFH=u<>DjOq{+Bv|hj#Bv-GXmXB zOd=TDhXmy*jLD6^+~#^*S5^oyZ+hmEMhng}(24-hLP_cqXVyNAgl-`ODX!`lw&E2Q}JREHXFl_Zh~m(4kHd=;!X#(*}@+h^@0lan}r_y&X8m zDw1wp_g(blT^PN=$1%%4w%Guj)GTS(EYS1PND5%FjC%;WvjiW@lj`Ym`>Q~sVaeV@ z6NOa`nYjv-Mf``4Ht)9ZY)~LXpMQ=%#+SJRw12{=$|6|LP7W)vZ|cUFMK|Nj{_J8~ z-o*6?Uh?4OyTR6nE;pnY$~^hZC*m}g(hK`kgPBOpOeXpqv+9BcAwNV8$&Vv}H#2mZ zt3F^+EEUu5VGp|omG|BKshju%gAnT=^s*y(AVU9ILGSw~XDd?PVL1Q9e*ZjA_4SGo z(zu6B6}t0z@xXGv&22le38|*|%D4CQHR{i6OH<3jR>hWysQJp&6MzN_WkR(Xs6Rv2 z5;<(oq`o?u+XaxYMn-msWO9i&PlK+hS+Nu7oYgIG1rIHX$Txm)sfjh*XMDGsi!yo8^s78Yd>!p@h+_If(_v?l@XNY(^01qzmx-LGAGmYsGkIG96->?e z)jq*|getX%4~`z#r-Cqt7Uea4LEUcKsc2hOkmm0`0LEd-T@3f6w|TZVzt$uMp+(}h z=U(9b;O{>ntws{Kvz5nZ{Y>L-{9hUT4`TfFZ#DU!rj(0gwFgW3qO&#n7hF(acPXI$ zPq7oGeo|*5|JiANMPe7$jeck5x&&x;ew6}@ikom|pz~r>MF}b(VBK11m0C)ze#WtL zgXpE2W8PY z(Ee(Ca4+L=+u(BjolIuR3#^3Bbwme&D2(@Noq9OZa*wuYs9Mmgk({RunpT`{srYGF z0F;bS*p|plBi%~KR-j&?p&&%`nrWs;%bezB^kJ(dfNyPjLF^nVV+09ZBLG)~xmd;S|iH%8s_eVLP+5WC171}qZVOvZG%1|>?frHL%| zRMXTy0{^liqWLa^YsZ)ITN%IDvXsQ32T8`AD-=30VZ?6hc57ADR(f}iZmD{Q266$t z8KFw2LWH&Pa(bNFi}_%?JZ~`45dI#HJl zG?VEz{QG_sH7{StB-6Y5D1Eh0z1qOLLsa|{d1+`4H?!L0U_!`)hoxZ0(c-~2k^hCi zzxMnpb#_cIC;55J!L_h9o5Dqs+T&Y-AY0yq3jA+#-rN}#lovfAZdGY+H^qA*Q3)p2 zlR!j&l8@Z>%C#0%15Gaz(&cE!dkX*|+4>?JjiZ?CR$Npl$oO3p`Gz~Ye!OkgQv*eK z)_qIhN3IGgBd?MbK;@Slm}|Jf!=)tGs&HbGp>GjQ0W|%q+ zHUz~abi;)75*S(HM0?zT{Zb-RoVu3HMqZXu;DZ5YTaeZ|x033ov0%X3ckwWw9EDgF z+KM3l9BklTU}4}ondGtnDb8X;vIFDsz||vc$Pl6%alrV$j{M%Q-{6JM?{-(OLy;+* z*|=+Fy38*5HSh-?ex~kDD)jJ|Z0wE<$E5R$`U&~x@~#8*oA-%4><|#T(H@lp@Xro; zjP8nNIn980mVJ`?QI1|L+gn`syQeT)dmThN_nUomv^|}rgA-(9hz#A!fd3$QA?6TC zWd=x@ZNvZ;>6+Cggt4xf!ormfcHpb+v|6DHVbkSo9;eV37?z&Qcv5h#@26b`zY9e1 z_hYBy1p_7v@Y*OmH7oKnR_!)Sq08;#{c<9xxg=6R9$g&JtN_Lu9wgQ%@GwIwtQ8UO zCnc=y!H=poP5#lspf%BxcL8qlI>Z<6FIX36GY!)%@RQyLCFQQWQnA*JktPg#P;E zjO~8#2hy}7>`Y+E=6EjN63^vJxC}QL4MP(OtAGf+GljGuJm3a>FUm%eevRZ$V&t&$ z#ICvP5^mKiVJV2T08FB_n>XW5@eg8_W+!ysCTB!Bq#+Q??UsnX4|eDcEDNH>Nq|mP zeE*Z^hN-f!wH7jT0P`Tee4LqjI@CC;(O8c^`TpMHAY7oH&gM#$6mR&~Od=QA;OTf1 z>d>;ygg)nAn27fAs{6 z=Qe!AWX-BceRQNJ3#^-K+%9ep058v2Vicz_EZQ(3EAAG}GJ&-~olYjv-+5Z;PsCLG z0aE2teCNSTF9Xx@Kh~g!PHI#kT}W}?AKSA!E>0syw7BU0^VwseI%jEPTe>jO*uG*g z__4C0EfBgObSRw-^D-Jb8z?2;%wOCv)#pRmlpAstg3-RH#>h)QW6(L{fpy}=M$%e5 z^@4wln`?uG%r~(m9IAO6-tI(|@pgceUyC*TFnA|X)X8yplr^Vg-Lz+r?69CUccyqR ze6))xW3W~AM;?7$Sut>qCqRwf?(fBbH*7*DRObggR@?s7uVy_+`8DEUfenYpR5Q$} zu8JwiWR*P7j&YkZs-e>$=?V+$$i>i_$=E(G%?z9dMXJU}I*3)1Sh+b@5M7u5)_rvP$1 zErn5`rmd4m7Kdj{dAX&wL`X=j1v+cv=&RqpZR5^c$W&1JfKeyAp~$kX8vytFN#gMmw}zuI_9XF&>ruJ!VCi~ z$#{po;5+A+uv~!l8=Um*5#RWhLC!)e8OU^~-_<^~Ob2{wA3Fdf_ajEE`o{WIEIbNX z%GD_RYTrtCCOi;8^<}N}!^!89PCS>gx8?vZ&3Z$#UcWlV=Q?5Q8$Xg$l*m(Bp?-61 zZzaIVE2JhR>$j`2!9kHKEphCknYy8rDl4xVclDmNW;UJt7pA4$oYSjpmM|s0B6)#&T-k17)~=3~o+x zheJQ7U8gp9x~;kV99z=Q37tsyGR$nI{oq(uf>(q1ye@>t%ykOHE<{JqiP<6K_O`vf zr!vQPP^17aK+wOV1oLZ(CCvSts@%;Z6Akt0%@5&gVs`-(ffRW2?Vc1|Ofh+(YERpB zXv3P`Gg~gu7{%z41CAW4YDJd%-u@9vsFDJ=9Jz0@!tSS>pRguG_+O6CdN%n7Zs3Zx zn^Twfx%o&q0bM*C{$_*igyMJPEe$GnJEnUOp#MImHtjheQb?RRk(PYkirUhPmQDYhfXLnOmzPlJ+LV;I2{4lRQCwMUo8@1EZ8hLW zZ{%AZgVeoA9}6%jty3%ki42TYx34|b(#m8Gdu2A;9%vyAJvL4#os1@UT1tp-D4fvD z?I;hd5aChw*^id;t^45kw{E;;QwQ9R44@EHuG7+u&$y?x%FS$YY$}B&gMtCWkbI%5 zkStLNd4(l61wl4!!Mw^padJn5@3X&U-oX4)gK&71flqFmuhhJqTRx`1g{M$v0gzXQ zQ_QSFk93XEY~*Xl5wQkk12RP#Y6*w8Be!7ZJw?dRt61l?tEvw2kdwQM4@W%_bfWi@ z{?;7Q+L$4znf4P$*bET?u%-S+s!sAOiQ#$bOGr|K@ULQ?(F$VO#VFy)0t)!X{$1dV zK)vU0TCgp%$gR7dau)A^6vL6?IKTq=r_A3zWjTu1)Vx+GSWI9nzJiKp38!xS^^X2JWC2|jPZq+)l#T&_C~R(>v%-Z=KrjG70O zb57w8p*;u}4B>q+md-q0i-leDy)28;Iam`5_wiT?a+LuakqIZz*LpwuMI}sA-?w^V zbX}QK5e+bPaABnDk`-nwW?Z4#!xR`|qzUK>C^VAD;u43bK0|}BUAyJM2)h<`y{Yc3 z`gcKo6RKBe+wN?QpwT3@B>Esy2wOl2Bbwh!HBgHg#w)cSc-7f!1$EB`w6o49K0FJy zf-joVYGa~_QGNX6g*Ge%F$XK_T=Pc8`A3(^tZ^z9Y1T*i>Bz2hSwaFNGFjEgZQA?XniMrV=bs4{j~nfGohhKXK+I?3rDeJXeK@_r)8-cN zI=N>9vk#~1G~U~xdklWpd?=M&EvFR8ISyqi1OQ^N_9;dFDH=-O96@HTFdFRuHxeIO z4ea+NW0zWamE7-|)aIlS#q;kEq08}4J&D;G)SY2`%=*x8YZVnDl1{bKQNo!G|7w!!U=>CfHI9B0C_~z^Z1nQ z{ME!U^4qU|zn~GG*mKIHp-%)1q(YWL#mp-o4u^S9=&?)2ek^@pM}O@RD(qmk zcimX6Xpyxm=}TO^EQ9ieVbBMcQy*#bN~&?uCUXNeHr*2m`G|9vtEyhV*Tw($VhnO5 z(O)d}fWGr`Pjo`V{+8^S&Zq{Pe(T+dtPpH{{8yV--w$QbRJBrp1P8MY1>)GoD2w8c zKyFf8WS+Yow@9u?lO?vn&39gM=J3T|CT*ujkN22JG3@hRW#{Z>V zmy&wvGpYHEjljmVtf4fU;`NcBjy9&5iqA0q)RjvGIH~1BN)fjn+*tHR+$U7zyaiA( z%s@|X$JS)%qI&7duHJb%WcWKFkDlmk?}Ak}RBjMfJSe39eQw>P@+V_I*c^TPBW7n&*X{PfmtgTOoJBCwqY^%(iqmBrF%KV7RSZAlI;vruLw{EARvS`q^4ea5Jb0 zKWBTQxya9b%Rf;eI~9P1Dq*wwDgM~dMUqXLeD|iK%2%nY5#$V}a7~zdRMlpAnS??6 zfeQ>xD}iSFIr$hgaCJ~c%i-%;CuMWg7vfM|$Ilq#9ITe$nz`&a?PeAT(%=O%cGXlB zdQVY7d2ziP#|uu%5K1tFo^d-hK=u$mF5{)R{`yl|_P1drkRhKwf@>|!>}mTkXU2w3 zG^kb2ykt-#Z2CdK0r;43gq}<)&bMsz%KFmQ-9B8woe}ovwop_Z;pP*jWq-Y%7EWpM z-B(ZKr}8c<5EIm$1TPHDYs}GO+y~=4m#k1;m)b6Dj74itT*~~#b5wp-N9^*0dnv+F z6VUF&f;X36iyxB#lMxxT+HO=)(@EH|DVWFV{9*!Z2x3s2Y^Uu!OMNydw3J)Vr4Gv)XIJT(`7Y zWRd+dF*f}MX4eN-RdS9iH5?Wm#HG`)&A`ii-}v^@%-}X`DE&3R0?yO~nvU7m3G;$C zOiUNy4K=8$v;l*2F0INgf>(olo7nEyu`a9nK@}-ezuHf@+C<6bukj{1@>Xq9ZhjZU z(2uSuX_6`E$;%~8qm+Mgwa)9X{z5j|4zdar(2{z%gs-t`L`)TI^BK~Lg;17sXOh}? z>hBPdd>wsNLp$|0ODo6uB>RlerHzu$pg>xN^9MrDRv!74>n^L6BUIH{^1MT>7ks{!Z4uUI?e34E+EM9Fs z088W;2_u0uzhJk z_pSnRD9C%+9K^v|cW@Eqohe^pKcPkJfZl6uIZ*RYbYNr%9E9hGv0LOysHHiA?o4fG zGbnrKr|aj^3$w^t8d5AwUPNbLlA}M`-^Db(M=;c(nk%TelKi!7R{fB7$xkl%eoL+V zfJ>@PrW@>(T((1D(hv`WGjh89ILTs8enU;K^yX7dfi$yw@v>Tc#poYOSE*OiwRR{= zIegP-TI^y?MK1I}IGT$Re(r2=gq~rzNs+1BWf+=R1zAhWwZwpZpd^V%-V?}&sX;nU zoVDF!oTas;+kMfw$*O{Yl<(e#iG<>&@|3 zW0qBq7b5@Tefde;B^TeA$U{Ypx%f0%oke2LT`so?*-d=Z; zCyeOa{@DE+VZX5~dyu`FnA(=d63ynLGH+=#zEjqat9Ulyxu}Zdfab(* ze^kx!&x^h@g8k9!l#%xQk}6BGJ2 z9+!IG&aHzji&lonUE7p2N~{DJ9uYba=a{OscSU$zw4XjNUFT!hZDyFq1m^{>NnK$} zW-A0UNA?wRVR+zn7_Ci{JodhkY$<)>4dFohDhUMOH#T0G;_!)Tt*K|J7lI|G-<`xp ztb_dA4|t zoVUDS75W=4^1`LGv)LN(#^L535UIie!u%|_rYaqsDfbDd6}Qg4k+gcTLy7UcUtYMS zB)2CrVGaW!f_X=veL}Faj+ixj!5!u4_zYj;Twj;Bf=qvu zmu9Q7gpFaLM*{5)Om&rFn6^rbu%SeFmyEt_u-(j-#o5#ueX8ML?l!<|72?UcJNzDPOCyfTEDgLQ-z`DdN-tenMQG0 zu#DcAp*%27`c`x+Jch%Rv8su^V=+L#L`k*FXLHUdb_`Qo5`zr3=pd>CCnv=WBQydR z`mhcARtF>1+;1i#>I=4Rd=ZVfe6@rgkJ_5%e51)Ip%@Y(pK5QF+IV^~w7u%3ExM+A z=(y}or1b@Dt3X?hA|wsLE3DWWYN!ld#RC&BY*lxXmI1*~%?qWM+bGt2vk>F9j97vH zYZY147&X~4rT(lw#faV(eKx*P20`o!{=N4w6V(RX-huwsXg5ks?`M|)p{!JZLp)}E z*q#{-Zdf9#1CFt4+=xtF+B09IkGVT#P97n76z&ifr2a0WEV%ndI9_z@ zRTB8R&+i-#tkCJzjSHTgr4<*-DJxx+QfkeDJlPqqnV#1Y#v{(q=y~}6XemucU}3LZ zdYpA8pR;+!4l5BF?;C4yCe+Ghz89EIdbP0cAv57r|31Xd6WMDouW*NxwX$^Gs~!PG zvBGHI;c`q3y-J2Yc(wajSGr%4e4&5$CQJ;&J5RqE|_dOUlhNNf|jBfgsD? z(`(r+32!%EX+q#iJj#a$E=4L?A_q`)d)HpB-pG4930{r5UFB+Y6_H zCC8)$|4|-Pv;dsnX}K&~VN^m2_&6{^8gS7kDUy}01DX8eYg!`bD$Nmlb~z;zP|h!y z*5RKmLlKc;8So=D{71C;np+$bdiz$=sFBYia z%=YV@SGUUjBDPATIgqPzbR6&LBpfte78Q$#5d9yn+7vS#`uZX<9#XKOUPR3jp-dAm z8c3)gWNS)&jwRb5|Ln>H@#^G(T_fXoAhCiAhAs9WkbjNuV0~;?2R4ZmxFa*g>nGbo2e_jJL*8w47lzC1Ccu+@_!& z+CzFtNR(KK1kbn+J-{U}up#j!Xh;0h`~zuDxW}UO6bMTK=@t^1^#GVcc$Kc}#mdre zk!SFWdbvq5O2nQz4Imhql_7o}M0wE+orfp1tCYsXqzP@Y?J>Op@Q_g=YYKWt<+!By zSaMq%#&bjpprpci#)+)epO!2p(qtBuHurL!qBj(1YXFrRpNNGQfYyfQmckS%Z{!R5 z9PAWlw2_CdorlfiguE@tul69rx?WE482GSZv|DFj9t^|*^qE_08<|C9bEbhndy*ts zo_Uu_DR>Fakr1xOY1;|;98Mwr;%UXNLrgek;77e)9)umUyxKxk*OhMD*R7>xQT)5f ztGn8grj%{!kx_HB)T%pIY*M70xn=?V`I8~9MoBi;^whq5c>=Op%2e-u1MdWFf zlCh>05yOI6A$eQ&_Y{QyHZVZYLWCmFd>BmVz|)^Pa%p@iA3*Em{K=zKQyFup}Kib-0vtdP|OVNKiO# zUZs$0r9vnVan(Q3rp+UIyhYvF83M%%fWr7AszHXbn);}L{I`53=Bz6D&XIG_lt8aBRu%3N4lB5U+!Lk1g7IA zY{sN>$1%;j@#x$2AtLyLK2GQ89DkT7UNTb^xRk1#s|gwDKpTLbP4*bL{ZL|$Jq!s9V7I^UOECg+T7k;KW-jiH^^73Mse75 zhT2Vur-MHtDhUma*+dC4;wL9~Xidh18Db4E3pzL_%-Z24*4$KK;h?g_}+vWFZiS;z(2Z6*m$gM&xHvy!+Q+%f#^1 z6I+v6-xc?M-f*UC@Gj;M1m&iW^5p~0r8S30J^W`O<1TizYI1Bl#<8{srk$uduc}r~ ziwJ#)YmX|l0kS8{^@D)J$MB@HmJ;Z$bWMw`yn8;y?#Xh8rc&m)a|IxCY%fOf+nT6W z%LI)6HY`u#2GXLMiU1PHYzXT;?RfMddA;UgRa@ji)?NYwI zACl~-2-!b>ek*6;@oNcYqh)QU-dAR#`-vQxgsbwCq`_{HpM4$EMLN90gJvw8D|lCdQP=nxOt17*9-ZvaF{#w= zj~g_w6s>e@UY%nY`ZEbf)(F7-F11NOP?kiv>hyUHA#;6$v*!-BZADu4=Ev4x&MoED z!DeMXuO&!Hv7HdfByR*3&bP1 z5F}(Sq-v%AlD`NnFA9=~k}opeNar!o^u+3u1|T=vk?P3q%D5IHRkAviNrP-Nddn0o zhdQe22XZI*n+e)*DOI8}p-67NUFT03+c(AHfhDr=*XPup;FFR!YMCJph{jD>Q$DQb zBGc_Xmp9Od-zdA%aS_nrvUOLH^=h9F0pVGU>%Qq%Fa-b!?;b=u_vGQ9kvd7bCrwNk z6rVs{cOoO7PLJTZx7dhV!iv_k;aiTIMvp5)g#vwjgh19}6Y1JG$H@PH=i^0llznWv z4R|e@i^+NPPnUq%ezw&kv8DPm5JiBc4Asxl4)3}Ci{LV9DoR0?Qs&WVwH@cv03H-n zNn8Lt9O<YMTa7qwYD`|F9 z-X5SUZq>-GVy**am^as=>>mXdnSe$I5Pu^rYLJaz(FhQ z9{V!JFvsCmzHrS0imt-tjb{ot-s_<5rD}7PEzK*PrE4@BCq4Z;wTu4T=Kb{FKwst| zS@Jcdd#BaYJee$6q4-^n{F_?{o|dT#cs4Z^hlSWAKA5gelFuNKA5Z??W(_{|*O{%05ui)Mv(-?r%frzG&%)9sgaFM-HEoZ01CgYLSLseDi+M0uT*n zuoFZd^i*v;pmeg&nl;GXF!n*kVj{dnvwe*pJW|?oW3U+?jik*=_Lv|1-WYcImq)o1 zC-Alm{EH`B-v|i^iQXjcL+Ev(8A({*qKbT1IO@45S$ej3Zo-_plv%Lh0}~J~o2iFA zV-L?D;in47Yul7{T=o~rfyMI6{X)-mO_MSsgQ8lqtT$Q(d0*l#Res$oECjBARe@^n zRt^fsuM{*itt|yoWMp^xj$ba7C`&)x_ce!OpmmkAsRBW~WvZ=Lb84zb(_{q!CqxVX zg+A(?)m7rbW$xo#CD4Gq^?~2s5D1cX9SP?|ZS4{DNBZcqH(l-<+ii5ynj6v9*tJ$v= z_vCC!U790ubE@ZzSXC**3zMFxfAMbgv}foBKkR07W(^1_OD2Ko^F@tkKQ~2--Y?i` zY&Nhn@oy*?`6ygz!UeD=)%s*q3-8Km5j%|CCD(qv?pE z$eY4iA3YZmb?hr62ymfZ2!C4UL|@9;ki%QekVFhe9zk{DgChx6Xp%Afc*9Wyxh2rV z(ALLSS%Z-mFT!{}(U?b)j}?~WE2M7Ak6HO}Fks&KCYAWbAH{KCr+g(}MMhcl2OvgN zH>k!KMf0y{_qYQ=N14)?kBOD;1#cxHtj3wpwNs%zk=$D7mVwM_fyJ&t8n zBA9d0`BX;$Wlb-fQFR2?E2>UAG12_E0gHKr#0Tz_1EIxS`!LKP8_pBfZFnt^vC0LQ0s}hc<8OO-M2o|<&TVJXPB6v9DDZ+8jna;sk zR|nmzr@3xBQo)!KMN4jundATB@mQ*WVf`t4cN+q|X_oF6#c|IT#=N>nXk;9U#o{GM z8YR(#dn#Tkxpdcd)Gc^56)O7g)`LKm0Kn*q?A;{}NH0^KnQ*PLZYVFPG`jwRO`F{J zV*ZMRlQ3C!d6b36=dG7=9WbJqUS}WMnB%4f#-H735k-e-%;%TQY8Jlr5Z@XU*B}N4 zJ@VlVIHa$$(VBabDbJieUkNvA3I^4?q?g`QkKobez&?^yx5x>Xk{!G!+*a<~>@sm_ zf&}4O^C6j`G<=`~iw7eN(Y(k9+~2LmYS+N^JudZjK9W=3Pq5rUS$y*~0Hy&EBYYJL ziR2``{zcMebn3#`W&WK1Tc^(HsuJg+~YuwmhQ5V1#C% zY-?(yhZc9T#TF9jRw&LgI)onBCb!C1a5VHC*ldYGEeyN}G_NT1R~kb4a^u4xL%{VH zb}Zi!hpbtgOmmIt!?RTP-D>s;3m(!Tz(~(-JMjBQi}-LO=P2Jq`zQ~JXO;=#eA%aw z4ahK0>_&=}TfWlLn2J3!TSUy|>AsvuAqCW{nzV`+C60U38#N?Kdl_bV?)~GlBn)B^ z%@Q}P;NRvoUeH@-mhK%W&=jMc$<8gWDp=G13PH~}dwhWp&wFolBL0J0 zDD6?&jHSnoeyy{<^cCiHr(AY2Ouw~7uMWwL*%lpFr2{cSYyIHJSm>+Z;|D+;(HSsz z!ua!O*n-VM`Wvq@mO~iW>!ghjq1ei(*W_&2_vngl?nco3*bcz#Lw4C=3zsB#!&Ar` zG;>v=iUsf!2=#ecul7S9j=PbscM!UO+T>I1g+KR@Mr(~^58@ z9m|~6Q{j+N&x<#MK&S9)aP`PC3}+mimW8{QPJ)i$kGidV7yHxE&$MuVR-?#uHb|+U z>V5*GTumDV*Cs1=Zy35d<{S3D)+XJi2JwghC!&hs3emq?R^p=^T`N3Fxo6ID8fU)y z%#ULgInj$?h+*xrIrLk~%G?jh7 zdD2JDRa+RVnN%j@rXgMU`Mkzyqg>A`7(LA$rcf zFHs3Y8*}C}qowP42^8a)fc$eTe$efa{P4w4)J&|77F(5@JRYIsZ#CISjZl7nKBDtE zX&=v#9ZzYt1rWNm`%SZ_3@HU|%+|3u5Zv1)fl~stH6!0gL;%zgA#?0wdwq}kw+@ri zJr3$^!R?kMTjfbE+c2(_W8}(<=sL>!5g%ph_*3}jpt^T!Pb#r(Xm#g4HAP4=*IJ?^ zVihqj%qgsZ3k^G_>y1KeEU1g8 zlTJRa5O=vvud2GM5};+{F8}D*gWOt}H~V;D--S>kxgW!DyQQy|Us*&LNhn%8gj9)P zpjPGs2jNXgmFIv%w@5hS5gPd7gKqU0#&1$*X=u^^88r8z(R5Y@`>EXhLO zh22=J9yfN`LwKZ-#iI~@^>m`@0=uk=%XMW^qE^*kiy&mmzO6p@r~=Z?Acb0HAG{- z&9##!f7b-X9aU}KSRFQx3l4>==uRPXDpk(`Ax0lefQ61{fsGBJ$B-NsuM*;0K4In6 zO*_>GAHwj5FQbSE28^Rwp4{v_Mm2CC-dH15!hm%aq*?C@uOA0UK&sXUl|scfoKjC9 zCa{YYnnb4$VXFd*;KA)#xA!4SmpA!%vVAjaCe1rf6UN0%LtfgUfZw~O^L#nP|H4(! zgZ*L_03DX+;8?kw0cGGth8jY7ow;c~JbVwRz080n&gY)6tIBolHX)CPuR)SWBw4@=xdI8u#|&r@^H1c()$j`?kUmT&H z_gU)OiT+;jZvyO!p~^ydo+rhm0nj%Vwq{zTB=8F6_=Z7EXEBg0 zX(Z`FCXcXFu(zD>Oc*YwbYkQTU@}@)kw;0da6cVUsrsl%JA9vOv0nCl!M2t2x$2)S z{;lzaEYZj?FVl=%E*GY8OX5r>1+wg{)-EqtlXcd#$k zfwRl0R274=Mfg_#Pe-Cq4=kiuc8bjNYtlKmLL&24qyDLhb;!YV;6PE5eI#w8(apcFXLFbF#+_$5 z2$vJ=OE}YnE%wHX0$Jp*Q_|>Ug5#BLwtJxfZxyL$&;n(M8O4Ad!OsK^^|#7gw9HE? z{?)0*TzYzU4n0K0G9K->cQ`xxH@knSpSLtNk7GBI2$?fOJmTx11Y5`Lyh{^cr_ZoT)=o^0vpJkmA?1-N50@PJh9fy1XH#!C% zu@5Doq<<_r>EyAufLqi^mgSzV!#cCaU5QJs^*6}s`_<#YwfygZYYnttL;$O!UHcn= zp&;-$nGmn`e3%6sB&|e@SI+6#FM_5OcO&^j=CaJMvjj7B%HiqHISSXiqaZa^#+)6x zWdMOi`?)}lW^X&gfYvqG=Z-}K2AYQ%w`;*xH^2Yi zum1O#ZMj)E%)d9IcF<(T^x7;NMcZxf4}rJJw4iw-q#=qquO5k`Uc`|)A5NsU0phcm zo4+j;#-ph}MmnESFXt$%4^nM-(e<>i)QT1$G_yN+H^g_%-P`l%6y-%pF{x|XR=ws1 zs6UN2v&yrNFWWftTBS+}=%8y=yt|iUm4_RE?R(tDh_1XY;$Bj+9 z@On2UryYzrwna&Q&t`!C>d^(Y1HK}UGw)u37PgV)6~t)<=xs;OE#E>f{o9Vqg@TYrz(l9R6+6ZBkfVgCMR<*egq#49777nklt2pGz z^>SCEudi*4QobO87Vf)zmzG2`jv`Hj-v4|t<_HY?;0Z~k-172(La29w%XsmZ8T4WV z-bF>89CA|FT_ft&!5muOk_rUBHY+=8AlL0e+N#HQwr_6)rCe`hD%MmKV#PXv2VF zmJRWYjvO3Ekr`I>+eel5+5KNa%^i6sIGUQVCTD^Y{dwl2{tmayzH2zhWBm_5+)Nvr% z;_42V5TRM5p8y?=aNA{WKG4K#eokb74G<@VH42fJXEXM{pp(5u!A4z)z7}{}t^tv$ zVtu9(Z_rckpenbpc=^uNC7EOX=cxg87%u}$u<-s!!%1ZeF5o&Sa)nc;rv zF*}Xunm%e((cqtIVcBO`gaCyF z#W!4dMpfRXU^0(6Hlp>~6OHs+o~IMN$OBlSn$367I*BJZ+SL2no;;qMUge4pNk&T< zfRID?w0nbesgLS9Qjl#7!5%O)H!xtDyHGqyF<1Gh3cB_BPE{C^#rgdEmEL}V@Thwa z$tUI{%J_y00YPBLlQINC7nER2-_6csd3{kCYOy_$uL^m(gG8*r7W)j~xytwzlu=!H zZF!tv>%8$B8#y4$R!uj&(1K#`=U)APZL)EBIg59I=eOE~j0o2%PLBl7Ytvk&Vh57T zWMP#p8m^Fkb4jFTxOuJoyuqnwJRWWj$`^Wmmi{>U7w$^y1^5}( zPPFVsvEkHFKFaDAFb6InP&IXgdH zx>Tjb|NN`;978C*K?(r_dkYfp=K1@ikMoB?VKUGHu%UCG{bx@_St#W_h|&?$f}xKr z4{)dpwcMgMVqgyeB&z1Xfn#FlV>EJLjQoHLbpX*Z-E=#KFI(Z~-u5-RDxrl-T;@-$ zQXMKz4L{;l1|9ujx)gprs{)i|XFczY0ucCo9gHUv)Xjn-M3m?Wg9X+Eu`|ZJBp`Rk zp-fqR#wa}i(~GvKTHO_g_=bwgxGS9Mand!)i3ntc>u4juFka3d8afRk2au9{lrLwA zijQ#M4?lI}($|a(-PU!JBS)hAK4EYsE+gfp9jmHx#i7o0F2222CLnKv#$bKuoA0un#(J&RJa=O}6`L_b;^gw4 zLclEQ6Shn?Tv~V9oG%d9Mf|ajK+{^ZGlX2zbB3Ve9*V{~^D+HolK8m2VMVdxP;9Qf z9);oUBMKCt`9PKH$m9$_Q=bU@Xz3EBRt^}8P$A}JIYLfGE9=CvzCNt)EXk)NFu8Zi zChy}~v$=(>J-yY@1-!j1r9b(d&(nIa6|#Vdi!nA3C06ZZ1*y{Brf*0QlEt;Kx3vVW z>Ytv1;-bXq)@@g0)J6W9c$F3wIAvTJz{cL^e?9;#&I*j(`uJeWfL~oE7p0Cq0Y~hi zx4`Q3fzp{1k&@?DL~8ozxjgVt)%PlMg}?oS=qkN$^i5|IU}Kk*@_fp6I0Rjvp((14 z0zzUPb(7?1WavBkfMNS>)m}T>RNFM|;GIHlGkR(BQ!?Jodr)JBf940KPAdiWk5@lM zoQLxSKmYG=Q}$iFI^M|Sj=itj)-c_)I%8HQ8=RJ|Tk9p`DobK@bj-#jd^F65mT(U< zAOY_PKPr)XidqO(5nVwx64J6WSl>6}%(Be8%tVWSVbg!rsMTgZJ-!#3nUYTO_Pokl z$&ZL@=f7n!0ZX+aYxW+~C_`{6r;Zfw@`s5rdQZ>LBE(?Lq-NmC=-aJKhFTv}<%5xY zo)pa1f)7Jf-?A~I@bKFUe}FR*lqkXfMAvX3%?igj3lx>p2BBr$-<`|+%$jF0Qp2vV zKf0lOsznwpe5ZdW_PyJ)Ppw%w#D+SYaK#=Rc{VxAqM=F??)ELO361d!w}{dDNmVU6 zb-xd@$@>Zhlc7CGq6M#7KRrDm`y_9{G@C!`OERz!%E&EtOExFyM|y876LylAtTQs4 zThp}ZnHkpx%1_|I_Z3+3zrtk6S?5%Zg)F21j6-Z$jyQ$->&Ac-0I?X?HN`MmrqnC!l6WQhE^-A)LGPAfYg#E15g$O{pqauR7H zW;5*nsJKiw>hpRPeT@mOO!JlG{HMi*6#Zy*;66a&=n6Z9l%iN}(Lj`e5$rf9Bbh{x z>f@Mm`Ggfe-yOP)gfi#STN#O-9Y}stu>4QBir4T((}F4UlaHrBe7Ku6(l=^Y<8ue9J)eXSEgHIXSEgH*z)GD(XuDw-yn4lWdgquG>Ba zk)Qp@0 zYmV68Nb)Shj;n#zocDT8Z^1pZTvA1@IHKrbj?ug)24sR81(_+Ac7`gK z``U(Z_wdL|lY(^N8JfKg>Bevv>u*WZqp-YZ#v)*VVOvl0wi%^VueSnzhOf`sQpC*O zoC(uyL~}|9ghbVc#$^Kc=ydu1)!drVh~(zL?|uumf8#;=lpg z@RmD-Z+^={gPROTXEoTRDse5)U~UWaTgq>Ku^-WNRZ~yG02WiG8@u34f(@G7V(o%# zKR;aEPo0vHFx)RNtAiW~ONvP`0eNsL`7 z0w?7RlqBC^z-hOW2F^VhM6LpRiepd? z>1ao1M`_5n@g=aHr?BzrA=w|?01zDH+aH4j9$ku$k+yaK02q97Nu@O+EoS@l*d<52 z{6D*K+J`2k*KlniF8?;Vo07Z8@28!;TftDwSPS4WBxW`c>m}~YcM|Xngnn|8MJv{F zom$XI$7J=C$;h1GQx3^_T*ThQs7;!Z1WP&DUk7Hh3Ze8~e6)-)jb72EJOph?45ta8 z`9$)bk~nZLUVG*)oyzV>9vgYb&dy#uAyO&cnOp5Rc#|BmM~Fpa4bmN%&O>Pao$wFLt!a)F%-v_~CXoSPDG5d(g6Q zUkVOIHp+~-K?50<~-&tul5b?QI`&M}4CgIjEE zrcoS4A$M1S4B7?eAyJcS>`LVbDt@rwz%n)Ht?!<>2z+Y+`>lFRD8-A|TTO5mT*6!i z-1rabn(UOMhIeGzb|F2m3ZBk*&i-`I!_FB42Vm+`{d8xfgwZ3Y#x@aiTKgXRi7I0& zdtKh47i3?`$xo&0Z@UQ1{{rm;dZBXQcMAF{FEbDUpXgKbtVhjahsmWgd7#Y35JK*1|gNfeA+lL?}XIml6p;)P_@uEyU%4w6AKZGv|&LyprLDzj8OU0~> zBhke4{ki66n&RRt=Wb?0#-$w#adE6HCm(W9-2%CYRg?_?nKVD08z73mGa2Ysz;Rin z6+K`=_Oi)@>5+cdYslVfQr(hw!Wdy$~vln*n_UDuf{zUDlchFYc8gXD%V|n^JnWyc|KJJv?^@{-0>OlMhgF;sO zIyyqk1qEsT*>aEsCKpy$)Ts85-r6k;KG`cmI#?HnhLpL5m1fbPI^OTX`C$VC=*CU~ z@&LGy{9;xo*9v??R&|i~{pcieu?T~%(7M}e*(jT7I5foP?zU*PLoavUaR6$$y2!e+ zrbsaen9Ns5Of^Qu4Z|=%j>wuXxx8=a^A3i1kC{*x(AW8Sxz(eM5n!=TZoB5Wj^u8U z9<`3g%)0{H_`i?_8bMRskoSeuc;=$0L`(kqk^&WR$moAmc`Iu*8joFv=KwD(@-3}J^jYT@lY(L6mZP>tl-1)h z2QmTVaE+o?{ty4l`Bg8H&GZ@<8pyf4j3ZO3vwdu(X9c9vr>ijGfN(Gys>Ap8BH{kH zl6*pZZ0y;|*KT&hJ5|KM~l--{r zGGm|TTz_V@g>zXhp5%6+vc3}v)mL%-0I*tc$qdv*s10SpviynQ$U2?%ygHf)?^KI3 zj7yR4?ZY|Cqb%c@M%)lYfrQU5$r>i(3jy5?g=0ds`rb6c$NCLNJ>wvHgk6-9&iI=* z{lkk}2}{s}aE<^$K)%0)e{S^UaBsw&dZL@OO|{~bx*Ldz%gcg_T#|k?nW}0EjnD=8 zPCO%i#x)bS@(#|*kusDmK)t7c;`U7>t-c8nI?O~Y)$EJDx%{cCrI zxXffizTN)Pg#q4ojh)zTXMWYEX_F>*Pv#Hro+UabsL#eBj3`%?`o$DfT$&5a1QMJx z_ami)(&p!(MhZ_?B?5`*am6468a#9o;@b_gS(7I~gQ1CNJ_3(b5WsH>UZliZaz4Pl z?Ej35_O24!-M;-K8wl51;`4gbbo?|CT=MlgceFqzVTEVF{X+v0b5Y_C?{fGWetP2B zSmd@hHEdo-PlXOqq^wR!E5N8lf9vbmEczWY`+b%1%Gut&7frZC!hgrXIYr0uK`UG) zb^CxWto^H^KCS9EEOovZvp+oS{p=lL7jhkphjvK1U+*z&_+$)*S|Dl)niXp9t`?4> zC&56?7vMo?k%qjIFwreqyTE&586Jv5Y^AJ8C#?(VPp;5xa=}2)7~yOYC?__jKjt|p zn*LhTy1V57!Feo#Ew}{A4e_;4s!wkF!z+0f0YOe_FX$5P5Qg#1@;8EN_-VmlIlY0;MH20~yL(FIXTnX07x z+{Bg76iywPE|5m~^LO`HH7YFy9-`r_)dFy-QzmZ?$DdepRfQ~4;z5?-U5X>rU9k8^ z4U;eHS&1)NPCD6x`rcfPRCj#J1Dd&rq3L8uD`I(LtKB6c>~yBXTT1A_h}sMWGKIUy z-~Y?}{DQBtCkz%@OO+WV-UkfgA8!?g*bGQ3Z6cEOoj3K3PR#P6Pl3Ac@I?4&Hpi0V z#e%zda?`;D8-4p(4Q{EQT)>wN?I0bl-u{urjfo+fMdFozus9QK3;$LAHIC zQEaz)Vi&T5$#6}j9MOjPr|6^uyyN{$2Py6-MH*Ivvv0q^#Z|Cm;|{ltC0z&R6p4)_ zlIh?buz8MC%%mNt%c?Pm2^{FnylXObTyMY)Q~KZ%QbB!Zdc`v){Tk5zsgRyXQse?> z!lTFqs~YR_Mw6*00G39eW+W8|ZHX&4C~!D?M@9)T)zoMH>WtUbWK|vM7f}tjEV;C? z+?JAZN0s*?=fNjjJYxx}U`iqvh>3C(7ds{O0z{q~T7S#owI~vrRUjb5P?zDa;l{U@ z$&sv!NJn?iK5xdYoTGlbwO}OvEU62EOxUCJb$mdnL&8oacE!Ft2SXxFl=U9gPuGsH zC^yAzb0ShQXCGP>R6qeVHr$j`_*Af}NZ0YK*x8zA3x^F8()sK6Bg1j`ch@5FfcS?f zK(@WL>xLdSt?R|BHomP`4;(iYzsk(wZiw?FaqB5|ar-Xy4OvNC+<*G1l%O3=EfbC% zaZ}WY9eO)Suu3P!ab2HD?85GpH!*BZRp?U+_tl zbGfbx5qPh4yUtFiJ{b}Z%-NQzgJ;LZJT&X>Z0SId_>z^xEpQA)>f~FPdwM};z zxpb*283uPkn9PhT>%_j{RQ*9q&WU8^JkObef@5@Y@5bJrKgytk+GB^GYg-5k*dqe~ zk*vURIoF%M&-7fch&2Rnq-$-P3sMQc@(O^qZ_fqfLM{9>2eag0rrY9EL<_`=ut4J)sa1QF2oP1@=b5!GiHy|je8obPFj1_IFtj4hdo_$W-Z48 zOPM9)BfZHL>=b5?iYEcs$E@R4@3~+^(U=8oIDvmNX4@nr|B#u&ZqtK_4T0e1nlr)7 z);Xdx&!6=IE|)UE%^#7BN*TIPlc$FkSec1CyE5#8wD!E6cL8@{0oRlN*I@Ov_o3sIsrfbUDvBeC$Lx_Q5#DwIbTSHaedZ z6xepj=&nMZ(JXi5#gz85upIX^ue#|*Qybk4ns!r^)%jT@9er&?or9NS7PllnJN)bi z<{ebCZ}L^p(w+xttN1%rsvtsb*9J|iTBBzW1mFd0T*z_Yhaz{bogL*ZcEpqfn^~P(DDp>Cu!N-_wF;#TNRd4<=V;V!VHlQ z8bS1sX{w_z9WF&tCqz`6Rt*u!cubY+Y(zq%YfN0-658T#)xLwSGAFh{dC*f(zEJ7I9 zCAvF)WccP0=O6lpOs-0Jfs4AB*&>P>jAj97`054ZLt>UIsP8*xrg`>yAl!`Mz>Bs$ zS$jc``fK9cKA0W~_zUmy{5kkV(zHHXnc;{z>PZhi=IiwxPJRwp!?0Y`?2Sa?oi^cx z%6P(L(`UiliK(E88VWJ1tKOeFdt3o!AdMxd9DD7cOxbYvtM*0OjQM%7$Qj3LtU>;b zb-%v_fG@>36-4yo63(RY@)WGRD}f<(`Ars?DXge)ixtRTeo4;uf-D5I9|n(Eq+_=R zd7u{$#?Inyl)3t#g3UPWMFmN96z}&zl6S4~e@rLUkl^s+%{%TOz;V{%L5ZrO|3S2O zaP+n=xltCRG3$=HA>%hYl3Hcvr=$d7X~~ST5n1zhtKSan}cS=pwFVF3H6x`#iN^U88n*vDgW>}0oK?L^bQJE?>H0*dIYE&n;vQ4 zIu)lYe63WfuT~!<$z0(jUR|hFl(Bnrfk4ki#`x|R+_Xckp6EDWd}LU6n92^@wSts> zHvv9#{TiHQv_-yeJ`Y9It^QBOX6Bzp$lDYeb8OcdnI+(A-``ivFW$ZObze4HkCm@H zecLKo0d+4r7gU_?Iz*TKup>}HXtStmC_|5MdshEB;opRcESHHWtF5oF0E5S z@E$U6IO28{lidY#U|=b`ucD0zvGh2W1WC0XS&{!^2J>X3?H(2&b8&KDz?*L{QgpE&E&+I6Y}mWMalK89+Ro?%vk>Z(krOgcSXpl9@7)FL zAluIfy?(Wb&81L~a}5F=Taul_HM7ERL);O>2M(}TjYUsjQ}!l9!4WeQ_x)i9gXrel z=mbni-F9jROt^p5`5mm zz8Y+o*;30W#F1Hy60eRJtGf!RIVy{sisl)L_cM-gwFc}~)BTI+D9*MfZP)IG?wA|H z#0pS~L^9!^SD0d5>){)5ZnG|r){bdV9Gj-;(Ia(7gS!N}a5R{Wg z$jZ}$*w7Nc&uBTT@ODxojtm6+7;2UUWE5TllJ3CAa9 z%=(O)jf7uL1&-xoZPdjw?H%U|{-_8BK&3=LS-iuuuYOkleCw0p{rhpkYzc^#xS9Lx z&eM1M!;9Hoces5}L+@JLT0F`vz?sK$iG-I%b__;e`vkc|zJqYy@Rutz@hI7{kZG~G zEa}09kUNNmMtsIkN`=j7)r@yKA4qy40{&}rcgjL#V^|`$4Lj6!dLxntD}0v8 zml+SSL)OD9t?TVAti{)1ER$`ld5V^pUO`8A+*~my&EQ|o@l`%)q*T_q2d|dCj!Fs8tadvNewK;T85!|oQ zGW3X>Yr|jYD7h<;V+0JP#^-8Q%DlU}sCf#FTo0p%qMS<`LnVP^la2J3EOa}62nPux z?Q>WFYJ%svK?%(RQ8ppHPi2b+5{5h)B4F!`VkO4boHeNIXzY*RcO>`z9jVziR$|QV znAUR0spGE`p<3r;XsNr?{%X;etLj~#m!HE{jcqeo;&7`SFPt&>#pM<0+RH$p#v>KOf}}T0=Z-6b{5bz-W}I6^DW74aAqK z^9<=+ewX>$4GcY zMkqn)ld0CzlvHbTv7oHi`WPyjOo5j3(VS4rrG{Ig{HEA$1%ZB`(*?V{Rmp5jIOxRn zwW_dl7_c!uk~78?M&W7cAb5)5Ts#W7se}EJyB_QE#B(DBw*iE9j17(Ah&_O@)jvG* zD{m>fW4S6=RN62{Nqv#f0c+I$+Ast|Wv;4Lw$To2>d+2PdG%PyLF4XQPKo?IB*Cp~ zwgP@Zi+^F%cQrXN8j#%_pOkiX455kp*12bQ)613su2nWoMKK%8Y=Gzt1 z9W&}Lz`}X!y0+X|Srv3GyRU;j;(}Rsf<%4KoAaNeX9Jo!>#YdB>gSYUd<-wo`-nr~ zK8qiW1(QkiDjKg1vQ(t|G~T}xfMAT3Z^Bp&5S3RFRU4YBshT$cIE|b>q0vw7cYDoK znA%$FO`KH5AnEjkj(*p5=!(xIs0@mvyXZJ*@vI6FOo>o4ffoeDgg97s$mXH$Vog6B-iRO!?w7# zN9H(`%?&>)NRuyndGWQ%A8M#y1oWpZxdFCc-iH@}O_tqg?~di*JPz%0To#~Ucenfe zjKQ!vq+n0gp@l|4=9FA2t_!PqX3LoRBfo6uq$=(WlKUq6$@E}l$I_Q)eW>H%piZ#! zo{cUmq(SNu{1FJueGyyOz+>JI8tE7>N9U1VXl=oQR*f}bt>M7&Pd9v(iUIb^bqS}J zxq~`AELU%ABl42(o!!?&(fO^ydp^8`wCmGj0EVhOnAb0<>D}lk!(^F68l0CzN!Q@4 zB+ctC`%9Dx4#&-06A8poJ zBEMeGPIO;U3pgg$UG@yjhoe!w0Pwhc=wPeA4Qjcxi4UI?;@3rmWzK?_c!UHO_wE^S z$T~~uRPfTjvVVAOGkS7R)=U@?lkMSy&6s#qV`)`^UW^Sv#h%PFwo@}D8x0?}n#(92quP>s zg!x%61!SeR#5`u*1XW?4mpl`+nuR4An1&9Zm0!QzM_Zlu;*Z<&F#CwEN@e9LK}`gT;FNM6Yv9 zb$H_Tec-I%jr22)bwf0giyLh6QJJnH0}v3yh&9cO#prW3%$reeT?7jVBRxOC;ThRE zAhZv3R4!=m6{{!WLk4ocyWB~l-vh*-0+;|)Rc7mTOI>qX(JuASNj~3H>XJhg1DL9G zqDmY$)2^*RGR0W?;4lcX&UiOLuDEJDcCh0dXmo>~-%#BhqTgO`@)bHEJUTs$LoeO| zRC@K%_UbWw%WB=DXtJbexH_kQY5R6+zXVDKpHVDssXoFYpQ<|QQ2Av&eU(>f|U#?BW2AFZOXJN+rbeF41wo;AE zz+khRY-Iv32s< zXHdn`#KNqslfivRv_a7)QG`qEt823bF&RFKY&4H0uA1AwLiUX?c>-O+q+L!z)iB9- zTp9n)5_CIP^>RS1 zDhFaLErrqzBp-w3YJ~?*A1i7{x{>U0!4z6vkr3oe)G)~`rzG3D30$h*T)^}VNGJy% z&~NS5uct8RRb@Bg-;VJNn=zzjkFktPExnndEt{?)6jFLBbLm>b!h<@n zs)q!f{S*2DAG%0)RNK)(8NDgMoxgfj{P2-^TbQ|g*SuawdbCourOG^(I}HI`nn?p- zB<)=JPmc}hm9=)g;2_U_y!|eg(AvRAsR=(v8$Vbs!%pWahkJcx`W%(IcPB^>@Utqf zrh7D$8bHnTS04lzd&uk~Hphm;GA4X$i~UmY8V|MyC#L1!*@wn^_GIkcRpwX4njDXD z`Ler##vYp!9Lj#ia!`5LL2X6P?47W?ken)vjqyC1APTGqoyJdNz&JuY39i?2V(_hJ z__outS|Fq>uh(I)<`zJ~d3fOb%?RcGDG4n#+#m^Uv7e%jo?U7S&J{HbsJ(Qy`790O zWJPQyVKHlXH;*GFJRs%r>!g2O!XP6jjLx?%x`xAhGi!oXx5QV2q^)u^o>Zd=L zWwj4~qjK7a8t9mj4+$nnVlXrHwvTk zOb4FT4&kh>`Bo5heXU}-SM`)s64FGqgtn#G|3TyY_-lkR)=Pm7m&gL1Zm;k}vA@B0 z*F(c_=GN7lUp}CUe|}PEM?vW%JOD_Ib?1G^CRylw!jcIuS9IAeUglT?5A3$zVPJd> zN~`w0D`~?34P#lHU}O1_IbaQQsWQIovZU!6|6|A~yE_24R=QHZTo*g|;i5{^bFF7p zv?hjqPI`%=>m#D~yn!aqpy%v#&8z|?o)M+AoxVc5%FicI|C3aV6N1;l}_+LjX&Uqyj=sW50%Fc zY&+o;Aj0vJ=z~IaE5g27zA?%DCsbxHp}C8fGYC+4MLllwjME0S3POv+$e&O;ahe%q z!a54g!VyRvg8jv=WR-;=>ZraXP?q5GiaH* zGNcK6wwrui$V*;OGQ3{uf-6DDI_?aD8K+gdFv(E3e^Wh?_m?gNuRJv)z6Do-w9=6{**)Ke8u zEl-Ni0tU`0OdW zJCbQ(cZN)h9!WTA9j~fN@1b`!izT`mW zjlh;CJJ7%NEBc7U&`yu~t{0;Z3DAHLW5+dDRJcbtSkddz#;M$~$I6H1nE29FdierU zoPUBaJo%Z_YyBIBi%aU)synCpqe5nbtCrHrefnHVF$jtlB`L3%j5}{TUEA*fez&M> zU182}s3h(Kkz^Sojpsui%+I|!xjU2LsuK2J;Ty880tuH!fSJ#pftW5XwMhJQz53i z^NF4t$HVgS;>FXw_zg0$V3j>mJr!wd9KXFa@TIr-vfDnOQS?pv2SDj&y)arg;OtDJ zB+@K~DZ#F(mnNe*r7jC*aG9$EBF105KB(wZS&yx)hzGjZwuH!8g(j26*u*?&qqP2U z@CekNS#Fo2Gj|VtxUONA zsg-mbOI9EVBSzq~iTMsZ0a&{~!XSK-M>@bv0>p>)_0cUr z9J>@dq1qQF&;>`-6L0nj%rhRdmtxHxG6NIDK_Q1 zg3jkofZw9m#-f$eK%&-31E$$E?rwFg8#QVgeQ*DeFSVL#LvYHpBk|$ssmf!qajL1? zPL|X&G_jp`V|VJ@uCdF2X?Y}`NUDT2?k0+zo77zmUF-a9@=U$BGzJy5-dMCz??4(O zVDM27Ji=JoeX}PnBA1oiHk@AtwSg70_diQW;jnk`;W{%__C3g;`h#Vdv@gU)WW-gI z;T}fsUI9&>b7rHQh)(6Fw7rznIe=m)j%x&mRcB9#`td2QeSQG)Jx?396};c#RmjMp zo?*_OcCDJ8(-i`q$_IDYoTNSwWt zp4*J9MRTB(805!RzB5qjK(?cqEP2~?U^lW!f2_Ob<71}KW9Jq~dt z?)%X9;d2>T7n-O>zt{a>K@$vASIsn$&}-V|PFUTq(`XabMe))OK^Z#`&b2uJrCz8# zBC0@n-Wsm)_ipZxF>gaT6voIK@f)pFf4&IpDJ#qrKwVK>0r6H*+K20GYYY5W(xpoQ z*6f>1w*F>xMJe6yF<<45u2!4BJ9D)OF@A z{wR}$a}tuPV1o4Vm0>>RV?s(J3F(hqyajiM*jQUs1?%qdZuz+pTN+q*TvBb#Pa(`$ z`7Dw@JW#lwFUQjJL-xZ1PnGdy|G1Z{*YJ*upqMrz)8*lPTCQ08DEGlXDHJL#gp|5x%Lb}CtU1MV}n-Tbnd4#$Nl0OXoNOn!XjGNqtN;WownDC?i zsh6Qq5J{i$BJ2DrRmO9z3OCvIQ?)6-41BRZxNzqv-sGMC&?^0j@+#B>*-!$Bu3LEs z%>Fw7%-$l@NMUUN!|bWeB-AJlTiYD#qOC>}z&bIJ0dKIRv|vGj6; zh?E^g&}v#g_#_NA=F`>2b}0CAyvZeYBN6)r7BhE^^8z;HrD66rFvDO>E}>p48N46V z1+7b?8Y<`X(N%4-WT5J71%zGLNjR-;2;%pk5?vYY3_x8o%&Bg7H5Y-jPlFqTTdD(t zbgvL!DKoBnrcb#vrxtc)ox6F6n7&@*~xXj?gWiywVj>L+O))lN0oXFp> zSF2v>6q9M9Lo+=Y65-Ht-O`u(LCQxd%CdYHw3T*+a3xm3g@4NELyxlqNER zmmSeMqOOAR)aqHqw(dAlOu8r|YIIGqPjwL24ZR+7E((93jUkw(kX{T_E>$Y8zpL6P|_E*cv-!hmpL<&ee9 zNuQWV#mx;*b!a<+WBj)fgg*(r0ZV*E3?3NPirxhpwFOB9re9kqjM%#g-9~uKKDsgZd_#x4mLr7& zt_a6Q9@E-;pM!Zx8sX}bTG-_As}KwFMY2$As_TSQE%fdNeVweJ=R-Lj&FRqVFIwVj45P4?pBEeS=*LEIRaTF@UpV~HKLsb9!8Ef ze^GPTpK!INxV(Uy9EkhMe2fos#@^FE1~4pSqx#f$!?$i>D*HKCy$M$%4r z4w;Beu?IR2j~9w3M>7J6{QDV{&cswgxuGsntkHQ*$Hg7ki&{*oK0Zd{jmiGjD&`1`s6 z;U$Wv{&^>dca7UmJ4@3zSC-%3hDK?)xq%zc-URi+P4!L&UI|E3Ib!czZhYw(gKEh} z{s@QW7PN>r@O$744voVDfxbSY52)*mp0=*5FiB+x=sT}Maz^BMDG{s^kG|p6*?3bmPh{z5%#l0kV+Z zz*&r@VJKpTK>oAG=)c30(*%LzZh$M!I?ntiN*@ z(W)g_TR_*n+!TC28|%xUX$CfS7fdQyVIRm6Ojdn&{51y{}>MoD51=1Fpf0)V;xJD_e`C&?LF7e3=-tKX-C zMz>lEy2A|SV#X28&Vz#-Ud+K-D0xJu4%a7xIzafARL3c3+cz}Bf0quY6&^&i5amgq zP~Y0X768=2f0D1?ENxL>H;zd$R-0Sk8KhSm70HGi;ew>;#v!RF<{;AD&3*+Zb}LtR zLf>`K1~8eKB`*F3Y{2l-{yxHz@9I$}120FML<-A5o25C%q5LN80h{7<%4I7!`X917eJ{C{# zedzBXF~luld60yZ>b}&omZ>dKcR%j!=9@#oGw+_08aa;=ZW;!5+M$=^9QKXwJf_FNGi;36fumT<|*Gkt(i=s?zupicH)PL@dz7G1*&c0R3B7FH_9 z`Rw(>Zb=^CNC^)OSwpG~N(Rqm8+d;dO(7Of5Key%G4<1kZ*bal8a62r;=Wl2y`}V- z56{sU-N?<&MI$#fEl0cEFFOZ=QEw-bRd0lfaY~{N zhh+TlG+bC{kP08{KR5=x5Gb~ug&(lKCD$i?kcVriJH1NO1a>rSuvH&}9j67RT@(C4 zoH{_z4@vZN)FE3qgdy@_S7GEDOYkq+21!A?OE~c`5(Y6|&*J3n4;yTj2*WsvRtnER z`k8qNZ+d|j|6%dRlb=jNVc#2pL5uCXW~6H4_zjSD1ep{b%4yTB#j+JjCau=JQ|sdd zooQ0z?4x-s)`q(0JRlZotyxgEx`0%H+5MHsEpUOkGA#~zuRI zb+I{=`gua#k?c+LSs9%W(Fb>7qvj|84oTogl%#GdBC+@XxXO3%3+OKuehTsuVBu3$ z7z0CmN`!&E)9cJNVCCTiCcm%^D%OuV_arj2!2Fe^|kspY>X(eZ)ANPm%xCbz^ z6C*#2IK(uBQs5+>5!?C4&u&ie#V1KhPDt}Xtk(63>OLRiEv;ERquN#-&-_a4zY-ZekQ9A!o*BQP+^SaD%rGg}O_6 z<+YnrYfl_k-ui#c!qpaUo zLRjm@24XH;Jy2mnk45x_`UcztrF0H_ z@w~uMij*xuZU+VEpF2Fg--h%SLAIF~{-X*LOt^8Qe&xVEb$mVYPZ>cCVO6C)ErWI; zOZFkh%ZO#~JTFI0Jacsgf(RRjhBP&9|}Jt+&yY~l`a1K5rY1L4U;YmVU1mLjVeD!J4Pq4&sHNsRP4rE z^nWOI=utYzT?Z5-iGe4R_mp}b6{T)vER}_{~o3RpvhW0z7 z2nistC@5ELum@BkeU{WqA+o*&6=1Va+LAtIs}4RPH$Muqpj*ewvfTTzS8TLe`7u3i zL4I~D0^)Let9tcm_*Jk9l{zjox0q_x?B3b6GJZ_QlSE#|Up{Xah&*u5Ovjcg&B zZF9FaID4CSAsH!B1$P&bp7X6Z7+ewb{1Dq{}_rnhWVEp`@I)39NMO47eiV)9o{6>6{v zzf*^`K+m>Hx)qS1UZH#uxlCd4ydERg)*?w3Gr5XK7LsEGWTqFJ;ar(`fpw8LKTa;d zxq!qp{*Mt#u8pPG_-;k%Hn)m-jBS=DPFHUV%f^qv*pF!HFv6EVPbU^}qMAR*p)|JpcU<4u z$YXIzIqc4}%2C$uTXZIv#}(Z!p2M05_R0W`y{zLo0Sau}j$y&va5nMzg$4jB0n@^p zO$>Qb0tkKe+X9d}f+3pdRudt7r+yrV0uwa*^I&S6I%tfB15bWGd+NIcxg2NMsQwbXa^>P160eEvCp81tjVzzN` z&hVqkVh(o?;cfAyMe~#OlO+gKReM(D`8ov_G2KE!{SmuYBjDZ?;gWf76ypBri zIjQ}eo^aI)M0k$zFu)mr6K>iTT8YF##5S6a&>}CI0Uyr)Iac(Zf>_nUJzO_oV zv3!P4!%ZwT#PbcYbn_vLfgFSN`z32o;qSF))|XeS*AlH%XEwUC;Gca5E4ao^SRGW> z1*YvuA>kI^wg~9?JXjqknLuFQ2-Gmw#OJLL#i=Mv}=C|P#HAW^p!3}_9t`DUa} z#4Lcs-HeHh2136vkO3l}@)4{L(cf*bTj`2^zO=qBS0n~q90+V|*PUkFen|3MOZ7Cx z&iS;OPtb67MvG`EP}JF^mO-hTO^bP=D(&w54RFw^*CLCWxg9|pCM42!XW6^jQ-g?t zt0c*#&VVy`Yh%W@a(yH|Cl_4%Y!FGWw~uLE8tD~$nj*=hyR-S z6!uGmwPJ%`3yZ_0H{Gy8{pn)zNk&3QaQd~hX!;B`wB=fmIR2kV>5*!xF1P{!&)EIk z)LFIf`?3PIGA3FTXgpamAF3DUhZw^aFCkl7HT@hiSl7M>BM(8Zz{dE=DQn9yW?P*S z@Q$1{9wIdCW25;27&A1z{A$T}ZA-jRgsYc4#reVBtSle1dooL#mf~B;K2Tanj9TKb z{V6&1+x+9sI^S8U9p&7^=AOU@A5fze8Yj41Pc4b^I3xsPIaVhrh}LA2Jh(1VZyRwm&ek~nSu3HdBo;TE*`R!g#27{bl}rnJ#)4%L`^q(Z z_qao|`7+IbzEQzgleQIg~b7HJjL&=#*;^J^L}%fDhX1?7uH#AE-A{ zNHc;uv{O}3lhzklVe8)Hu#N6_0iG(q{GMxqE6&JX{X5ZABX-_94_fZKx%^bL?Q z{er`*+pLH(9x`n;(X#xRxvBI)5$YjbhUG6r*g+D*(OU?Tl8mXBZ8Kr`OuC;KgyLX%|^ec|r=l3VGP5^2ltMo^SQ|U9zf2X6UDP z2JRT^y0c1+6{Tq=BYS;hRVli^AN4!+Q0xnxe%8+n@)oXwEtkF;MYs1{EH5&w^n-|I zFka^N=`fFR`F-U5njuBJ&YFu=X2(l1yZXK51rd?IM$c;#NL3+a(N? zOMbE~G3CBa#kFjwl$6uQs<%;4Z8um~m6Us=C!^w+IMy<`%l|bzf_*jFQHkbq6KJeGC!*GDPT|-gGgYQJR1m(X996B1Zdd|zQjts zj_KygJ8qn0D-TQ@;>eO$*r3ZNbY;AU3Mxc`;;iH(8Ri$;LQ^b{dT&#&$s`cPmrKPxy~^nxb*mT**ovtF zV5qd$%m&N2PC@W%-GJ*YQg+%feP^QZ&NAH>m+!Y#I*zawC~aoYv1U$WO!SsbLq$EJ zL`gQbc$iTn(1r-HA-WU{J}4uVy48G-T*v_Jq|Zj+X6I0F82~)YFMtuX90v!~XoBTg zfc6Ei7L^1rZia&AQ!Mfh3Tqu4qR=16C^YI1JU@wWX6%SCZtdq`LU2a3>8_w3-!NAm zKIFLY#B6opL;M}BaE6m5hK?;H{n}>0K?d#pzMFXj&#|fGJqsvdPz+4*`X^^AJ6Yko zg0LJ-Xz!6;+*vk)P-=G{#Y(<;fI}yKzmYNxguMr(4C%LS5In_gEm*K-52cc)C9efp zr~XL~dYlO9p6Onb)zG>C%73Qa^vxeGHK=Ix@6e%Jx zDHQam=AYKF9OO1e==Ut+S;Okj*I}(%XY65TQI!*n)1(j=NG?>4XJg&KhCn|*&&hJh z*66U_-#d*K2KN(y5Wdk;!PDx);c%p<{CvG76_GV@5v%eFIuD%(u|@fa2#{8g$l_Lu ziA($ehn}5$I-SvI@y^kChqGlE5abs^Ml31RtRkpi7{^SqJ+$`O_)V7-Y)f)!Z3Hxg z_t%{yZ2E+R6Oc&eNTdMW!}xoN?mU?)qHe&gfv1afVoh%A&0nxp**paTnP*q3Os*P$ z`LCiyBohmn*~f@ne7(#6)E+-gzZk5B?PTg=FX`lM$`OG=tC5c~%xiT7bVgFD?h1jAp6|Ezsu9PK{{7MQ)+&l(*vLAj$cA;BW_{GR%JdlrSWIRw$+eDoZ+6kddtB3 zCW}PlKxwk9xEi$YJND_LjxtYrKkg0VD^pTH1A8l3_7lX!^IH?ongHYvKDz9qF;9 zM&Elo=d>U|;_=srK6!`hkM&AGAsw-+)^{ihha4Ndu8RyU7dUHJAePbuoAjFK)fvm6 zVqT{Mut0zQA&f^`NrYAWyu3V=*6Qf0fVaz#=hk0+E7$%tGb3YRCNf>lI5t* zCji9D;bsZSZgaC&xT%qvNRCZN2L2qxv=tZg7SZ(z4kR1GAC&oGX7g1^KB4++TMjIS zZvCnuMo|BcM) z4pNi9klHMP*x^;n76Zvv_Qi@P7?mo6En&4phGVs=!vfuEWO#WNLtCLuy zY<{LC!dp%PVU!VyyG{SaE?coC(IE%3o8@aE&pP?RCe|q0RM#5!L!mb{T9w$dY*)Q5`clj-s-2PCV-`2p;4((J0SGv`>h{ z52vsSl~m{#suIJfN8nqA;nPNi z=xbGTi+jyf9kW?p8A%$>< zJxYohgOblhaJzqTseSH2JteYe$Yi)wg#~+=)?o(fvH$hX$bc>===lB?m~ut$I7y_4 zP3pmN6u~(m2L>3(e70}=Hm(kQcxXOG!({6>!aVCxtieQLA*q z+RQoP0}$N%CSTg1>b><^fX!KaIDTbB$z zTR6fxem0Fw1DrK!6canCDq3DH`yfW59#uHV{!PV2fvX>}(F=3sdK#Q3wP<9MY@; zmtr7d&(U@K7jl^-IQe6?#pephn_54$DD?KqP^b5Nq?zx@wJwXhVY5oRMAQttIrG0V zW^%nOTtmNcI0CmReK6m9jP``~U!w2xiBD#!gqKU>vZBL9h|@QuCtd7LfiY!Qr>~i9 z>}ZNR6mkWqK)9NR{!Ro4BegiNL#rrR8LBGt>D5sS2z-5@@>!^1gAP z%;3?d#rYE5yZ)@y?-6wlaE`Wf%$wrUwE)9lBxZn~&g9sGs=&+l0H*FpBNdP$bI-V3 z#hhcZILehJs3CNMWl+y!PO3XqOxSWt<^mponi(rrn(_!kET)>@BRv-Zh}P+L05D>?Nh$PpPohG8EI^EUr?niU59_3>{F@xR(S~lhI%?(kAyo2VuL43dk z88|0wwv9SH3jBg2*s*-4Ut5UWpB1O|)CTwYX|h zcvs02N^-{s|I7uymP`~Pvik18tjs%=<1{GlN5FJj0dV(%n$vIxojuBfC(S``Dal}L zDVZ0ExzroB8c6*p(gRoa)h6wmecWB-!!%IPoMJ50y^Qq(cpg?ZeV-AB_= z?|$NILN;kVcWDcs&y0#UbSK}SGSgQDC+)E)3%c_*|8#fLX?X;#oLHaESI3?G$yr~y zr&~s64-of5@O}AWg(jU|M2hKu*nvqhJk-`YXjg!I6a<5B3m7uFexwAcK1hW<0d9nhnKo+cDf^cmut?e#QQ-8X5kTW~b z0KGUY8#u3R29|Av(Q+}#hr(?KiG@GUKBKum?xD9E>pf=AXWq>7<=F@(^uz8R!D$r+ z5_W7>ik7JQOKD6!i42|F+$nXmF}s4NZ_-Qp?v}~kEND;}Tah%JdTMQ6rMwft_Zamw zw}3~SZPDH^^L<5-qs-{o7xWH>X{~fJTi7SL?*T)>KdoKQcRo(PX&LYg>a!dL(%v%S zWV7H3!i*aYxZBSHfUWIuRVmc@FH=lt5fQum@I%4=3gJZqH@ z0dewti|(BK{xQP3yQI0jpomEe%AEY#hC4kMyuH}O zxgv21fzN)cmEm5Vdqf{O$HAsQ=2eW8mw1c3x(D*^6Hf4zQrJiS&cLjl?rQ|=ki!&!0SS62wEE& zo)50=;xA@@>d!@l^+U+1`v_1tiZt!5=7^C&bS2q@m7KSJ}m zJ;{%u>OzG%Za%3C^_-vj?S>Oglx~w%5sv9CXS6=eN{NL9sB^=rBT0CtHsSKM72(LOI_Q+6B=*VxFB*P5kh*n|H z)#_KuJ`2m3U5IcJJKZ(&k${GtaI1)_u{6Yg&N>q0U+Bw&RtE7Q&1h${dL|AeITp1x zzdmK;qF)`UdTQR*+b6OH&i(TD015Nv!_;a&(oo+}L~c({*U;%#CP!kr}Qw9XBxX z{=)W-7$Vk+!LW-d*TU~e@?j%iksbrHyc<*FimjGN>uKxnZN++y&X;&r8Mr?UOTK|; zsu0vu#WI~}};_Kft4W_)=^rOt5kx4ScXd__jLGo@K6 zj0I+i=%a&*AL$4&QiVFJYq7ivjndBcgkGaq^heuo5La_XIxK@Rzoad?TtXE+$~945 z?;qy-^rQK#7}s1In+1pjnM2x*O_;ALViT9-%}K!v9!q)5%}b=ANOyxqYEG~0KmFQn z7M))x-4XdsK`TC;t{9U8K2DuicIILP4$5~Lm#<^dnC^m6Kn@@Xh)z zKUE2>A2*=J)whnWsV<*jK^b8TDbpa$&3q=Fn$K$#F{gI!V0z#g_wSzmGrsk=CisU= z8o&wtYf_9Uc7xttWG5~Byav3Dc4X5q6QRdWb&zT_PaQvV-H=|E^_4y=us`?n?O#~^ z8}|iD#b9ic31}XW;{jNERb+;PzdXTcKNOX9D&xVxk&%RZe`>8dyyF;UwOicib9BYf z(?Puyt1m&}J>l#6&3QKat8@M^)>Vc4@%$WwjaCxx4 zyBdBH8NGDWP2fkSQbJq$d_L3git6oM#SGv?(9*u3A`rqxzM66vK6LJM3!GE0YOEeW z{FY(>H6c_Wk0Po%XZOS1dL;~c0DvDl+!+PhfUQ0*#JINz3#!3b=nCP{6-{h&rI5M8 zGuOyKrJm9dM#^%8Xx=Yc(v08YRu$ZdO+*Xk3K*n+^Er7@qg=YV=sZGuF)B?~euvP8n!Uy8#F;IM0n7wujtzsQed%XEcWV7T@^ z6lT@0glHnlWd=v&1i;s9d(-O!PEOyu#Mtr z|0tVIEP*IrK!@%_JpeLCHW?b75?(W3EM}vSOLL*gBlx*;dG5q0pYF`HjVSvRGFX!^ zP_o$zAG9srHp9l-s^bmk6}lFp(>mIBuDDHxm*l(@>K1Hh<14~QJHO%%nxA98UglPB z!igq_q>d@-s%M{EEVp@CJh)tOHp?CErMMhJV{g>!jO!w#bG~)Kz*zv}Bpi%vABCrS zEDpIJ(^l2m0uRg5j@5XEvlYRTV0X$s+8+B>FviE5x4N&+{uZ#XR>1cquXB4@)s1}N zk7wO_56`1fZ`xjy>@PXUf%o3|@MUXp!ASG*+a2sW+jM<7=2lLn2T8`eAY4hsY3uhd zRoIJ&T&JT&){E=) zlI=Dd1hu#?y$u4aY2+$5rYLC`liK}BDNXUIWv$+x2&Zh|>Mi5F5f|#_EYT%T8aa+_ zl#e`j!{MJ%I^2sAZF3(uFaI8d=4+WJWqZcMYqIIl_D9VaUdgloWTK)MSCR5*CQdoX zPN3=n03GEylFvmVv+y?ykxYuMsFu6hJ?z>QrlqdD(SDq&JHZ#9j0|6FTf1J42LSkR zI|hTBsifps^!?dVBrU#Uo;O;>%a5D%H{ILsR3|J(Qm%=LoLtnkE`QL>D#Oaw8E&8) zp?5BFm8g;pzy_dyTO%QWwI7_ix?xwW`I+&6P(ds`kp@p-lAkF0Qb=IECZQexL>6n_%~~UchpTO3LjiQNEx@^4%>( z5|=oTK=LfT@&((g<&S<6-~OOragnC`>Wa_aQW7c$-Qz2ghdgmtog;AJPfv}fVe(P| z_6zsKjc{ddJ>N$bXX3x4P3S$eoSL>DuI5QM*J!}XxLM9Ol}b4{5z@hNscGrEMufp* zMYKU|Gh7cn@bgZ|2{x~D!I<%4xQn6Coboa}PBS5vI@zIY%gLTK+vPJS%^x$=?q5tl zye~%cX)h6TcA=t8ga6xGly#m*&*|=PvJrd?z8`wn03R5`r-hcn)EHE2s>{naDuy=7 zvC(;2<59JuCkVQAxBwnH!z0o04v)s-ClF|vqMq&k_y8J>wbL9YtQxTX)d<%@c=0A{ zZ*L}^_A#;6C1hs(mgcCprm&O4&5w;@Bg{o=qGvPh>njz(F=S_zcFk+D=Co=OrfUdX zL>Vi9c-vFuCCG$!hHop~brqcTEt^MU8RR}%#&8VgVo{nnT99H?3#Y#I(XrM0JEW?0 zXJtw2r9((I{Ae}@ywTAilZOi~%D{dF=kX|{UH#+ZkRDV)Q#fPX_y2{NCt4Hdo#q&p z2hRtFE>Ro-em6nfu1FHy^+K**Vj3o@icQoRg}sHaK(Q+6o8gs-hYePaV1x#OZ|*ss zyrxH2c;8}`PSfSFm=FeYyDV{>knXv2#;TE)Qg>Ghb-0}=ud+G%&WV=-RE}R3p4TVQ zF<-k;rc3-aOb9$wxdbh4BifeI66{huV?_-}diW8LK1mfM->f2+mdf4GbZ%C%tZcG{ z%e!aiA+!eLZ+X2ERF8-gV_=)f46VhsL3J>w!DESXaopr6p+Wtd;dXTp!UFVY3{8hK+GUin0)E9jG(9G7`w^` zhNalrpizW$GZ5%}!(0X!1$B|2K)T(VyrdQfD(Y0nrPHRL#}qZbu{P2{Cp^^<&0RI7 zSg)$OY9{!vI8jw

s0b2TlWRfLpXFD0@mBmMN=+f0~ifrREa#ZbTEu^Gp)E?#ggD<_c% z^~hG8>D3d@kniCPCf|bv>UuF5$nrR!_z;QxY(&d2A#CjR{LBbhOao|AP&?O=Y@*}Y zg%cC)QNAjgZ!owYq~GO%^PzTJ5Egl7CZjD)(pmBh^GxYD(lInVZelM$D*-QdnXx|# z^Puj#B7wmJSJ8wHg-X>`?}ZO|N<*5mdW$f_pJ5 zHzOYcY5}j0q5=kgY?g&}~idpxWZCkf`*6Myu zHjd7l=D?ZIRoL5)JZg*F401@*_?22X@7W=E^ed*<#q+0CBvf0KaGPRdn?MVhbw`1xp!dPQjo1{CNyA0?a3nUwHXa!)+Q$}YsNAd%Ew z$J79NTSpAm=e5)PKyk%nHnkd4#{u%IcMS^9tgok%Y!E4fN=8RNAiPmr#2}4tqW$<} zboq0H1LTBI&4q5DE-8X2HHbI7t;MN%QZ`Jb@lqtzu$x_b=t+-{@pSme0jRQg>klse zK}Ik5WYqT%xB&F!>;zYbuwmat@s2dQ2VRUEyz_R>8(ENtnCij0z$03skFFBL(_Apa zJiCP&IE`ogGQB^DI?m7Q(i8|76Czn!llLjvZqfLTl>TG+vXR#o-te;p@?G4A1{ZEl zmyozFo917wkZct&f-`a=49Ie#xHRsd8s!{^LRrwdz221_!X*~9(<@gA!88dy9CZW0 zERd>HxC6Bl1UhFuLIZ^kbFLfIW*5!c$_N7vo*_AbAi$+2zcuxnlr(7Pw*(5{LzH(v zH0m~oK=zhJPeZwPlsHHF_hk{Vc97`P8;!G&o$Nb#_#yQUh4IJNPZ7*E5SlmS5 znCRv-=b@0yCTk(V`a}*3$ip2Gat<8%K3?ZgI*7#j1>G?=eHT_w#7Xy^WA-znFD+Kk z{mkz}Uvv#vViT}?mDoXnW{g%onE7Iy5vKvtPM5wzd=8&<+^GtTGf1q0Zi2IXxJ4;2 zvNrW(TsM*5Y<{KrGO6Gauxu7e+)ojaYdSB$kEmYdJH;DE?xB%LfM?HjDOCKDVl_Z*G`Tb_O zO$cmdse`Peh{XCm6w~`MdnLG=bIWLEc=T56+y&BkLFfs6rV^*O*`jVZW`dnRVBpW<_xu?azA zpF2qW+dC3Fa&2Dwu%Wk(&bjES4Nh|>0bIC|CHJGr3(78uY3zEgn$^m1WIwb%^-2*1 z^0MFox@zloyTbgGT6mH(Upx`aqBnb!Jt-4mR``0>cR`iEL{{1^gX3ZkGnZ!mtFTQq z+93XIWRgM&jwPV5IFv8eV*X?6scG`}atGmwaezf{dMW}6AfV>=;yEB=Axe_=aox9R zq$KXQG(CJIX~0V~S*sUg2oP81d1$b||-a`qf`g z+*9-_YCs(_8xy+JZk8v|a38%ItRW)C_)1dEtUE%nqZVt>@A>exhhRZQ9?X7$ml1&P z-~s~sJnn1EFJA|?HWN)^uk1tW@13aFwXmd(&dgFL_ZyC`k)9PFI62mad&a#8TV0jo z@6hP0D#=CKyk8YZ9!pBX4?C9E&G-2<@Y~OQVy^+ zKTS$YSKu>$#WR3GaA*$JNb6NYAkvuP)>wK8*D_OiU0U9{8$?Hzu-wtINxZua?aIhL z2x{E*B#ztF)}CStDlsIktN0Z~2YEu_!iqRW4iUuQ*0XTTAMsvN=nKf8ghhByd0;o3 z38#^xZ9P^qxjO}~qvrqkCTb%Wn_t%S5EWvU#tZm|d4?uGc`!Y;TSpVqkawm$MC0%w z^#}uRMhG~Q+5d#{+8C&Vd=@{j;uweeq53Q)LjjUSDz1|t^JsTUB^|StE|Xa76NrLF zsEF!3WH_ufZh|i;G;Jz~N+t{4BpKfy{R*7`duApVU>7a3HRo}owl3ch7Z~+K(myC9 z$18*iq_$MDSUy*+ZKSYbkXsxANI4U!q;0(X;OkKlmM5B6$#Y%y2Y=U@0AsIevr;)p z0B1nQRMVJey+Xniufd16-WB60!?@3uO=>gJ4C_UR-n+2qd@0RY)!c1wVVrUt!0U;g z5i{0yL05}>_y&1k<2dhFitnL>f)Rx4^9EJ0cL0IYMJzVxJVyijZmFV__xdcJ%Ldg* zxtLMG6|9v=#JU;y7%aHT14f+Npc|U5uk&=WBqc3K#b#}z0ZE;xiTO5)Cm^j#8o}P)H{(Bbta{)W!_Kvburp)2-sH?umpR- zXVz%RxjTYa^^u|l2pEE&&PE^nXs}&KB*4^9736;)3gHYTFrubWnuvK*MZ>ACHi(3i z1hrfeTBylL5DRt^Awdc-{3M5i@9|tt7kRUMm8SOYgXyIjB{D~*@^SWvtowQoUE@d&=F{PyywL4_H&%Q<=l+qyC-F zg*v{qVwUv0&@9CMo2J_<`;UFEW*&^Gt~4Li0p}Lsa1Y;CmfLACg6xqQL2 zD?fxMdGa%WPcLzzyQr@GQH5ck;iwDKB7|+?)Vwi6VXR0qIIG8LOBeOjn6_&Cty@Od z3^t^GMh9zYGY3UF_ zpfy#vdPThZcHfilLrAee8rCG_l8yT?rY!+uvSto;xY8&Jm#8K)PJtFi(!jBwC~3C` zP@b=$$EnkA-${(!Mf@d~SgjEhg}%lY|FFz+hgVAZ#>CYu=FxXjJl%8(<9@qB7{?CHE%63 zUPH1oY3**(-70F_RtFOX_VL)Q5L9PGc!+slOXN;8k+dQ1{t3MulXc1Y`oDTL*Nt(!uFyLpc*d#W`^p#HS#B}8-ArDd3IgsP&MTG1q?|Zb=PR+H8 zVjVW#S;jB3e2Ee?*^OmCrO}Z)75hh1IlIYKkVcI4|Az8|1E*5CJ&E`m?JOXX8gv-G z6jgYyhIU#)ovV}*lAJ*y1GpI1@^)g=Qb|LsMl9c48`RVZ2{HUP53NL7Od9|}G76T7 zhhlgjf~)M0j*U5ka8c3?F+KIE#9& zl+vH(O9pka1{?dOI<$qpq>58}URyVMTrwZzer#vlfbtL!jzY9L0=I&2=XpDP4KsI5 z>)21RAv+`r?_25mm~<@w_cHOYAZ-{eCowhaLw_xZRQDkdt#bXwz`R}L{RS&EnXljzk&D)x)PQ_diR z^KF6*Ficc*`72M#a5V9n)1#=2>&%Mu@EakyG{BJtHUx?Hdz3mqcFyU%6> zf=U>>NU&r?TpSMpzM~^^G(LPK_RJza4vk>=tSl@TLE2lN+Ih1??NUk%ZlYPg9_)4{ zov`g|taUdyS7_kLVNTnMe5O}9Z5!-h)f?dO39Ugi`?bk!LFE*SrS?!mCJI@a9@e6) zdotkJ>l8_-h+=w(i_TDOu7q&hvk{Jflj2g{|0mqpD^CV|?1l7P0vPBU-SP4!U29IgS7C@UyG74;033piE^N=Yh+WJ>c)hnkc?B2G>nzSG>h=H<5Vi6_m z#kl+~2Y1*8{>&^B7n#9|E-NmnZA^s&E!w+A@(nhzlG38808z6st`~Vj;<(Pf!ZuCB zww2|SB|vwzcxSJyNd{L|*~oE{nCbzVV?HIy(});Hm-j%+R6j!SCR89BCQUM13oo@0 zzYOoSLTr<7n=P&L^R1L`R@U>$)$u8B1IqzyZZq+Gn}QSnN+%;`c8iVK%nQsQgZMSFeKe+u$b4Y>}{&+!G2mcDh$^3p0vZ zm3hUbSpR%4>yNhRnli#no?ZgDhJ-{7I7yIu5L}}5j#q0Mdhm#MUT8?Q6G#rq+ouz~ z$QuD(ErB-)N-?Xd=F>q#o2{lUJQXLRIH<<%_iOjS`=MC?>uCyfAcbAIgQZDxInYL; zQ7(`-aNjk8lffX-dWlklP{*7Q5$n%m;t6)-sH>PF^19CDlHxiF25~kg>~F9YIg)7f72CR$>I?8>2TlUo_r zeGyhX(F|?jF@umN5dtRhpuPSSQoi;|Jz4ZhcOENRUTA71uIf|+XLYqU!)|RgSiRY4 zbjB%U*X$tu9emUYr_MUmZVMJikNbwktY_d4NH@ZA4q8vl3qC)h(yX?&I)ndyHc-il z!CaK%2coWQ_EADosYjs)+vKsDVKN)%&5eRafXu6YTAM}`)Y&8RP96-9AyrWP;}ZMJ z6FhaWvbyVR<~sF8+3NRs^(Mhkjtnw0{5^_i*X#i) zMRmUauSF(qOP z0a-5?Itk3$8~&33mLsu6J4hU_uR9byKoMoMW4^2HpryPoSYZJqF+ogpFaTvkpePsJ z9k#UGLwO(L=yUODSpOl9p^29Z)7sdoV3` zL{u+ElK89EMavHzCvkNDwX5N1yE*qoIukJ`%#qG!+;P$E&(}2)K&0-O;5AV&Flwyv zAi&8nxV_F+jDRXZF32sWGu`>=Nk!GAkMk_c|EP_n?U{?ViIIcULIm%%i7Cz4_{jUfs6%^GdKwB0O>h!TJcT^ODufn-ectNJaQOnWp-=3%6D$lHcT8&~FA_K5 z9Hi7t3jHV+<0HGNnn2D~5=AmO$@Yj5CM?ge$NAMH!!{iMsc_NfPju<%N=NIC*VNxi z7?&fsw1T@hC`{*j!EXuYuaX4+v=_&x=F1gQ<|>OQ z;CE~IK0jujd0R7`CiFJcj2S#9;R#XtypTEKj5q{)hh=Grgau};6!r*OY$*$;1^2rm ztrnhr_*TFs#`*JitU8b_aj%H7^y=1rl;Y4>83TxO#d`U7fevw@#Nwerxg?+gfA5@- z_heIB(5@Qh-`{CH=4N=)p+(lIML>Ps4aV|$X6_tUNs;9SDa~9sAwrm6@_Z57mA=*< z$Hv||zQwOKPU(u`v0&FE+sucXJ|_QhbbeRku&1_!Iyq$UUidWwL$a8Q!?Oqg3?Zm&z=ER4aL@^`_i$ai9c9;UQC># z1z?K3`LDWxo~4U9pB_c!^@-!*P4KM3F(X;~|EuCqNW|j=G0otcUw} zOdYkT##7+jsAE?}gNu!pB2l=eKO<5dqIy)m5mJx(MRwQ)VmAmLsz`gEGow{%NbwJQ zn~?uhKq3sSD z!l&@`xefd4=ZX2_C?RSlJ1xx-%Gp(9?S?8{@sp~H>r}H>P-)2ad2dWC;X2(>r?8=4 z@&*esJYVQy?6nRr( z_WKZKKXCOBJYnjr$Ui%*dfU`9k8;pNO?awjtlnIo9ExhFlmu}*>C@;(g0{`r_qt&Z z1rnn3(uX7Q)4wyDwRPbyCRVuOrYQZh@iHuaF{Tcu1VHS#V%uEOpyJWWxvkT9r(b)B zF&Z48j{;hOj`^(_`il1a_(4bliZ8qWdPuNPuyJ=qJW9toZq4I(0D#1U=^B)y3{wbe ze)EYUufbWLNKpT#?-=ikzrmFj6C{~BV`obq;>HqZqkrju;)2d0ovC=X_o=C-STZ&) zRt^rQUSstds_EAFrwju)pbwuk_b2N}eVbNX%9o}JjSsw@_jPIDR{!HLGzKyJs?f|4 z@D}U^W*GsQWW?+-vO&7uUz)bvug+1V6fzn^m|b)=nP zI%hM4h(hA4^3a(r9oa;y&~p=2X>L~Q1amei zXG!+n22>HSG46I`^fKU}&`R1)_|i{VijHFciUT$eBHo~ z<{sJ{W!L)v^*3WN@h=1DS0FdC7jDNF!POB{SYEoVg;F9-XwBb`O&j(DQ#T&D-~z0C zX9#Qq)4n+Xxs9c*TmFixTCpx8tY(W=m(V+H?TN-zCd-tF(Y4g~HpbEr*%X8YAi(!Iu&TS=-Fpc{xA&pgJ~&&esXErPuwnpOo96w}gK*^OgKmN4pS}sA6lb$d zq1eSM%k%LPN(d=K2R8BL^7crkl%pyt_(4&-ZCh7keo%x-*ZjRAUW_g$giL%H`|g?P zi?8ILq+E9ssZ|D=nCd_2b+ru&;O1QmKFVg;$0N4AtjntPyB^c)$hA`xsy(s}EVq3u zEzctZ6Y=BHa_l{D!&dX7J*?OQI=$(T$05Vb#(;H<4C$_G1m4H=`owSM%;}&l;U2u8 zRjfv96qL16wrZUENoVr(cUoQbDc6taQB8mIX^Lb_!M8B1I7WJFQ9dn{yJpD_jU7t- z$g-JjmnCM?{eX@YqU$iq2|?U9clbF>4pRMEEB20-Xz}(zT}f5g}3sPF}C~{F{*- zlD9qUs@MA%$YHoK6}Wc*LkV-g*@;6dpB>SECQgEEU%LP$EF-K_)r=HjiDT=|bk-)m zN3%exDg|i?5v!CxFWEM>(=H$z2ElG+e>}5QD;#Byz1^PthM=Q>adWtp2=ga5;Q~(0 zO64gvP_hwiES%GY7CF@i6dm|JN&4XRfE;Mr4+Gyw6uH5|^OeubYHbRjQ8!k2-_RH# zreL$UU_?4=%8!SGO9YAtS%C-w9?!DAEPK=ToIHRB_)Udq=B623AA9{QGk6h2Sg`Jt zduu9<$^{$do{^I~6Z3Btlh}-bavxP=0dahQy(H;&-NoJ?PgRX3i^T_!G95MGrp{dlv{}~`68deOn`2ltaBvCZ2VVcJHV%4xW|gt1pEp0} zc>N%dj0TiZdvS=jB)wNd+`Ee3B$UT(6~^-p&;?OOWSfnrJ^nUXAL@+6uH~fD3;DmB zme}3N8)A(7$om521Q5YHd)r84U*dEWGIUw%B4LVh?S)aem7Uf{>Dn#xQ#q#4h&Iu< z43Ns?k2+|{>^Ajiq8sZu10n=usU-Nfymkq}H@P5>)k`blW3Xhyt-fbX)NJoZe`1yIud(swe&Je1_YdP{hTVlR6_5ghMmQYV}?uoj@CLJ&mo2=66WIDKm8=)=GXi4dgbx z782wf2HiB+x}}5vmoo2P=_aE+?Ruw4-1kOZXACQ!)!WR-90(;d9@%f1lHP{kO8~I^ z%mkIBoI_=A&AcMUopT2n2Upe-h@(uRvmGY6>Pl`4gTB#>XyyuFk!UO|m1W^ux~BpQ zPGk*y#--OryKtLqRlB*syE;}%VttYCg9kAoaDbYMJ~Sb`S#b2EP`1`xxTEV)x!I*=kw{6M0lVt;5zEw4pu~-*V~7JdcO(^LHf=7Q zak8U-O;285&?c9vsX-vRlY40f%6sX6ydEW&XvRzfqXKNSo%|EXEK~+Wyb>=x>+3O{ zU*io#b3Fn$W2&$l7i%bNn}4ymZRe2sd*qX?a3MtlLvB~|k|Ox&-!t4#&}792{FC@x z5L~I_uJ%-4eCvN>D+{S6?#_x{WWsMD$LB>reyNWq_EWAg_1%jhcB%4ioka#J=94++ zhfM0k5P>9GvJ*XEsQ{ajl9ck1XY$j(aCSowJ>_7xy#x+ckd*y*9jlZgwJ0gDlM-@tMwQP_ zpMg~H>8Wl=`U)J@C!O+r>x1N($N{sh+Y|>E?@cY3J8-y zK@d~b?F1Oj85H6X@cYGwsF?l`Ax`E(yTxf9z>yn7N9CbMKTv?lzj>+aJ9wrw7nhtB}Dx{R2#M2(hHIQ2cl& z>K*3Er^{S`%QvVk$hvnvH!;)YQT%C+AU$%QvQSqq#JIG4u%E{^3igZOg?xrUesZ}L z`<<8wZFcWTi2qc6neE=}`i%kY9{tOShlqFxcp zW7`syn(xfuZ&=VB!nQQ=0zi(H0EBLMy41hT>8bD}09(b4V-r1?(~jfAVAbb@+EMq7 zMXhWVy1u{Aa{Zt~aJ=k&tN6?p_|@K3lzB`9(MfGk!}wF2k@@QHf9EPBMNuwHp)fw^ zZ0t}nEmcZFg6ud?@OEx`x=Q&il3}KR#q*i3zd-#Ja{(a#z~8%6wfv-VR9usICs^XV zXKH4CDRtGyn0~-xB>TM1ri&ae!o+{HPl}mFiW`Kg4v>rGL3MuAJT82`gsqivuacpdnjs#dpH8u)v^3M%M87 zSW~`@eVBz|5J$E0l5px}%l}J9i4e#jh3!N+!UInu#xv@tK03f(uC8>gN2|L=al`=f1aXQ+AyNgG< z$*N0Qh{}85-3M%BHScs1$sAh6E(!PR0sr3?#9(cJ>)T16^G}UD0p30?MSBo{ zLi#TaRg!-#GM!iDo4b0eO2!~o>z?#aX&EH99@Wzg!@N+K)zB5(c6|TVa<$bURelZ? zgxe)#%JnEKNX`=d3u$EA7|M-y&I5x1`h z{NB2I$d7x>)ru`wzjJCg9f%a1x&dA@?kV>{1_uWcCpjjvl0kvnQUa6cucx$aD-INA zP2Yd{a=*6G)=N&l1v#g=GQzvvx&dD03*FHPtD(2~f5vgHW~(;r+ai32iZU+>p{OVY zQ34sC`aKtu1i1RJ!>3=sLKqi{y*9RDXDuems;e0BP=UYWbUU%baNgwO0m zjb1+N<1hBDz1r4mJl?>kQE!`SqlVFoF7&A8cs;z}QdMwQdotx%3z`hfV>^LTxCIY zJiTu$m9}JT=VBhfx)jZuQA6mtqoJro%@c+d$L3!j#se#8h8cwGUnSq8_@={k*t$#E z+}GUhxv!J=?)HrmEC+n-Zq3dUexcKfJL&d#DW_-6afb&P5AO-f!aAh<4TZ&?yvIe7 znr^|l0L`x{w+R)2*odT!=D~FovAc_nL?iDh_rVzt8wE&QgO|H*L%bUE%=5^Engb2_ zKtX?zdcEQ;qx(z7pFiM5kJ=2_668s~)u3B$qySDM4Lp?T#;z(KLVI!;eSUdA z2AJYq47WA$yK|_czPm+`{F->K4^}}|7@?<=2ta}-u-^sk!^He#{S}SeZviaNulV_wZ7>5 zu+yy@YG% z7uRyn?U#aI){KFfz&e?!OOLYF37XscS_yz+YQDd8?fDDl^cdA|?+4Cf4hCFkjb&!A z%EFK;jcmX=P8z{rnMe@?$#BdZ438RDzhe?N@bTjokgzqoD5 zqkR8fd)xZQA>8f(P~R`u%{(yGz!g2!Z9HkHgFv-FWq>DzZeJ|CW81-`4lOoVsSU;E zu10z<{?mo zFcL_q*a*~(CRMEc`$!G2EtkSp$MP*hH)XOLmS}nHE%px+B*Z1?YD|{d5Be7|bA6@H zzx^3<{fsJlv##tnweXe=SWKB1&qg}V&XT6`Y+~dD84yWo`o^(Ig_c`qSV|qUXl_V5 zthx9nnG<+n`kZcKMo;)Qa6`EfG{1)75Y!t*rCeEKKEyou-lAetEQ&2(QbIZxfSJMp z7Fm5)-+Xx?HmTVUm{`S%U(q*TKZpc2a~BI%A**p~>B}%ztD$;5Z~FjC&-dm64-4Vj z5Jel6?(EV{dVSLZTw^CZcNA+6Rm#6^zz>N$ru!tAhyy|l_(%?aBWY{sc-l}=9d(PE zDA-kd+Y+1B`18g_Mm%{3A)WvBdReU=!K4Xfh}UYo%62|%C0-B{F0E#v!+Pn7-^vVt zrd@62)=$W4x(xZ;S*-4!lov~$b3|x`Rr~3>T~M&AN4k8^NRu|Z8w2d|Ys)~PNlgVE zhL^dt)4#bdt=S5hR5SMKx1_PkL&!eNkO|sKaDixuc_1#hx@rx-V=J4y3g}6?_1gC( zO<&^!6Z|0`}2-@2vZXZ&dM$wsQI#D}2 zxO=L$R>|%~>WTvNEnj8qH=!GY+1ROUfA8svy*ATMLuV)W^fr1TAN|N}?0R232;@47 z$~gv=<$)>2*O%@pJRzFA^6IK@M4TV{QtrOLn+{v&1--YS;x)Rf27_6$g4%o=B!7yVWOFCI9oKVRMI4cO-X09=77Ec7eS~6Yu*Eur`~=I+bBLa-eQBw12}0h%W0bXqEMnb!AZyT=^k{q&gijY zJf?3=Q6=mw=!DjsuzV4T9MEWd#AtuF53LbbKK3B}7Y{7oHR^6S@q-grKgo~5G6FU) z{15Wor`d)SQTlmq)tAI@HoP|_>){r+O0)cHU#g$+1ei>5mux+Y)=#>i{#JhEH zT#73w$1-z_`)h|{s>{c>g1(oZO=NG$kb6!Jh!p7q^K|{4=aA(I*ap|QpS; zNGiFTH~=7i+yTt-yd${tUFtK^swQ}1ZSlOkX-oT;1d6uSSNbaUX!Smye+FLqBsR`R zvfSzu@TgfAH)r%;pbwaR9;Z|DEcdLeRr%H-PVoj?Xb_<3FWqsJ zMrDr#;&F2woZDjd9?u)Ci3tndo9rUp6i|HjdmT%qiZIfXfnyMJzlwiSV%cTli$~J3 z(rt_gfS?=(2BX>*pDL2Fq(F0sgxx`Az}6Ca6eoT83A267c}f~?v9h(taCEYe`n--(OY<&^b!jGwh<{SHi6VHn$*CnlKUuTxJdX0Y#Ss-2Z%$G#2Ro3j&0hwXaDokSHRc*)zDb zYJC4^IwiisT6S&NF9BfQKA zz;5%#=Kd{;?i}{h0*(D9CmcObi&sVD`fz#hq^o3|X!XzAy72~b2&7iXP<)8sxE`_^ z4fqSr?d(l4GCPH%@>v011-BN6D)Ww7fwe|*jI3W^+3k2RCuadtQF3~h+-o2x{s5V}j- z>GM5ea-=-81}o>m2Pc~7*)jjU+Cd4L8r(|g-Qk67)0jHvzM~gSmRFo9La|x5Vgf1^ zm0cyccu{M^3x-R6?>;gpMm{3b)SzDb`Ysb_*kwy%GUldWSvI${Oel>3XXR_lXR5Ze zWsGGfpI#@R2>zsZM+at(^43*&8ecWYJM?c%>B7W9&t2rCi^y#;23`}Uw%{uKR& z~4!fM0p^rrwyYW~nB1|qj_9pHM^c;mX z6q5cZe`pSxWKFRGf7V)gEgR&OG;?u$`UE4s3*;8uyF3k`l#6Ui%ZP4)G`Uh5a7(8l za@2p7hh3PKkk{HgfUbNGtqFOhO zlO$>!sD-D0Fx{ztrk(Q?vTuqXm2=-!aKNNSixfJ{4L!Z!df?=B2_z4+F2>$x&=wDp zNbp>tymKNIS6`FUquFPqTxxKCf(qeJp@F=2N*@eR_l}7CtXA^Kr|j?r>#e4U-$cK+pVy`^vRtssAO|x(u`s;NZSAW1NHD` zNI7(O?bB#ydYv^HxYNX`P6Zf1cXs9lF~s1JaNSGbJ!{mq z3$R&BHZ-23)hdXR=hTG#=!TJ?U}h1A#$RmL7U}3sIIm9)hsgF9I`!|OdMX=$k$6)q zLc8HOEz6;a$*=~J^T_K5uh%`@z7m_A)Y;y|q}izTQ&y6w9#kX^7xQ)mzo5qa#ePSY z&BQEsKzL9o@9Am6F`k>Es%DwFW(ZrJ!{FG^lS3te!$s?Zn^YO$1(R1_Fjc(nqv$m~ zvdbi)2tAc$G&a{zdrhHr98U2#X_$Yq*uY8hgcaLBDVgW>%>q0Y!+Qh0>hjeuMQ3qZ zqa>eWIyEU_$^a2Rm2RM0!?HpXU*K-u3j~RJ@VuGeZizR)W>q^pP9KZWOq6i29rSqU zV^qutI9Uua*Y&!MkECkY7YLFs;QTV!Ln{W7S;ys{L-C>Cg~Vf%lC5&b0;T64`JmsU znKJEcwDw=PC==gg%H@w%70;dHO)geQiiG9BaHf5#YeH~l3=lvY6)OfWsKJUJ$&#EkrHD}><2}Ab$Is4b*!??k_6x27*L@rK zhr(u)trYhTCb5KCMO%+6*{7LNBG}MQk%{H`Ye#fP_BsAD^; zNjS%(_!}Zx$w~ten_D2Y);>+3c6b=no=?;DkxW=u@KLV%RP-4X%v@(Z;NR~B9=Uiw zR2^p#RS0<2!no3{A`>fT;q9NQt2Nxy%GQL?uWoTo}u0sV{6O=?Wcsf`HnY=Bk_NJxI{sbDXJFQ1WPk#G$|LAeYL9n2S5a3t< zbPnnZja#h0K;7q6;&fTyVvqYUkL5sAkY3@=r31W!LZH#LX|dR`mJa5?KA3#H-M9yc z_ml#bw~F4DyPxzXr|q{_#ZTlmwwdz$7#V=k|9cpcdS;t=xS!tdmuOAv%4W&8i1!)K z_UG*IZlaPmOLBcxE&}{=h-jz8?oqM)m>wX;gyVWc_zTnOr%zE?{Qh-(9pbe!TZ~#e z<3_By@3)bmMNQRX(?B2@;c?!&aq{T!tF$qvsE-vBHE1OTSq7u#Of^?W@R6W2mX@X` zSNlL(GnaRitDyHx?}(XAWJb#nMsL?~1+q-SxA{y43lfa+Gt^ssv=?P&>tNQe)+y!#@-7E^(e{?*QZhBNMS_1zGPolK4c99NZ4~zdFK>R>!3b}zSBgtX*5{x_Y zD1eZ2$%MC1mF!NDrh#Wd{`*C0Px0kr&CryBn5*q0Y&vdWMxS<9m)H0ya!C+sgn0Ql3>>|nW0pL#JM+}z zfyTavPO~eoe&v+iPwVGa2HFg~7hnu)Z@tpg)+D~@w@tDZ+9Y(NC%_qDu?cT#g18U$f0K_>lVm+7CpG^ua{p1!&Bn22e+Y^;QhAsC<<$B!lg6};4-ytN4;p2O*w1b){xD-zKnXi|_Lz&FcUU(;lzjeXFl zhYA<-76oR$cpGOQja8!0#0Amzcw=MytPheu7h_;XfmbmL?`9@n{_w9bgXB>^lPh zHXABX6J(48rIqiRv9U)_)K-S@E#;$)wGaMb$}L$Ez<$ap`Ey~SjM{LK zQdQfsVLqaK10RkcQ1F;APU~k=WOp8!ePb-1mNFB@^s^Y~8mbeWBs#bftNnK%-UBaR%9j%;MsbX&idM}I;7VHY%IzfiiT2Ta0z6;Ke< zKV^sz_%*zgrd?ZBCyPNjbPQ&Z)F#RY|HrPa{I*ls>O(%czagCvS1e#D9icdsqR9fE z%_|;i?q+Z`rP7#PlI1mGlg|PMch7PDYI1Nh&cvH`E9dKDPm8l7nbT@x#ay}3y7N}o zZ+4HC5-F-r7EJi;A=?zLj^Fq)e6isdBQu00Bh)9uiru2dulYfKunZ_uQ# zWPkE5f-!=Gsgiq-29{xtevBPRQMz zptXI^O?Z^|BjL<*m6#2J$}DWi4Ewd{H=%ISDxXLlV)%mSHCL&5w{xA?>>N*sfMbKs zj`7K3z;_?myn@D9fq$Cf(*uTk%nZxD3whbLdKIs%)4kkNy1aS#p@7|2P;aw|5y{Es z9`WBQ3X$RvDnLLBYMS^Io7v^(OE@REs#Qo%ykj-c&UN<&P8k2vbS9wvG^VRKq=Y9? zJidYOU%9APVc1ic>G*=kj5b{p;qTWUFLX3a1XA#bo~942Xbc0@HDS49*5I z#qOh1P*(Ode5t@?qBo3TqiCo}sa8);R-l>sfa*8vhs{%LwCsDsq{wH zIGW>eWlhLDuw)V(aOViyN>vFn zk}eq2oYF=VO~5nOubfZVENHJW?^pKGp=?MBIxL{;TJ-aIh4}e&ek^!ZKYXiN8#Wl( z@|#C<6;+JYpfSy%+CkOc=rhV*pyH004ze1$-JTNR?5S#$$ylRZIdF!6;N@J)%7(ok z7F3|UKrl#%bZiD+#EdS~ZVw`B3eF7MS%8xEENvKQgyVO#o}Lu;$|Gb_I>;Qs02t(YLs%EGb9Uj$>bQgL ze5mi>)V4bA2av~bBa;%%O})?5!C;;uN%uk8RMl6EM&-@su~y){Ibo}wOTc@%vHy~s zZ>}3Tm%c1n^1P1)q^2t2JnUH(oL1otH_Zey6~+itPzbdhzI7N5l{nN|zg3F^1rZm= zr1kJ!p>QcIePyif0HyfkB+YiCP{&vMibzz|6t+(S7hUeqX8#f~)!aM2Sn;)m8X02V z%1+Xexzv$1Awh^A@S+ti){xmVfC4%W+cd=yfe7<)>H8p$V;krt8DJ)(0y)crJMQV&`l;3D!&(Wmdv5;VMfS*uY~sBX+#i zZTcc$9N5oR0mjJTIbBcS)zluCYzfkBiW<@mfR<5J*~cTO=W4T}%;ne5lCv1UsJ?az zk^j#sN(}G4{1(R;3JvlOPtc%)uG_h{z3YEmRarGk>txl;4DXNaaJXL3|Hyx;eFOT3 zZfFom&!{1+zq|6umd?}c$*K-qq#%bO4%DN^-PA6YBTyqpMDZ=!ffHEH)gfM5T4&<^F)9%WyCmAUdR49@uc_fOn zg%<~o&j$VbZSLHiB{>U*8zvdKC9O$BhwRHKk<|wfY*HqIZq7g-rV-=Uo-oa`_)jT-RYAY)3i&4BICE>L#f1xPkM(V+x0=e|A0ptRb@)mCFVKhvS%b>&*Edjou>k7qKSCSZ=j-V!TTO=56 zBPBi?B^jrzmz&r4pWBu8ThasJm3c^%f{5r!ID9DiKHt5D2=mu*b=uwN8x7nyW!+hl-h1^AQ1=D~{p7tzY zF;IH$;!)bZb~O8|gP`4$b38yC_2gQ=Ek2Iq#zeAKYk#2WX?}78Jcd$5UFeH4d3e|y z`LTOAWKTY`*Dtg&xE?cP&vH%bmsP}_a^38-r88Ekv>+|F-gWNLaQzFOYI5z>rET4m zE?qRdiig{GCUp0VodSzmp+yyZ3j-9oG?n}f^PTJy8C^>_R>*@TOM3*#;{x)1QrRn+ zd+VdYjP5Bj2Ez_oKLl5h2gPEEXAfOlwOP<}kMwzG84pg6r@z?d%JpAf5qQ5cG0t`d zwQr9Q|Blt?4Ie_2i)bw&);ENVqWb;cdZ*x;WaGIt&F=|fZX+UqK;(Mh&qE4n)jhrot>B+*?WS@2*`P$4>ZqX-MFnAGZE=p{%7awk zI00$I3hyB=YXcc{njeW(+d>vV#6B^L5245<)HgHZb>_@>ae8+cB^9iOKZ&Ra@N5b$U`_ zGhd2;fDR6bYn|yiG3|KEq+=@sKE>A?g;4utHIn&Q!$RNvKE+yIF0~KmLYnx$m2!d< zmU(V!$*ov9k@pF;-55&MV1FC^qkxaGG0jKur213=J z`#F1A&TV(KNZ4BcG6_E1n*pNel@1$LDtI0Tgxx?<-x{&&Bl+iONED?r(*;i;hGZ8f z;8UtS>v6E3^Z}JMKr+6hm4TMnsVir`XIq=qUu3gJsVo~X94H{QfH0&YpEPFY=oaHp zs7;_W4K2iCXn{5LJ3G*<1xa77#L6YuwD)?XR2Tn++})2z31t$YEc;&b|;5!6s6rZKE^dIG_0Dk~?fk#b*ope_Y; zOY2cv7Ir-s1IDhVW%W428G(R{YdgY^D0UXzE%G~fUm`I4Ed`V;L?M6q;iO^G*5)vU z8Z{!OR-xn(vX2HHB?M76sN@)PxWlm<+mAO(*~rwYVe1CGy<@6n)cML|Qees@J;2}7En zF_Y2v>XI7vxx*f7Z2{%MJ4fZBX1)?B7EWCe>7CU0uyq{~0N3s5VH<~8;KZY^ zPvV%OpCsAI8?OP;$0WMHAa_u!c=WZ|wf%tn5wtsAdBR2J*G$<8{Ujooj&Gc||R>HEb?|(X`BjnEF-uzC{#TUK2lHVN&H9ZZS(d zEW{se}hh`W7#5b-D1T2-2yLqD0oqzqVh3IZF1|?(B&!L6<^(H3o592vHuu_eV z$E7w-6Z_9-gwFO3=xuj0R|?|#kF4t{JY$_3weY7+LAF^1@L%}-j^8!v5WNHQCwVG6 zF~=XiUfBGo%o3-@K)weZ3fM`HMw>L|6+hLZOx)AO6py!9CPe8@@${B((Kduvb5sJg z6o<+si1;V%CCgP1_;a*m4KuA>rdgd7gDhfp72yRodHvAaBgG$;U&txLEWNUrbV;f1 z6o>jQ=*SH((?s&Y-62H#1Z#?7-C#sQnmtchx-Qn}pRTLyap{F;2;l3ruxC^8^rKGV zP~2M${;flvLex_pkq))aiR*e)JN@TxKo|a~+)VWp{-O*Nxvk3Q6oZaN#9pK-AjPlH zjpVm!t_t!3PLTZorNsk4VFi~>H!u%GLoYTbX4(@WjNA)@wCSB)FeAxM*1`Gl9 zEozSFT=KAD$Y}y5Xgc?%cw7VzbM@zeeN<>Wil4dmvIR4FjHwWDn!i&H_@zD(Q}6R_ zHFpGVG8}6{g1>P+S|@Hw+$t$-SFj9C=pZx4w{dbUfCqakf)Hl&J205E1YY;Q)&^r5!i`%IRD1I(v#sB!sBv{Fv zw4jYx9gFiS!VmsPg`Xl=!DthAJ(7^L_K(TwWy6wE(HoNB4kV0Itfcph68oD(yf=V! z^V2B{E8x%!efz_BHK>&B1(qPeFOxyM9G%X@YrTudJAHDf1D`G!vBnP7I^9q(VEVa) zo{R!tylOapVX6T=W3a zB0gF|rio+@)WL<4ymH<-AdR&^qsH;|zYedQlp`a8Ea7zTK!!UvJV3U$5eyAuI*?w4kvby+nBh&FO4&MY~0FTA3isl@h)vi_vO&7vo4jW z=KF#dj#R?J{~QqPiNV|<1hzjpot0w7CM+PLa}Uf9hz27a4r)iQ7%)O)5)-|%Crn3H zmU#Bela+b=V!);D+yZx)t$XQRTmaslI)W5Ob&v?IF_Fc$7B5-q>AAgNa98Qz!h=jP zpPI_gB;%U&;|q_VB$PGRV@$S_O(x{!ldJ zh`vRj7kFIMa-zydpw3$d_*c@rVYD00L}S2+u3>0oMd+qB#8Ly$?q(RGvUs-KSQ@nr zg5an`(@x~q%d+IDvB_ZJpcSdDOl!j2+0xkS*ps_Q1UHW-*y66o#W7$__haqXj;2X# zWne93j5miq;CA6Yu=i$9$58ykc2>4**;_|FbX9{rHF=?>NOrxYI1^nafnF8J8<#g+ zxE8%IUZ#pDL6w$SLtp@P2z5}RW6Svd!#QX_fbw9AUZ0Cb&WN=*B?j&YZzwzZ zhj*T<{J)vq?xRzTOTf!J%e<4=rzRmD_Zs`F2m@j`^5byk-r-0A6OLcOm?v3deYOdp z+Jshg*_`jhEW^=tYN+Fl4iiRIh(VX8HZLF5So_jBswUK<$<31*h9b+5`^bJ8+ZBx6 zDeJqtP#k$({&w02##;=&j-bSp)a8;qgI=<+@Ien&exsc4O*_lUdy>+o2_6bT`G%EfT`J?`{_zEF}VP#hTAucHMDVTUYgA#zY0VWAJUu$#t za_0D_hH`0img|Ydgxuj0EY?&AuuktbOX1BM#uM)`Y7eC?2}i6 zcQce!5#>%ozJqwlR?$wn=~VZ4uQU@GRsMHNN?djqP8_+==e`}+PV#_f?%SO#Jch&{ zbQ1j=UyoLhc^EXDGNGlyoujsl!+ue*q-Uunysp{g@ucufa$) z!wpp92Xs~FYPG%mbj*LZ21M^HXDL_Thw>X(ix*=A>8hqZ#PsyA1+wqEFlNTUQ138~ z0euSLvoQZ-GD9ejBOkv98Kkvj16J_2O&;e8Gab*}J(v;$eK8A`l$36k{DgsGDg0-h zr;JKW-Yj4cZ_>vJbWoWs^^7alsE^?2!A&@j(Wx> z=8Fr(d$PHa`M2nw`d3(Q28JO3Ny-b|vg@mUA&TQ&x7%-BViaJwDuv|OP1qs=BQN!? zjLxNKnbNvUR~b;>&!wC^@*z-TkVsZ17%;}j7zYUBG{OB!l{M-q*>NECYITtdEF0O1 z3;P^o@P0+d4W+!|AkuxgNhreutr=*nk0u~WKB=^A zUQFMipa`58AMb#RaPK;pFHME^%`2$najlnJM9CUOuW?))9Hc8l-9QN<%~T6)nM`<%R(UPaNX=jW71Uwu0u}J564Tv zuuxTcyl!MH`UcYHlBy*!oid1CGK>R1lu4MH2{fBNk>KYz zsrO|*nqga6#YqTO(D!WrCDMHlt=r`ibr&hQz2xp%GRS9ZTuTe>@v%;? z0*Z?_TZW2+$fv8}eoK_ey|eP6R=uBAc_*_SIF%M2dYfD0uX+iB*l+);I#k_#th*=n z32-syNCDT{%YW(X$P`*2jE!PNjDs5vk8NyBoDTbfWsalB0ri0~JtO<+h~d?))*+)F zchq^n>QXTt45`giq2DoF^#+I-R4E{dlamkG&?Qe94yhX5qsf?vq!Y*;?5`F7?K$H6 zk#OHv@fDJ|20PY>B>x z*Pml2VVm0V8s#qfKG9iWQ~~@sgZik4c9P{ppu_0=hiVtDu! z!{*j0u@{tF4G{&gKN!S(W*1aEkEcmBvEqaASAGUcg>Q<5jqT^k{%FK9w$H=?#6;`E zZpNpfL4_eD))G88dm;fOG-akAcKbNa&%Kgb{>cLN$gT}*ShC8-E9Wz+?oa%*1VT+x z6;*2@20NoluA2q>y?x(qQ%;|(7wqrV*%h9jsfu0~SkSBIuQ8tMi-pp>ugpnAa;+{7 zu`OUfabDytejY2>D~{o_@lIf-btu$qBQB+VbGo;4-5*b*J}gO0gL6t_di|e*;i7C; z;|NXbt`LI+#IUF)HidI+eK4<~(xq@P8zWiYIY5la0o$}wf2rcjx-x8$7)=Gavq;Et zWkw@dt(MXa^>04ROFRGpktfT1$E|rMq?&pJNPr26_rOTUD}2XmXkvdvT5!?~%nSI!cYMi$ zcUDkPeT(M)buvp=ps52rSq{;M>tFv=Y)DQWKEy2>S0tjiFEq7g>TJjBR=$v|9m5&b%Of;z1|> z&6sDcmBWqJO^yzzcuo6`;(+!>rgX%${(^GYV*R$(!oS|vl5Ol}rm3MB;ONQN~ z9G0GPF@)+&&=v7D!{wkjmu@PMH8@J~8G%r=AXvRKBvMu3^y@r6FK=EW`7V2>uH2rp z_f|lErM>J=$Rw>qhG=lixjdiY!Mv0NL*{N;esUm|c?K9I+vAexBJU z-JR9GsfiUk4WILdEqZU6o=JFtz#XLtOwxGW9_8D z9FKB&GKREvihP>T51PObPPs0nP0;E{8%n3!Ad)CRUY$HK0tJ*C*h~VjAOF#p?RwL3 z2ydbExtp-)!7mi9WXO0r-AC$auqdaQ((qM1fop~sKDj+%hvyS!84OF z9&78Tq0K4ny^B5QLCxvw8|LxTsZi z)qPPiE(N3c-8N6ou|HHMv{=0~Xo;o!Mz3gQMz2_k9gQJ!n^@1p0MMFe*^doNuJQml zbN!1oqgrT-kqew;9Xcr?D3iEg{wNKD2=Bb2?1Q0GCvju1tx4ERN?k+bDg{ZYl$t~F zhCZJbXEW`G#NOVIW{KdA$o=HeDS?n!(mIxq%wnUwbA|U=Iy9w~IgNn!2DFOqTt|=` z<}N$ap-^i7L>W_8j1G2TAIb87!ew-vrd7&-q%^EmGW4|jK3w%fZx(S&1D}Hb0EQgw z{u(p*=K1~dda2O%czknq_-Tf#P9+PZm~sPrT3^W?FhBZYD?c&`Q_ZG* z&h6nV7Qb7d`9FU1s1dwU@4LepF;3~}-KWIqRD~RT+w{kH)Q!%??0<8vi4tH^6Lj0H zmzB#&tH*Pm9^B|J;00si80tK%7hn(c6IDivn+r|`QYMTvPzEp-Ny#3E4k7olH)mT@ z$dFoMxFdN2g)xhwKaKA~Vn#|kz5^@>YfB!!l$y)VK0!zN=SISfIx0kR{RN3rzXgq& z8X-(JXE;CD7rCSky8b2YR$Cv0wlk>R$L0cUfgz&E<=j_LODLqc)~kCpF0{xHKBE?*bV+Zl!dn*p0~9)<6TUH2 z<-)Sq=m)D=n>2BI9U6;8OqL%Xi%FoR(LGO2Z_e0I2uhl*?iZQ^+}!+_w4y0gZuse3 z|5Q|J`>0wUtl9=>-zK z)uxHkUnbdJ@MR82$2*7o31E3gbM2vbt8jF}N0#@APLvEH0q>D>GeUoomB@*m$#1t& z_?lwp6vx#lt#rSiq&}2McZu$+4DTjZS7odI%{PfQHpJFXhv@U78g~lrO@w#@RK0f0 zE^j6BV19+Wbhvoo`ikb60(ZuxHCrnvZw?sA*ucs6BE@T!L7g79&J4udiYEMxx~TNH zlhGZDysM$dPybb!aZ>ZC5kEVzMaXHG%2Gh432>d|GpbaD8ylPDQPkv47dC{+l@MBS4!mB%U0Bhx_xdiCV0 z(Bv=v=~NIA!uPhI9FD^CMCg2)LdMuHMhaRfnv=cvmRDhWuc{AU259}`9KD_Q&y)?heMWfFM+|ApUhYLf|pqi>eyvEW3(L;>~3}ed$2dQXrc;W_EN` zF#|jM%?lcFwF>T^wN24vHJkXfj#ImEgyg&kER@Pp&y-zxB+|Pr!|m@NpxwS7YaykZ z)ROyuH6~~WR4*Ho%gEcI%q5UPhyAEuDSI$X{65$>Dcl7fLwLpIac;{wNmc(sMa-8G zs}p$yTGE4zNfT#ofqYYDBVy?=)!(3>VW@SW4^p%)%G&8W0?5nf{^0@*}(;N()5_LseAEqA1_S$;Wfbj~?U7a!6N;ge56$T#iUOVdSt!23_ zYNzu%XPu-+s@RcF)KO}-fq)WlXu#pt>0)0~flxg`>9dT}m<`?s5cVRB^~Gc2D^{S9 z4ek)LnGAuu*mFv&HwI|L_v+7oiAt9oE*4&u?uFD_fk_+mY7JFDzoXY*p0$y&s4C(5 z(>zJ09rW!&2l`?WA{lY*Q0P`CSG2jSkSBQTTYLt5R`E6%)QbM(hRQ-mp5*k$7Yo57 zRiVR&sEC0!kKYnfIZS&EVkE`^Wj%-cy>4q;4HrYdDN1}9)q!!!Aobb@wawUSoVWzC zyjdI67m;*|)vX2#lS#hH(l5OIkz_$*K$B!9GI9q${k!lM`VR$DX{Be=brv8nUkbNE zj93dPDMkrYv);!wN{^X_$K?quR+T|qZyq{g;iJeonBLO1ULAThGe{uAh5k&av-nsM z!?xg91j}~n%4%~n!%3TnV^uq~eBOrNZ~zf$H)Y#Ab)b=sW6>S_A{yNqWFOO=7bm=N z$F>}0e8fjB#K%5z#kC-G34E+K=2v?Saip`?_p9gPm?T_o z6?VUOah_h;f4X|hDt-+V*iMigM9FiDLnW|Rg2FUAD0eSIfzC+78F9jkbkp*ysabA% z(y(PwWv39)6G%C;0g;{CI))JCNj7dFLP-|CdMZm7snqh9AuM#SZQw1wk+buPe1w#( z*{35YJ~ok=k?xn4e!+CERo6LO1Si>3^I$lPCqJE@1Q8c;(|u=^oS{Y)CWY}#nJVDd zs9RP`vo`AKZK=T~ffbtQ$ygGVRVZ;2I@He4EP0)QnWZvZF`Jp|e-<4SgPR~!mm)ct zx`;Vzc8hh9Am>T^9&$mLXns#;@via4;SB8{9qPa*7H$+^6gq7(PAKt+=B{aV)BJMj zu6@TXTwdYbzyq@M7H=2hIFAu9Ty5wN%4SohHbe0PgMMunt?d z74?9v17TnU*4LL#CxBb}t*fWL{n@s5?tU#2bA9*trV&%9B@4goi+A-or2_#c?1WoF zC__sEgC~HE!C;l)dxGhX74Cz=V;Vxei!&3{OC3SeYbYF?8qNhU9pX4dv8l6l5re)G z{jz@$QAI1X`siKC(SksxrqEN zHLPuafUqzcCl;}HNLl!L>x4_07;ZUr(KHa)qd4b)Tay|>C^IR$?PM7cek-g+G~jt6 zhgwPGzseO>cZm8d?ICYAybO&v5W&3dzAnhVPOwKRLN$AB53{{(G)2{jp-TC5a#n3yOL6pZPZN(}# z4F{eYe^*LiswD^-PlinF!?~_$w{scWQ6!FgoJyww>Z05{+Bd*&F=H-;a4Cf3wT%%v zt|dIjduUKW>Rb$o3^z()%~fnz#StdKRg^XB1)7aUZ#_S43wh4Eui#M)1!Ou_IheFc z4wO$!ZGhIwqjpTI+unv zG^rO%%{-8>kznl2d%%^PqtXYWnnmOsQr?+dO?RdM6z$`oQnmO4FU2pzDo`ihZ zeZGR@RCW$O#()cx>n5_xSrS|eo10axR>l>>jo_>tJCEG~RMZGe^K1W&pz?sbJgQC8 z@!7bjsxP?xMvR(+G;E>xxUDX87uFEE$!XF8o=KQ=l_%&!e?NZGkRiE;qFzBq8ZH>o zkc>?zQKqr5-z6(?ZvQDl@-Rfs=N!ZNDnu zwjVc3vG|&zE0r7kxq@CV_Bn)*y@8-<*QnJ!-FXZC>fM%&=m6`7;Ud>}1PQVz3&%~& zrBB7$%ki{D;qpqzd-SL*Z&d2lV-Of-?<}5li;(5=#Nhk@zlCpX9LsZtYu&=u>6vEf z!4SX3o%b{H-RWv`DWKLWK&miO%z(e|qfQ~jJvSJTRqx>aKOEsBdn2j|osy-dtvucg zZW|0$tM61gk1NfeNIx`C5FoIJ-R;h!jIH_IQd}F92AArFbK8bXKp5#&x`0$riS1(G zA2*5I;T{GLq4Yi?*DU3HS@2$-6@FY`t$B&_9aCcoiMfH1Ds)q)B|5N~ws@>uAYOg7 z+-!Rd3uep3z@~`?%1;NimL>E{lWw;v2{c=vdHglQb_aT5z}%G}P4=(oO>oF$sJ&}z z(~f`}W;h=s)&$dIjqEw9FB_xrWKXNZRf zu9Jz3>A@RfP~RwYH=&cu^N&?pI<_axNHMgL)GqV94Yz)PyZ&}vnl{I)qs9hEyNw%V z0wawe-aj^6yF(3v_Y@cM_L5|nwe+5Q)0@NGRQ}jz1|x*m{v_DH` zQqWcRc)sl3NL#wCi5=N|zh8JB&17;oGgPe%(VcRW5|Xf>>LQZT=SYh>r5hQwUhFU9gmhS0)pmpt2whv2(`c)BRYzF*wzeNp*O@B0y3^g^ zr6uA-*xsz!fXd4uF+2>P3?mb<>#*Hv^fu_G=2v*fA*HMdl#@ZOE2Q3sk}IgO6M~(p z*pej0lzLZ4{94#*7;ItM5TEVR=MN)xprsLE3PMqBEJCAW8s?m`p=!##z1=Wi=9eKK z0jyyqj%-m-#-xT*RVrd$b>=|cwVd11!C1@t*PIn5Q=bIRKA3!?3UnECAt)c@G?!_RTU8^cfIzn$G<3Vdb%+-#+dQD+IjQg zWb2G3k0Eky&^lNJ9{q)lgI(dalFg?>6RUA0E@U`1 z=E@i^OCRlMwddsJQVc~-wlWHTy(lNveHGe}LL$`>b_iJF+L8%yD>sZz>xab6 zj_#q_H==!%3zQu>wopHyIkvx7Fl||t5_*vrVHkVhrAAGMQVA67+;Td>kB15K$RVaV zb^GFw_V&)oV)&uDWFBiFEXS=jupQz-iRWP`aV<6YSe)PY-(u`I%R{lF>95F&CMf~9 z07hSzpzDey-n}T@AP@7XT!&~#Bg1qo=m*~BFk=p(XHXXQRjfm^-fr+hix2qH=>@$< z+$KNSguBgZPKrh(nFJcP9eQ=QomDCyZWfcnvBJdWNeGWv9p_q9E)-5MEH_Uxl`AtM-Gys6$*6Ddz5v=f2jOj-@I{3VN>v}z5RmvPO&a!H5kquKv$Qw`J_akgaGRC<6(WS=vNQakzM(j zZ(@@6x3BnceC+&3I$G4BrN8eLXSU_Vl$1(63(LH-0YFXyIHeVSk)XxD_0Bj-%smWT zUy<2mG+Fd!S#1y>UV7(|Og_cBj1wpEf6p9cWV?nr+? zD|(l|v;osKzq#A#O-@3fF4Ft5N-xQo`^La2>K~VDT7X!m4JB}?rvsa)=EA(>&c$g| z(e`7%>qJXake~(yKjoK@X#%V4wEA-0xjnAT886-)xB7%Tv!0e8bC^zq=CDCnKjt$Y zM>}-O94Ixra5FMyD1F`6CBON@U_*r>-DuC4iDmpn6v89R&(3;$DR z@2bd0IG+!5&o-P6RBv0_@hnBgRwcmqRXS_n0b~rt1cCw~u{Go8D&Fu5&a&E`S8#U4 zZHigjQ71%eF4ieeh5T-qxC{d|svlBRny%j0<8Oqmx^=Kmz$jplQ(hL^zsTL%3 zO;4$B0#hgG778@nf7GKmF4Q4fNG7^X=RvSV!%!fV2wWgXF@Vgp;mRJy9r7N@^Uyme zHaj5S%gtONLBgy=UxAbZ0`5a?+h~e%z@_0sY^gJK5t$?1sb8$FoCkzsgvIEtu0z*- z;lZShmxcEg@zpK2!Q^9f5@me92ohf~Z5LI5;(S{X%_9$CR(PTP%N6ju$Efr{hP+bE z+8~NwtOc#k`I=T^ZXO_zI0ZzasY0`+mN2tK;uoX%4$#x9u$k$qi7roIYXNrx6ARx%op?SyeCu|E6)uxrT^kP(1{9S(R9D^@KP$8xo}clOrf^< zGR*@FL~)ZQ#&SGU2m_NI;hoe)U*hsa4SDqfD7KDS_m);=Av;w>1VKq6ShuT zqywX)QfLhvE=6;~6eVV$Ew}n>A!qbj6#Uzqr}Bsv1fPMnJjjF#t{|!sR<7X8#gc zo-3UHNuXiD_#=G5NyuXi&Ihc}n1!H?r7;v&#WxziM4l_Jdm3M2&6zc*t%&{X{B=aF zSoRaUmaF~Dc#Rr*86yIc8<2vk@FgC;HG z3zu>h1iJYZBq7b=8yu(`g0}A~>neg8rJq7F;=7^;#L=G$yyw^`tCZW<87=B6bsJIg zl|xWfqZ^_w@K(0GmFg!JsDN=OH(dnTlOw>^2PX5qe3X&Sr&~l{OlD_Vo$MNi27zeX zu=m5;)iK03ezD<9>R4{Z#T`F*nh@RORy3+~&v1q1 zT5`drR>;xnd8d;|b||bmta4#P{G}Lw4XjgSvSkAj?%25QYX`0B$H=*YYBbm@vsMH} z5`AsQ%3F8=OAQv8Ks%Pi3%>J)BOVW~5}0f#wrlw%g`Bg^tRKXA!Vx*>Wv}Z#fgoy9 z90Y`|AP2z@`aYx7m5OCRbzzb6Ql7$%#|<6>I1@GvA>yV2998sOmr)S?%%J1k1-xV& zfE{9B6*vr%$1uLad+f<@((lmjcGWUTI-8|b?=DV0qnNrXB&7L0Cg_Lg$a@nX`1#b# z_zvff7e?8^$IMhSse6-&=h9Q+R?UzwA&m;LHN}YOc5z+$%Uamm?Tt1oatL@kBM03= zWyuDXsD=J(S2*EYMziM3^In^Pw{# zZ^E&R4Ru^9S*uEMJ8Va}p=lxZ*U;U75n81qL?y5I2PG2{!9;+2FZFODMT2F+iC{?> zSkReCFBLu0Xa_4uNh)vzcZYFbYXSj%s*E>b;Cb&AOnqBJr8aVjpib<3YmWJB_9=8T z!t%aNacW=0zFk;4i}L!X#_&+&0{~0g2xleOYg`+eZI-xs)U;SLizrWT{Vo#)#m&j? z`bsoKSy z7rX<4?&;2G%~g)9jw$70G+`UBo+m#)27TE_wFlYPjL6?-%R+qmRTI4(g?z>0yIPXJ zj35~vI@jw0NOvxXy#J=*maPakw0-(1CCjv*Kc^rO#uwID9J+ZMeO@Jo3ECsDcpZDH zSv>u3>Ie~xg{@R-`m7Mcvo;#(s_fC2?ZwmDd_$IHxN6I8c%k7cqfK};@!;BQ-BG4p z#{M+CBoKYpI?bm4T~ku9fcd3S+Ck~R0M_wBaPBZCrsP2gDBeP&%Qe~N?P84Iuoa*g z)#?}U?g&X7mJVW&3-MXbS#F6|DVVJc9swLxH6hZV8^F_xnk;>(84yHU3af^6oh{X@ zAKH*RG!PG`*9LN4!7xlL4^9LEOB5;ZW|R($0Vi(_>jNAdSXS@?M-K-@ z9=B+1BX~|pXmhFXQ{hlapL*aVV?@jZHZ%ZDOwS)gfKWyh?GiESYGe59j%(+Ekt6mB z8&o@Rszo~-#yNowAh2e8!n#Z!#*~Pim`0tnmug0Q%_KWs~x|I8ywMzr4*-#2#4V zI_)iqW7aNi}t{*Fk)Gz~+SRN1gt&iINdMeP_e>z|_e5-Gw ziZoq_S!pHm9f17^I_H}Z!i`A^#J8+WDb8v7&4LN>MTg5qQq%0MNvt2W^2c@Q_*65I ztvv-KU+}n`g(G>{jITD`a7@F*v;->$H%w(B@oZ);aTo_p(yWvbBU)br3Q_C`aNNsp zLdH81?~BIZ6>NRWoFrvxbfpU9!ffgOA;Eb?BOObjr<`u!hES1TJscuDHJx-jyELuE zLJ)jOp4YD4Z9!~D1mr4;F*rz*B6r4K5hc^%F$||N1THp)3m%~namqFh&hn@?ITyFy zs!BwUX_U$Bamy_O{L1BmW9;7e!dKPo7l6L2s81ai@PN#v9(>Zxxb#lYUY8NKR5Ut! zUFs79b--En1j%yIUPgba58%{CD(}1ZQ9ioaj>r;!ZcH#fnI=}tSg_h_WRS^J zoH8oXtYPBHmTLpzbxcdgHUYAN31er=(WBY5408Z^SeDfTGKxqAoVjtmq-YMa#!h_w zYHmZN4mELCnpYmjeGMv9ujl3XdL$E_RgX(k1{kKpK3%(JW`}PFzn?1JM;&Ka^eOzE zBkDRu9h$!uBBU^MR5c`AB`JHmsqQhbjYvwOZ%RaB$ko=KOYTQtxlmQ(`Y{7}+1Wy+ zSAwGUpUN=Y0 zCGa1UjMNQR7m|JDEPRN=ddyXADq>IVUcEI0CB;J1J+`td8l}z^sXv=(=wdWJa?@yA z7dbfSIClOW#tX@&V^Cr;t*1`gXDdl7vs`IFL@lq-d^oTx?=uDCiYwN(0t@R>^s*~> zg9c)(_K7;bkV0c7j<1PG(FONknBCx<_6-QXN?e_&(kj`ZOvL@)4iCy-%Enhky+(%u z%!oId*$Mr*kL@zj9uxcGQn?%+-s)7L`pXx-Ufkl^ojxU+)=R_k1pU!RTgxf8y9EX^ zAeh}ipFuA6bT{zQw-Aw#I|+MQVDNh48K`O7Lz=e5%?>>A>*4>gVRcN`iipzX38_&h zFCQLL9i@GG6P8Gue?vx>GowyVw@d_8m}mn#i0O9G-=!BF5SL{WEmiYCDITFLzRYd} zBc*fQ`=33hGN&ojxBhOBX{9K9fD7K2&Vrf`*vam>Q2t+75h{#RKVTr7j0wNLO^=%L z*%o&?ysE@jt4Lsqz`P@?db_Z-{7KJYs1Ywp3CTW;DERY*H_+AYkyE9c`=h8Y_Sj^d zd}xtZA{{&xw~uqpZ=KML7Ew0EGzd)S4Rx)4_m>KB@(hhyA-|9TrAkQkZ18 z>o2hgq-B zF=;WVXTx0*7b*FQBYf^JAUawHVo9uGsouk3%un!FWUvwMtc%h{+xrNiG)s?;XvKGa zQR!XWRbPA&pOFP40>^yg&yR}AKnV0jp&-^0XDAGg-(gFKQ>7-qG$T3ze5|qmCRVkk z5hr*aYH))J>cMbwzNnfXuS#LC*A8R#$`R99_M6$r&Sb7fvM^Kg0kDgJN~rSHSZBYR zE9ncTgJEU2G8Se2=|ZL|x-mg8 zV{^euRlIT9hQLL2i$wVp8^3CM|67)NP?@>2U4y|rIJX7_u35wR)=T^f?o40i>X>!P zZzre!EM73M#dFsp{sE@?;ffoi8L8vVFe1!SZF{<`(K6yMjs@0&(#w3dtzj)q+WT*1 zxnCB7$}pO8!7}IXSykXn3t55SXvLq*roG+++-^bkM6fJ&5s&+=uE=w->+R44N$Pf7 zg3c7q=noTan7Bz*yUKNiP1Q4?s_lfq`q)ROsUWtv_izW<#eKc0RD0OZ zN1FMaD5lRGrqH&a0JM8IHPq16mdcpk|Bl~;o-&N-4;bmta51H1I0wMc)j&>74{%DD z{(26Z41gZICA~&TlY%bNh0MxOZf%i<6&O0SMbGWC5A{x5{{89*leDZe7kEn|-)Nz&b$5PtQ^~xpNoEG)pKs_?EvRI8fP4!Is>iF*`E zc7cn=5!5J-zMo>uZ6F70@s``Ne;Hr!!=N;GXc#Jl+j3J6$v28eiH~i&ze>wi_KR57 zRhrEoy06^l-_6Vt-P5MFJxGRmL&dKNny{oTHADL>>)9WU)3$i>6`t7*se8QK1T)I^ z23-MUDqJ_m{&E*qxEqTmv}RmD_#FHJkih4 zmUr?wZxiCx!K|Nf-r{i#F8tUH3}GL)zjGwe#ikIUf5l*fO{Q28SZO$BmREOcFMx0% zyThTK{S7VM4Ymj7g_W5rlgXI73$-dw^^t-NyMKPfC$f&mKOBU~k`|B$t6v3(W~XY3 zj&q#&Sfz+>2rzQE_4=xB2H_>Ti&CT3UalfQnD95O;Mh2DOHV?GPvXcv;ifFhG;D;B zA!|)Hi=28&O%{R0jeO(&cW_JF$8f6caNL!=;7ws_UvyKaPg)satd(9?>NV`Gl-QKd~6tbJTyI>;{kR784f;T6k4ZKY>(_pD@#+&?4#Gzpq8xpyUw@HwNnTwQWB1$UV$)=((SPcIFnNceF7tt6pxFOt92XqoAT;CV|Io3fNvKV%73PA&d>fFVINe-A(b zJc9!qLAi7ld7RXW^F5DxG$7xe3H*7Ma;6Q*=ALx?2+Hq#8+Oc4NupT=c)_Es3k0CG zAPP-1<4ZjCBDS3ejGAin!EvFgY1BlM}%=2ezV)e6>v4a?_ki;c{|dEjXXj4!xXF3qA`uMoX^>x1L z>FGB5lgkVrn@9G_ijoD)-H)$!7A~xcMG$wXeDx%Kp4>slnv;Akc+s_;ou4(Fcp0o} zigkMr%syS)RXey&X9OA(A~%84#PWRd7X-6%Me#;{T^#E=4iL(k)j(i1FD~5hx+Jwl z-gb@f{9s`GjAr>UVfP#@;;@jS*RwU}E?9@~(9(nQ7Izun+TjzU^Z72z{Z0s&$J)p^ zY_OV9AZx4JY;v>#Xvwd{`J|+SO6^e~33KCcpFXXRt^&*W@+JNNDyIpnE%{eR9#{|} zndZ^o>c1tPD9ca{U8YfRT zqWF)6cH-JjPY$O$lyD$yz99|&jK$0S4vQi)uB|AL_m6-*IWnE)K!}vD$$s}V?=HxePPPbyET1<6@ZZUl8Y)sT3ay`~}H*#+=AQ{q@Lg-S(%R=d2U|3{|Ydq*g zCO-<*8Dt8}7i~(Wyl$ENR?;M6pA#~d%reeL>><@gObUfAO!TfGshp4a*E}mTlf-~p zUgd9VGH|@&vyJih;QdHADf@zIvGm1!00E)gs}3$0)7lM2vfbgZ`~=5PI-*<86*~I4 zGEz)_KTsi41rk7(?0=5K6Ki8g`SP8t0UXssdL!Dv%Od^5JhN^Z0Wo*l{3 zLat6Mscsv;^Qwmulb<7Gn+{?A zW+;#W$V;-|n)mr+88Yre5$A*{FbpFnm4~}L#tUe&)VXR$cXA~-$nzt{WJ>n|yx`&0 zFH|kareWBm-eE8ujk)*nvypQOU0m4Nhs1Rxv6xjkIj#ZH{e-2kFWmkv$z(sS9qPrl ziGD0+fdOzTQ1QeA6ns-=%4$-m$8qSdI(!8qE-Epl;YTh4jNE1e+gCp=oWzC9Zc3#| z_ZvT_1rA=4J&ZJxT+tq1zy(`VO_x_ZvL*ry0zUB8`vA`jFn@OFYaX25F_jSkIX{XY zLRdChA|u6e_iK9YbQCcvh*D;2udG|gG^RdXpMCZV_ghP-X}k_GroFug$z$wYDlX)U zg91Y7e1?i4&x46Jw-+G$yPQW393C`LE?&cBj&AB=Li?YMn+QsYhk3qg~? z(V^CB9YWqPaD%Q8EL=XdVZp~*TdnA+rO~1obvr38fm$L2D2(&cFkow2z`!5`Grb~!?5H@6+RV9?HW`Cakk75#Sy#VowvD4b+Zv0&Y4BPVcVTBwna7udxXx3%2I zB5a2D1fzyqjU@n*L=9oON;PX_NU>eb3Y=%KanQj9+3Gw$ftIIb7deV<31hFH%ef?PYa7X*p!EU%;S5(%1mwvta6 zkK3~LdBv$bq{hmYsP_~D^tvvL5xDL{eIzfjs&UdQvlXEq|)h<|^8Epg<5FML%Hd4_0jRc~i#Q!35fqgY6~z znQLX>Q{?#F?};ho#8sbz{JIz1l{7yOV?xQe-`&C4R%Wl8SEt}w6o)w>>-GRu6iQ~j zc{%k*1mcWQIsDNe8h!;!$khi}Icg7tgE~|sAp+W;?cX2~@Jnx@NIF!FwvdtrGM(V_ zz7XGYV_S^H@fJ5aAD!C_Dr-dcRiSe2%=;D1U`Bu{NsFf$y==ue)1#My=);D=-P&l5 z%)5pLIai)FzrSbzGHu=S_s0t2_Ay<)xA`)B()a2k$jbU^LUTM9Ain^kgfty98h)`0 zkw4+(WBQ9M?pz8mb{LG*`K_{e%{n~~2}Z)6ks27p!5Zjf!lrgH~QWU@R@6FlMjn#B0JlO^^sAk7^8=!vfY z#rL`~Zg_EH&mO&)>e!+R=WpnRKy1c!AKSZ&bo%-hVD^-S@a@>z2XiDNKidIwcA@{^ z-ctNwHu?vaszl#CZ|%ij;QY5dsI-$C9owx!$+}JWUn?f0OUq=iWeJr?Eklkh#_7fF z%MDRWw_dz!vlT4~SEZCgP|n0V9Z9L{k4tJ=pB&O5>LhW74ylb}Z8#pra>ml&-&8NS zP}e$c)wl?`!+-FdT^9M)I7{^+$axw$q2TSriK8$F08S+f43Quo+%#olV(k*#zJxvj zo-hZ5+QSvaJkQ;IP{cJ92#Dq)(@YuuwBM1=<5C=^&a7UycvsnjXpeA!LGl)CEw!qG6P1CUp*E&8>?IH-dLby!2o!2HiW#Ydu zj5+mJ&On$8c&p-iayZR39$C{*N_oz;7$->=F%qyQ(@S|v-_ADzdGI`3X=;~a>H3+DaEPs2 z#}^w*JQ9pRwA%oHbYP(PXe zVAAFoXlhO2nS;B(wGGb|w~$Y1$}6|WTUuxVz&0BGL~WHZ|NDbbY|u((#Ls;pd>a37 zA{!_4H8}bB=$S=2xmsd!6|>z>lK_hcEA&!*E>lXcEPn>M10I&&HSUpqNQ&T0Sey+g zzK4OXa@4KELnI{!4wy>*>>KDJfOjow0!b&)36*?ZIcHj;ZE*9ljm{m&w&?80SNZu# z=1Z>p4E48Kxj*A?4haQr!kgLuT+wKm^6XQ~}SmlDvxcJ0h5dEh>tknviJwdPIb+x8Kc$b)(VfDbw$DDD*gG2}Eq zVLTps$+7EhD3e@Mezo1k2vSB=X9^B>T0w>@qj`@iP&W4eXd7R>Eonhj>EszQ zM|H4IPMuf&s+x3+N*%#|!JBS*ftf;=@_ZY<|7Ts0zp}!&I{`j0Uz3F?2lY3q;YZP_ z8b4Vh-slE-xPnjMZeK)2&T@b5u<1ua8m8w(^>~eR=0ntq z@_`eI223#^y2KV+xCTtl+)=}$xPoLfl%h-qOBYbYF@%W>wUEFqMSHpf0MN!{*`v%v zGI4h`0F9G;6^X-(yZY=cZ5ED9*O=crqOSlC{KVKxfl8q>boMfvO5Rf-9rlHenK&S$ z1L3D48C)ceTi~^DASu^ZmsL-Nr~F0wb4`G3NdL&b$OD6lb5{ql_?uoux0Ndeq@SlKKP5Px9^ zN>v*5LYa3};VS7563&#LjOE8rJ`2xy#4w2)j>%3N@n>rOG8?;nuD(z&3Y>f<&qr3A z4vi#+LM=6Oq5WLBBZ4j`M9tVFK2>&jkR>{twMWxBrVJUTT*X*KEzr!XSr7UunCzEZgIN*Wjtz?Lf(tG}pF3j0cMM|J8L-X`wxKg4{0fT1}&YMP)i0YfQ_A-sUsU{}>2% zF84KKE0I7b8n`CY5&}a20Re0XvsOS+(h@l=LVePEsnh7`XbE%W=jnPt$6!vVzzlvf7LKc^mje_?Mo|Rk6@gPJM zcXQToALJ`DnSWtFI|qJhHZ|O8F=tJi$klia9%>2g2AN@~XS#jRyOmgGq%H&>@=C>4 zyomct_Gc|_{)yG*Ks>cjZy6~GtcIOFkWC?~pcLLh*lS5fv$>9PA6b!%yyAX^hfa7HhllV3w=|NNf;J+zc`g-gMEd2y+JYOr68sh2UnJTh8#uflc}u>$0PM@09oADgDW*>& z1UmT{$^&Rxrd3=T(y}fT5dUFI~q8BciY|NvpF@DJ?(1$Oo6!C z8d66e-t1W@e2EuzLpiS(UK&kSsM6xm$1QSjvOTV8y&05>P*O+_=wgxQT7k(a5mTd&?yP90H#cEZ6+} zcQI~xwGT+dJl(@5Wjy`J@FYvJX{g2>yOMJN@=rT*;qIGqta|cP&P{r!gN$RTZysVI z?^{jMcfKakdwtfZC9FE}tal}~tRp^(Zc&C?T&H1eO*y$+Q>Aa-8DUw1bcO{>1 z^H#1-2O?8;e-|VWtH>sE zc?!hL%sn&+x}aOVwpq+q?0KkN-}a4(!D;G|C6*aG_K*ItLTbvt%KIjV*LZ2Q*Sekg zW}(q4gsa6kWo02IRF$V|djP6_9wL(~ATBdN&;_HGaJ7vorthqjX!e|1pm6PoF;);1KuOF3&IHLTNSGyXEc9ux1#5 zIoFYTBAExb(htJD>$Asdqzbb;zd#)7+ti_?xG-YQs3+EaO9{1K2}Q+!VW%5|LxT48 zSf`&xd5F5uV15;)-9f|z%wBoyt2&Gjpy{YIC#X&h89RK)3n zZ4PuK8Ook|KNGPflHgq5+iHQPmgc=aL1aDoSlzFrIem9^aPQnZA4J9cuTY84Fr{uk z*P+gwKlmE(n!3aQQYTZKnAh$dvk%C&Ra?sUzlg7yKZekkaZ*!J_>l7&qeJ)1iC~H8%f@rT1m(W%frub_+)!GFf>W8 zq;{4x2OZFkOklO!XnmMw>g1`Pha`#WAivnoKqeAH@M@&_JMMtRx-%z<_2LBp5Dwzg zzpdX#vp?xQ60#fkX8h@vZR*#HjvqfyP&N;2DyuLaZc&mwC1gYB^wZa04CWA>Q^^UO zBD7>b{zqav*E?z-bf7c#?;W;T%gqbEU#p5c6iMI=R&Wg_D$k6 zD8v_e!0^cLMAGkDzO;Lh1kWO3PG7&H$O%lTQnfiL!GzlhZgt7mL!S`POvNU4U||v7 z8XrzS_BeW5dXb$ab?4@Y2xXvHd?YyrzW3?N*DF?YZf^STa!mh6uz8Tpd1_(lXL!0F5$P7Y zR(jk!#f>}N&PXfdlp;8a4^Xun^YCoQs?Du!Ju|{U9tvWs-=D&sGU=o8?kOt@D9nC} zq5U&szV=bAIMJ@^AG-Xqvb*)pG#^0T9e<|`%&Q}&$rmJ`_a+9c&XsVNsmwCNpWS=^ zSc+6rj03J~cvA#bS7&KR3^GuWx4$np;A?S~f{%i?-zp4zn{IgbhVy0}Vi-penvshb zHnkX8lOgM#&5Ze~uVp&phD&YRV0#St8dGTkxpJ6#hJXsZ`Ji z{`abSvpS77Oql25|I^yt)ndm$c-2iMSHqCG99@!em^gSLUO&fWfhCLHWDa$P?(zv; zjBqZ=PuvTV(QhYAdsqH-i5GjWP?55z$t8LGKAv-gNjhvVay2}dFOfB;rK<`=a@>mh z+`04JJ5jI&w!iw*;X9`&PlO6o1EL`(@vINMyf6A>;Iv)&ZkbFLsjia)nt3g76ZpS~ zV(hz=VWz{-Mq-Q78N=|klvE_S2B3AK3#=6MxqF^w;1x^(kKJ8qPl?Faxja!?fy0U# zKDGHAzDMDKk%RXIOV%svf|;Y%jiAd!6q&ea4F<Yg)ES?fe7uicA^m-9m@dWe? zvk7C1n#oce#z9yq_&_o`>4iYU8--H7-7A+G9PF^DEAZ?$V)lQx;$9@h+ArM zbnECn7y(6SW|*I9hn2lWk@=_QhlBRm6^3tPokGYTdmHI3w?VI(;S=S(uOX@eqb$K* zp^bHc5dhNewXG6|CVa<|{1mTEFsxYDgL}Y}K!a<0m%idl(}sd?C*SV16zM*Mr{Fe&9ICUNXjYXUW8X7p^tFK(*x5Q|3O0P zfkc;9c^N+a(N_8@P#Twmb7$bAuk!PUjJx#LL-4pHGt`)?ODvZ`@i@hKNd?d1#STlp zs|n*NDm3~iD%LUS!<}?)r}cHHI`U{|J(0t;w$`s z9gqMgKlMAhyB0YK3dH%DQJWtre74*;@dowv`!sE6IUtIRJ|_-km59$_MIIOl5JD~7 zb9h#&>T~H4)w4YAR7Bvy-Qe9C={N_}T87{ZC&yai+2?M}azGJ{Xa(4ZM%7XMjUiXn zqv^FSW04m5x$`GKT&zgn(C-$znZ%KsyPiA>U=ZbIddoZ4nnuWjxe0IuJ%!GFnNC+? zi<>W34Nsiixsx9Sj2wPB6}0Mm?K2>;>t?TMz(IZOA^HEHcN z=~4}lk1&8%z(B$&35xkqsMeRaNCsKz`RIP4wW_5FMeu-?rao0vc8F>ZjEtr~& zDxb?Ua9$T?d0cC68Y|~X%IETc@*NALI$4Q*On&yLs^8a0yl>n^aoVtS6}o)QX*J%2 z;hgMGy5m=y=jYVx>Bo!7aGne+OHzUufSQiukAWGIG?z;^;Jgx3K!f4X13+m&i3q9# zGrc%>$@A#^$OWcx}Vc7y!nZusb3afi`8|{UyK*#NRMHBiJ z1l|+V(ji~WH0l$-=1}{;mPNI_d4;cyEjKIUQ4FBT9-ZGxqbA3hK?miizy-k32Nt!g z!&*1h0#7-Czs_xP5D|ZEf-v?&I}&k7 zB;Qv$1_dpzK?*|lnx~pV&G^gYx`^nmosVruUh%1+q=g;hdTs-I?d9X87(%Rm>KkGI zhsyNx!_LJ@@%O#_-p_ct+nHsROn*B5%sIgb0eX3(Ia~q0N$}Am_C6aP7B`GL?Hf_d zXH0oPG?AA-Bu-)~d^pboJqQ^D`id2l@PsSS9#{+$`eglR4y()tB;W|~$FH&Whx@03 zH=3*Bw}i>8ZV{2yd&mGj-tDvi&=r`9i=v#;+BAh#<7~sI6a^0PhVroOpAB%8Z!)0c)A?G)2 z0-=o+ydsB)+Vc(6TQ=scNo%djv4XDOU{RYi104P1AyId=X3^FJEn>Fa;)C!8^!#n` zy40ag6`Y(@%-&F4-4;xO{h=iv8)qxrkop1tAo-%I)r_F79 zZ@>lvt0Xh%FS(vqptj53P&E~)j{@+pcJXM!%UW!~DLRQE)_d(Zxx~&x@8&kk@6*~v zKMf=tFpap2YIuWfMvWDauCi`AdXqnXnpCnOD@UeN9rmvv4s?zxV&obx=$tH4JP|m4 z55*W8Dwv>(Z&R6T-h4DuRf?2P{p^s*kX-DcX>>O!NfmX-ng4e0U^pu@eKf&huwujg zJjk{X4BhnU>JU7EwIs3D`@4oD`tTI)TAXT=LFTG|fkD#Cc?ac~P0tXQz4MvZ||X7ojX#Z?eE`2Jca zSW2<@NcjN=EF!NnDA^CoBKeidSmH0*s^;A?Y4ebk%b= zcYo7{uj$dss&bhuBT$>xXno*K{JT^{50V_cE6?_4;K&CxJNJmsN2b*}NG$-$4n!{``jIM{BOMcK8kfNF;!t z_6cxEt-lCh>}Y$M&9+vwg?pjQfl)a3dxWj`rAQD;ji^2ovz0}!+fQ=R1e zU6ARMGylA%km>HQ9te{|7EebS=4?}`|Apt9P02cbjVCi7Z1el0(kxs{u@~21YG&wx#m8bOlS>WBq8wc z{;IRmjVo>7CD8!y92hFGEm_)OQ6=j-NF_J~z$fJPJFg zl|Ol#Zrf;wpQV-i9yX!^eFxKr`_C_GQ|f+Doo}yTe0iAboYnzR7vAEEX*)spxNjS< zRhUb-LV>v@jA`?i$FT-yB|-6U0h4-jq*hyRC?1-$5Tf{we}ea!&uXUdy(`0W^aY0z zaw!tpyC_a44BWMHdJ(ufq(xs$#XSgrY1;}6tpLF^x*3qiDqqWmwn%$J!oKSYdj)n! zw>J67D$QU_(bKv3W5cig+Uw36ul;dNi2NT@Q1>!`oE%n@SWyly+_=- zS-_f3Jd5MvHf1p~o~cyx#U=qvj6^sb{v$;-Uc35sBAO@g7hrj0Jz)kJwu_?D=QimQ zZn@=t{~N4%w-6Ca0IH5B<4A>xpldah^p@~D*`hbjN{Jb&ODhX&6`PX7-#lV8YsYY1_46;q?pIYgUpRHKBT%a)RZcQ2E()sJpDBhNRQqF+j+PzIHhD$yW&^mzD z*rMHr*SV7TMM4mUuuPh8+pobO26QOu|5#Tzq^;dL^Neg$vAtVE4M9}dXdIbcmnzjA zv%5dwhedYh-Ueq8h9Sp_>Q1uRAdm8}lNzNXh6sVs(RnC`-A5!Tqu0x}v9o!iy;=I* zyZazoxwOBaFK=ux2uXmjf2J%n+EZbt|9ValI5A@E2We8?dvlaz-ZkHjSW&__=j5F1DshoA252L~)8OtWE6YAtg8Qqo4tb*W%ev3Q6naPT3qxuM7W|<*|p) zgt|rfI=4n}uCWQ{dX#3xvsw+eBBla~q9gF9LpQ$u7y$ms?N>073)et{pD*&4lJhHk zg`$;}bOCHB!3avUc+h#t9=fRWp{s$d^gt=T^a(8_xuKy}PRbu$9C{Pud1IMqO4hRQ zE5MPP8{@Z_ke=I(0*#~AVEuypgLDG}>xELw@~Li;mf99&icYlBzMLDH3ESqjQ2X`h z6(_Dxy3>yJ_ppc*kF>K}_cAete9TYw!ncH&thklqdnJ##W1k91jAsFImzuio9SaS! zd#~|Ux&SBqSPE7|&U?$nnbfX}w(-AmsQBu8D{yxF{*cFg8qY`tW{O4O!sMft=(kwD z;Grx{GrLQuC_2mNQ6vZfoWotGXjF=l3TMFd;l_$4r#2x@4_nhQ@k7gK{(MnJ16{gl z!qioG`f*56=#vMf<{-1DWTAXdUzor9oHd;Gu&s?eS|wv&xNfe=BQN{h`&&9EWl}u4 zi2e$5XZSZs``dI65Fu@7xa23FJ~GZJG>{GvcYz%gBFcAI-@j#53kk>+MkZ}?&o8|) zhsW!})3GMNHR)mUdJB-QYi!GIPCdhSIz*DQy)`8Gp|oG#tZp}6rYURxJSnI~V z>Z!mezV(!ixzA|w*oq`o!Y@BW1o;DoB36aIS-u~HSInwrk7mP8_HC#W2N6qtUHWT2 zfwnccPSLK1cR&P`nH;R3Qpn%n^F!_es;_i3G|*%7$X0_bLK`m0@v~m2tz+ds#V+a!~#K3T^NACuMNLdrq|pE+1sYZy-zIR0NGyhfsBD3 z%zy7wCNR!C=Wz7O;H+b#04E8B7yBakQgktu#>rCz5+v%v;qO!SRz|qxIAhF=a@VGB1|14X0yw}VR)W&A-RzIidO3I6Q`3DwgMxwOw*f86U0S-D0 zR~lt33_wbEIR~aAL17cKKs}_LT2Jp-x$St}i62o3WdS7I(D}gXl#%rm<3y)AZ@Z-={u8&!TNoxXz#D8>Fgo z8>`td5l^9L5fZ}$dNB*w8C5gOjJpD)7bNu-Hjaxhf+ac{-xU0w;fI6l3I@*{)JuSh zyUx$JIkZH*Wbp*?hk9Jkm!(wbAxnV82P6=VOUFn&BLVT>)C6RTdM$hH9#JUmCvvLA zevn7QmFYEQNO6`Xx&0rlwo8$V35lPFRYQhdrvw}fqwx2*cDy+kL!-<{O#bn9hiJNI zdgVmpDRP~JBc=o~8z%UDuuQIGK`x-3a$TbG-7ZOh&|G!TdN8p7-=k{VZKpW| zCG&R2n4g6Vrg!-Q?_lo0f0nYT=Ed7UY)P@d$KQGYgDOEcKkD>K)Jmdw3%Bq&QZ~PW z`}MDKy#-InaZEOrMReEEv+U>GWJsP6mE&gCvD}kf1MU~#z2~GY9gmTSQY3>7epZ8T zq|KXF4%u}*O=wNMr{q|oVQ8s7vY7x+F1LzdUd*7rS0W2RVL#uZMGqlbQ0M&2GuB~J z^(Y)-((|~X(a2r)9W!$w79`GCEVQdJ-w8;3SB&l#QfuZG)yL9?kl%?yuY_3Lv3Jen zXGpjT<#@tcqYIrQerQ(mOQs{|1pm`QbEACKP{!lQymjE2M6YA4`PW#pRJvABf~$-r z$X*Z4Gj)4-7=W)gGX9?8dE^8u*Izxcj;!zt5iW}2pyaL~+?o+8Z@e77Ue%k-6~^=V z6+R2-t>)w3jjo6LPn+2=bml7{PCeZi&8@0Ni>${r2ozt z-{>-V}6C7X$d> z?A@Vu;iQ;Vl=J1%J5sFD`*Iqse$w|E=nBnrhLu#BmP~(O^8U_}Z&!ET zaPSUP+L%-n^KXq!T>G+>L75>!T!ym+acHOzC5i#1>9mJK{>x$5|F9fqA7z`#yg+jx zT02Om1dn-hcKwPbSj%i=DIFe@;boL7 zeqhV@G_xi#S?m_w<~xf#_w}sq}VkMIZ4!7JyBW)tiw%w4@)Tm*6KXJ?cBCVgqIU-_Y$!!7hZ6UO`3i zBy|JO+b5Gk}tg;RY(WMZOi6 zueGjSmntMk?2IwoP-jm!r;CSc_02AfSE3xFpDc=OF-BD^1_v#&(?FoR7YewIRerWdxWmhh41w;x{zsl|HATl)lOK}8hN7;<} z_0dgm1r+N;5>bVXwiolAP>Q#8za_DBtMC;i<4|RLbSW0OafNt|X^CA!%V~+(&0y%7 z+tI?(B>rIsBqtP$yIVqi0YTrl$4XhE)oKV*{anj4P$Ydsnflx-X+n1YXg;%mGbgZo z5_E?jSxKuvzN)RCaJ0Yb4^w>CNPjHnoIk_>Fu|;KB07Q4{fI(S_Q;hedC;Z8?6u2L<|Xd z0@q>LI&1XGpNpP|gM)%65i^6Wm(c24!jkIk;vgEB96{cA$Mrq{#UsceP7IF3X9g9L z-tmw7n>6C(T^M?N(1VoDl-;l{BLF>Xtm&PnSfsB9J$DE>#j_edLGz9GQkA`98L^2? zI9+mxMB|{DC=hZ9^Yvwm>YQ?27waK z<;hDi6exoCMGPw_`(fqg_qen830SM%ikhSsd9Y-YM7WOd=$DKV^eH#%=4+4iPXJKk zratTCERjzxrKHQ%w}{Ujaq-mhNxKTo0Tn-@);1=OL;g_Yk2A|*6_g?@O-TW}jAqT20gG7WO zk&Y&>A$czx#Ky}cx37ZoK+J69!;u1Iz-OF{j;rI zz3qFDl-VFD&PlS01cZQ$p(7~?2|qsdg8As~B`OvA`!?GxGH@ZobE@!j&RB(aAd|4> zD-;{OWBR)cQm2pOzZ$Wx842MSo%OOu8Wc>sN5-GTz}9PHm>>$=bz?2r*I&q%gHYmb zJ}TsG3v3y~zglrVDxAb;=vWCnyS4a)==87DrCOS?u?_T)^o0jNJjNJvns0AK<)s!# zk8TD;T{;$Ix!HJr(#{d#rbFPxKjsIAn){AiU0%w<5@E12E%ZEZ3Ax;-^CQB23tke` zhx-~jPdM;|U64G%e|CBt>dZo9iT3o|XMbiI4H(8zW?`B!i7(#M8thAL7nnDtUD9*@ zDq-82WTvEyAI3i7@3D}R?|HkmITPS@RQj-UDa#jPW{Miqi{B0bHo>;%Uk$gNV%>@% zH2e1C^Y0(FZ}%AyJF$MeY`$*7O!gBQ9oW@VL8|tihs4&EtMj5(+MizrB4n}+H}7zS zT=e+Ns!{w)DkLBsgqa}EiaB9|V?yGwf{5b8h?R!C#TVTqe4siw_GFmeu70$B?tQCJ z{C9V)Q}9`{2Z?XfW-g|ObW_2}Snuq?<`wK~q*lA1t->?AwE(Ztpitvyc+T`-)Q7Ov z&~Xk-T?L(sZ>u96`vDe`F0GsoE3o6prKDm7`CzFau0^Rs>CWJwpBZAn~mugBg zRYNzW7iRcT3`uawbLGtg#0E1J+g=w$M{R=YInfW_#>g4VBZ9|IA>nXI^7LiSV@lIv z=6A}X8Sa?%xV=0i_OS3JV_fZj%Qw;QJ93RWn_b z3WFPX?=ek;T^E8GwF@H7F)3fkb4Sj+8*nEi+#oW9b#XaHm zb!kkX)J38QZl(K0ae8frg28EQ|DcZX=_{tq`Y#9uaE@S**eCrNItC$!=G<8)N|7Jv zG`6Ey`|SaD5#G>+&g4 z@gld$7_G?pNJ9MN1!YlNr1ioj?=p4Ry2Vc*SeJ6o5b|RbG_TJTgD!8UL z0>Mk@`A8Uc&hIGlylzXPN&N-(>D8bk$TC!n55v-Z>!D4HC}3;^B_+E_%kv`_b#$C( zPttgm5TBZFwnA|caRj+jE)p@_{V&LJb3%JqDLkOxIcQ>f}8ETOV5`V=eAMVi2O#%{L!ODvO}u z9eJE0@-Jxsvm!3JJyVgko4n@>bA1J3ytits3z~n_0#HyiXYNk;wpx}f`oKeSA8sX0 zuE5ru;$3x%KHqMomBhs13!c01&tXX-?W6B|%|;c5v?tr;u#*3-d=hz=w+32VRgiGDTz(zpl|F!yxF#T*5~)K3g6 zG9vsSV-r2N?{Uxn^$#k_p1`bHOR~J z#BH=h`6RaSTC$Mp3-X^j;ln)wJ)tmg`cgP9vzA8 zd+7vdc0=Cujxu8+*j@XHzs-a{Eatw0GQj}AA+;QrpzTM_v_^%gJ%S;v{;#lQrZPN^ z(F?#1@aT8*u%pf~l4f8y9e$I7k+(3>Y>-+-p^Ew4Q z~#^3^pBIY^liF~<(_M;9FBjwGMHEobL6 zfXLa*z%71NN_g)fJ5s6(dCFstW^DBus=_ULwod-cS(E2LoVGfh)NMR%foJ}ss?)&Z zzG#j{@MGG^^;rf>4j@<05H~}`$_1SS)TP!)Q51O@DV38o2txit4^s6K$go{0$WBNPd3JTFDPg;8!S)>&=XxW{|hl;4d%CDLV zz89^#E;w(Z9;p+55+s;O0R)`&`*HBIGPd2_b7BWwzwz8e;F`U2f4GxyVn!W&~6=>gSS{+MC?&sNl#I`0mM#_Ot2y8}(nqH$7 z3o!J{t*{O%Jsq}lsHFkv=+O~NzSeuGtrMGg-5!P!5iDD;`qPUOLdIy^c9vwhCX<`% z8pyO^NA6ueb9Z_UIcy?jq&YSrF$o&Rn+@FWZ|Tec_Bt#gp_l+w0l!_cZl>KMV85Sw zWjlk`bwdq|q3Z-jSY7?egbIfMhVuer*Su9=o7)fO0KVy+)7iI8hwTP%Uax2h;i!?6U2lzb z?9x&JPax~Z144@KGS{-KNF<3*)nCgu6j)zYQ1*_8@m2ZBMxuiXIs~S84tUav<`cqM zp36fs+nIZ)v@xv5)T*#LHUJYDW`9thrg{{N`#=imBn_nA*&!5YZ`K|=XQ{QEPlx7m zXMZR4Sa+_rnV#?nWi-Hp$t$)hS;1bUL65=wx4l1IwSzmdCwPZu=-DNe>lSfN)@%Aa zUJmZRdgdo3R{Ljs%NMa>r|6#8(GO#$;x9hwPMZkQ!>AbOa5q(wbo0+Q%|70>QU{k} zh>zKK2BZ5iSqz;s2Mhxc{VYte+9zGQ=~U&hYF zZt%NNq$AdTa-a%mOI{<kvhIGN;UxTTER5i&c|~nT zWLBeE*G5p&uMRvMc%}V^5WaYvbFl`fkWe)iAJ(R#aMf7dzHxk$u>eSqXs8QhUU620 z#+-aQhm>CDJV&!zy0V5HylQJ@4%7^deQu<51vU+B{D{Az}dB#sIkN?I>eGy`;c`S?(u9 z*k;*FKc+Pa508h^5yFJ_kzmU(8Z9iNvxify#;VR`_R{T*ZkG+ZI$~ zL)6NfTz$g(wq(}>our3(65)T;9T8-p%E9)_JT&qcO52X3F|(A2s<6HOx3Hg-%z?DAZR2*w232;PEglXltfM?Dl9 z$+4en;&YwA(j-HGK51FV?afWYA*I+j8(52dQPBZ%4|GcJ2ho-VKeB^L!K-xLvB^<` za;w(U18L;WuNt!=mE;^h6ZCm4SqW9LZFI*D)2`oG%@k#t?hwvb8vis6y^ZTIcEyfe zHLp3Od`Ix`Cg|R-uMcjgp`>1mUhHvm+1yNEI@Ulq)&YILhT&T_S{0J|BoAGO(@(iD zVmK!~A@3+r+bp&5vAXh73;`DY|92FPv!-BdXk*vAh$}J|R9GRnaX16T9&jd<1F!xi zlvAw(y{WWQO&VL#mz&_! zwhyR^70b`obrPojAKi?iS=NYm|8wsP7$~iJa1lmXbt3UdZ-Zz{;6|+=pN1FS(b3js z)+O`}0qo+_2?QMd?v!uYT1gL!rq!Z-m9F|`tZWyQ6&?Ng$m`pjVL1C}2mQ4tm8e|< z`Q3#wm&49mTi*MROwkt@|83d4Y6F=gA(>8!0_uwNL(bCn4s=ZTh6rP7R6w19&`VOR z#`rNnvt|I)g1S$O;eRclzcFru*FMOXt2~Rov-nF=;x+YhxekP}<7x_543(>w(*=%I z(YFeV;OduZBa8w;DWN}f508v;h+wi_9FxFXA(CAVxvB%Z)%zKTU>Y?EPGodn>triI zfS6aE!J^`xq zp?4I$SsAh)IxFZ5cK%7i8i5}`)K@Q1e1KC@XD4&t{S|~!f<7U@v`Pg?5-oFNUm0xBtfn)$iJ)*`3x<~>**>ZJ!RhY-)^7)Athw9Y#u%+ zN&c?g%ZEUj^f1#QyhqEjcNbgJlv9!^2=WnQ&BxOWL|t_n!HV~d7>wchy>RyvjPkvtc%K@f7SUiAlPd-*`R!@c?C?Fj)sDVzJaW}V zDBt$h@&v#8Pq?ttWQs<>Tzu{MADLvIYQQ0z+$#o~H#6v&hb9NzY(a|@V`(60Yvf&k z6Vz9Ht%79&$Apram3cp5En!RZ2(%ydi!CZ~bMn9XN)Ifa0i$`1AyKhL5L-FB`GbNk z=D>9xZ`2s5eq7<)SOfrs>!>%9V$`*gNiKG4qoUauY#^hL9FT1GBl?b=e50 zK3^sexCC7?Zxib2j***iebZN|QdyYdlh5&`>H7#WM2cy6{~BhSlFp9rqmhD1+M0!HBXWiQL1i?o8{|N z7TbaT4+COLtB=Ly=m=xN2k2QCFd21GPz)5+ZwUbIKhyq9Q*6H(M1Ie&v)vAJyjn$u zx>|RB5wy%talKdK*!QZ}5o0a^F1P!dRx>9cWM{_n4!6zk*@oZol&a7mTDk>-Zumbd zWb4@a9DUl&jj$|Xt|#DJgXY#unXDUg#^~_)WIVY-pstYpOp95=Be#G+i(jBUF))TBvBfbhtS&L5h34Yxpwre~T2_NWXV&J<-SVWEk<8Pf{YxaTkt=5tV#l(5E3as^ZX~{r<6Ry~_S(A2kMZ8sS=957#R#6p z-pT(TX9Yj(L0WcC-3zP}o8bsx+dUgArpbEfhsJ8cPv)qNO(}*&1HQ}890CTe9P$a- zGiy{a2vT^4J+eAm8Xt+@1REP%Az@jhAH`u`$lAQL`wKF*wxO(?F1hncnW`S!u~u=k z;5-9vXP!62Ak_?4XwqPG7{tuWE*vcPOJeP*+rpLHq-p=hfVuFKA2I=~ttU%K@>f{o z^lesY0vE9F;Cu@C(G11%)@cmSG~A`r%IPrPbKqi}9i5X%1ZA2dV79JhAbuP*x=GR*1)K!Xg&iM_$3#$)+XsUTgFY|Agw-eNfvl@kyn{dHQ4*1KwxZZXZE1)_k@fR#wfg%9| zvsI{=aTl+uKj6BA4eFlrQ@;UdgE8zcHu3~>fA|blY6Nv#qfk)%lgvy~UAmpV%WEXp zHe^yOU9N?+<-d6x5+3tMwO%q~c@3@iB*e7TO4AL<_*2MK#YQ@WdqiwId4awI2G}9m ziyPzhg=E2e^xP9l?NUcT41SqvNj9iS)fIq8A}Gfa%gtG7G4GM|pjH*eJqo(?cLb8r zT;xuCSyS`|#*P*rCjgq3Kvo(jRonJ|YW`!qcKqfdJS~m+k)oGBSd6wY?peTN`7OB? zQdeJBEfW0yOEhc zsH03YrmA0|s6t;c%FJtEe4D@>tH{83;TYx>+Rl|8!99OGKNb(}7Br7>pXJqxu;VCC zR3!R`lwDg9>Fba3xfP^S(FosAJtT@zv}Y;$g0I?#rsE%?nrjlv{sP3Tp;@(?ZQzrk zZmNl7+h@KmMr@>w0e@Fe{M;Lt{Hs|)imzBifBm*9nxfJkTt$Y1`ua?{oNgqFGX5lr zHLz`z_U-aFT0bgOW2+;?&X0PPO)HN~6muv5X!r!H1^}uKwP)gefLApA2qTcz4hS`0 z0m;r{W6O4a+6A#WFE4aHU7O_AO*Dw4Sa)dH=e$P+QQ>ErNHxs`5Z$+a5Ee+aryR&d zixdgnyj~2-lLjH>S(Ot_+Qk_av5kR^$AL`Qc#rj6MJff34Y-Ahz=-zo^PN^XyuvPb z$>%IT=FM4OXivi-0uv*^6FH!A!JoCqG+q}D&N$#Dh`T-T%{k^SQs2ZX!6cG#k~gmK z;@^r-sU~}waCHj-KDiy)54-nFvud;P7kGHBPH|&Q!)+)S^&`QT4P=;w&fw$f1VP$J z@Wmk6p(ao^RktxET#T+4#PCi*@fJ;C_^PYH6XHEX@r-!R@ccg0J^2pELLZu9e_~ap zm~NZGKl(aJe?Bd-dq>_*!vlP(-`cIeOGCsG$_5@Fr3Y9Ps3T>6i1{`Eb8(%c#5i9! zoWxmc(VFD_e`c3LgLnXptOGe7({MdFKKZyRd>Wv*!=_IoShIM?ztc=NmLM41PS$ex zRPSNptqehJ*8bjKGmYS{mi!`~f)Kr;PgO^5XbZ%0i0}Er)rw0{$?B>t`)d9@%0yFh zE1YM2Jmg+(O91O3N2L&4*vd;?l)OACDtPxYWzL#-F z*42u2Qtr1g101!9@=j5V)A-_30?)o!l0;^$ex0*wB5d9-mizLl;v7I>HK+5JNNDHiB@3BTB zgJ@>78d?~A-j|_Rrg1cO(8qksfY-a^t!vU#_EGm5c58*d<89g2b?ZnR+00XVVK<@M zYGtz6;Cm>X_7z^`P3K#5KnYmwCO}9MeV0{&=t~ zx(h_;U}AIG0NV0MKPLKU$8BbTBNn0Tfud%{9gz%PK7nGkBFNWXmifNsvIsmGzcL6T z(vqMtLEcQM`mY*w*@HQXLNZ6~Q210Ut2U@Io8;)mmzvL3WNP)%jKB=wHKprAy72Vq zIIXOEGGWXN{rUb)pZxtj`LAkZU{}QE-V04_(h8=#a-<3h0YzKfN;0HBn)wCD8gDP+ z5+S0C?czG>a8aXWhsTQ-ndRU1P221SD3n62J;FAQ_Q3sqZe)Cqbex`AC~(zG^AOfb zJAmB`+P&n)2W+DJ^34)0EW8@d%(N7+Kg=Ad<%8n2_Ko8R#06~v5*g<#ort*xk$c~d z5^F{4YUpcc(LUcY;(780=kg%ch>Rl-gL17dCGA4ww{<*638{lf{OS?Uu8)maYg(cv zLlN6TZFF&2cafQCf$o;f=U1+(Pq+!2gkm05T1XxOK^?fgPOk$H&Ket+oj|HyZ4pRRyG)+fAPyiIxN8_N%V(V*0o5CQ9hE#IUQVmUDjy z{azco#B=fkGO%6ghAe@W09Jm(Ntd9cVIOj@%hT}rGbLGKRv16tEQm?K8?z_pEX(*+ z{wAnDUbp!SJ%l`TCpm;;l3};c<9zcP-GH#rpd$;^+S-ae?1Ek4`cIz<=CmBc&$wsQ zg?&eo0V&E*Px`q62^$n!%6XS1cNz@lebiyhl%b#$NcW>xW8Ra9CDh(?VJ{o%O)vW_ z`$7+4Z@)sZQWI=Z`*@7AJ2gGMJQ+k=5scGfR7^fM@o!w!lBo65T*ET4(Dw&A%8udK zP}tFg3Fj=BdUzi21J7iT);km)<&(t4?E;Y|^5(mt{MkKw+)(m37>fScdh98d340v0B2%Wor} zkrBaiETdwj&3Myt2P|Z*>CbstM&Vvho1Z5nm#YD{T;OXS8y6R;u==;KnuiGWXa z`J^Z$7pNbBN63C3cZWUW#u8hDP*xFFd^=0aHv*408tqjNHE?CJTO%x!8n}QTPpI#>%#{WMh|E& zwi)NFcm$m&pcCraGXloiWH;4u>J!7o)^v^HD%H|-&Ak8h{Xe(`57ntw7r=rIj|Sn% zZDv%D!`H4f9w{5sOeI~UtF5p(xm9(8kNkR904si#j|Eb)gaMk`#e-?9FuChh`q~OG zdnpn)hdy#@nbE>z5%Ppn9$1Oe=bU@>M!rAHBKFVTK%4q z8lqr!b5OC!Uj+LUw(ER#q*x>#_a=uQ95(I7t=RveW~fAMyNG5{9V!Y;fTX8Lw;xw` z%DoR0=dSJ^)dYPiBX42m+lGTFr_UujIO3%|gFwDpXKMucw7+4K*K+P;eA_EwHvCU} zFBJttlQXMeKH2}&vx6C7sHB}S0YhQs1vyS*x#Xy%3;JyNv#$)MiBp(=(fpRy#Xaj4 zoxa1*Zd5yELsK+%cL#7n&a8;oj;K?pIOc&PW&BXWK=NAV6n@LyXytb~fKmY*Oi=$Y zCqYovrr>vG>91Mk#r$T9d{aiKqCCt@8y|?htI4ACo1xqEKA3WL@B| z2DcTEm5T*NI>s{r$>=pf$m>VcYnhZxl{CdDWb97&*UXe$A>HeQs~5o-Ta79G#}(4i zTnRt0B0eIZqHK-_QA?nb+eWg*;w2L1*p^AtLIK!6T7Nh!5arBSIbCm!cg?_kkbq{d z?Sg6@%W?w9j}^f&x!*Nr@ts$mD9k=(r(|}oxFk^QYVhM75WsaYIQ+ZpzF#z6*IX1H z)Q-~>3756y?H_xvvQ6_8f1rYd^a&)+@V1#t{31Qz1+c?rA1z2}<+ZP)h|BZD9Rxnh z%>fz-tn$#oHh`GrTZG+==|~T>l~=yDqd%H%!xM3*nz;hkNf|%zWu=}T<1% z05OU*U+Sy}R{zN1YKOI&ywUZktoAxeo#lpQJNEmP`&qGFxMisw-P?b)<|&>S$KO)> z(;FZMxfPAs6Un{q{f$C;YO9mb^ANsyTo$@`hsv9M0k;xwGZomgRVXkKpO9U58-hSn zx;3nzxSJ-2Wts^?Oa)(nKzT4qjdXM13;hVHvvtcZD3>|Oheehozll<$kMk?I?q_?( zhBjbsgNK73C07m?qJ;+jalRpU0qtzXZtbBR%4VPWn`upFX}N;RE#2LgGDKX2a4thT zTUf+2L0h>(UqC?7v-(aoG-&8VRn}5~UaKsZb24h_C@^C;-uByGICXg`W#?qNOI5Ki zB+~et!yx^6T<(B{e^S#*SyR&T{Ysm(q)3sk<$6~8>;gbQeu$}pU<$YX%^4>5w2Kks z5;0*SOS?2%(d!yP-)@G4@nUOsYu5#S27_w&SA4p~8eY2>D&>K?eDU-%<}FK5akY(RV}4YcpK9lG6DE}zxMdGk{KWnHxMW?>k(i2?G?`qXVFHe23mkZ zH1~4X<0pjxfZ+!WqZ-jm{-o(kTQZka6AsKZRYg7laTuz72GP7{Pgyta2hLnuNL zOCeqHWl3jLEak35__#ojqjkJH1L-2inWpKry=F3w3vl7vH0NA*twn{a zcgoJwr4i&_bM@g0I4BfMKr4+N8z=56S*J0M7^X6;l6a57UGuq{HUPZ;kOFCHENC&B zVjRV-K5H4PS;-RoK)jK1*Q#wS4JsQDdU^+D%0u?aN?(LQ?WiW67jQDq?Z{%bN;sUF;B1Koj+_h;R1uFR6mQ+{jjSrrw@uz9- zP1@FgKYXX`!y^;Dv0r%uf6Z%r*pr5)tb>8S<)g@lh5Q*R^MEkF8 zAFGYp_{&59&AJWjTjvCgu@;C2rxLzJmQd*ov{SMnHwN3a1GRtt;=x!KN}ITjN=--RZ6`QF z*uLX%9F11fiEgEzuToCB-B82NsYt3+D^8+{E6yddzF2VIEM1#K3cNGiL2f$h8F;Q~ z#qI0wFk;Q(T=w?JXZxN>UH8$BSvKXVE=-~_iyJUTO~k8)Q$}3 z--)W-`I3rP5U1*_y5gGP8Xov zHw_F+fk=WKjIbB$`BWtoIuWE!+!+B>+ZKkk<$}9{^5bBE0%ltr?|x!!ZMK7x@h5Cs z(!;KL8M*Xlc`aL6mT>O~*p#p?-+_q^AkDG&i_MZsV32vRF48Kyidp3$wG$QDMnrep zZzaLVteW8%9610#K)}BP>x6j$`KxOr27VqL{+cExzo;NTwo=1Rh#qsV46~9J@hFky zbglAsZC>40HF()%z!&JV@xZ5D@nX zjP=_sZr8xwS={f!w{))+>HPnD4W=btMg~Eu!UsUt#W6rxkjd)@_{L^!pIVUNf24rF z_ytYx*IEE31d^~ekS7WQUNevDXjCJJl&^24p*dBYE212_8-C}Jyl zre%Toe{bok&{S+K9K-mCmqCM)07aQ=?-(erVYF5HKW&54^o}FnEsV*XzyU+EP(*CE zLIth{tpP>xrE&$cRl7L5yz6F6GK3lvK7f$R>yY-{GP^?VG-x#=&BZ4FCfEhh#j8TnBq5W?BI4lRr4u_ z@S0C%nij2a^)X|*ab2>+X@^Ass}HI5-9;uR5|cNPUZic;;QK3u6#q$;pOfY&=4BRv z-ZU3tAueDW6vgzVa44d(5Zm2sZbc-p9_FLZh^V!5{Z>eL3jWT4keRUSw8l6e_L|zf9^(;wzW3+^Zj+$n5kR6C;^BUcLnhO zr~(+Mb+CM=*r+M~RPP3lR1($iEuNNRogHJH_n+}lzYczrCM6H~CwAR+(ET9fv}$}p zD|U!!Zp45S!xPA@Ve;wr+!EXYO?1jZ^|ex5<7rx&pc4jlpE2F~AxoG>tQ&&036+{T zzxdbFnfwubBR5$=6n`((^P*=lhC~FB#ydC`>;`Wvm*i)uOs+v5OywB)BlrEq=9TC6 zQEmN``-pACH@R3BMu)Fpj3=O0x8$fV8#TPb4g5O=7Q^)|)w4TiC(n6CICDYUqn@Ys z0;e+&KPqg6u3b!6{0lM}A$QQV8GSQB^sv2)n-Nom`PHu6M zVEo2zrMo**5HsmWt^BSqe?blmI$p7l(GE%r_xw3RQb1xJcFC$d=2inlQwrya#?EE= z#_u;M_4s!-oyu!lX-TzqY-Eeka9$}k(*rxh#s(df!s->%-i=NI;i|V0U#nOng@zG| z6WFrB`88ziK1gDC`f&z%ST;u&me_^-dK`nR_PL-NA zeE63=utTOT&EeTi`|EUn8yXTTJpMAAF~TC!GyF?1qng}cnlHOzmL1g|7r4qrD{=?H zB1k|~CB6gs6?4i#&JiVO|MnXp?C8L)>YW{X$D}wQauD1RlRsrHk+#E&$5$t|#fTE5 z;tqOcGMSYhy&ij9%38Hh&k|%RISdFg_=kbFRHa3BisUTvEuyx_GO-(pVbOr|kWn|b zq5!xzYD2%ec((rPer&8^6r1Va$)^@7c&wtOngQc$E-|i+n2i9P3;p|hqbxoP5Ksi} z>5t#IUZ{ju9d$GFM#l%p(@{GM+}>i=O?U-e)_@^xqN`b)f}47)w| zxuv-(wuJZIF#5Y%W34o3uNtw0w-Twd;HTDB+9EYnYbEw?hO$UI{nuqg^5#1tFeO^1 zxNTBR9G2Ycqvq63x#2UZcb|hx@w@AOQ^j;^B1LN5Aerm1xEk2~1ccYTXO^{Slb2CG z%Q;YAd7Tb9kIC&U!#C&$ac;K^%T1AE@?CXl5=)6>>`Xso!Y^>~@yYEh5QpG-Foxzl zhv6p%_A%++$B0#vcDYghB7s3ywUZE|D*0C*qPcpFLKBuCYYLuzxp6%yDH*+)pp>)V zkUHc9d=*&duSHU~=D%wby0V7>5-DMD%%ra}Xy-6-89*|R-Aw{#JDyAD1wGq_%Ke}c zhaqEse41~P5o3*92B=>DL31^-^bt$Rhh?}R0$uF8ZJ=Z^k8b?c90MB^%wvxBVz1xy zK)*JY5stdOZtCa0ZAAQ+Cmc&FNozkjLf27CHauFjWAl7$nmO5@qgBFN^J4VtOGAX0 zul@HmI}I5}4$q%o_&H+z}13nfhx#d*kv|O|J4w*C%*pH5l1W=cED>GiNB!dhDE*U zm!&`9-2u4V2>!81k}Ta?ZEPYh@Vl}^)rHH3XP;*ZN$_TiWLWUcBGXY$Pk6?*4kmktH z-2Dhxo_$9LDnX2$l<8U@gPe}gWbOL>1D2z_$i|S7G-3}@Yz3W~RpyR-)=KZhxhrzB zl?m+?FFYz%H}g1;X?XgmtglyR^yk2piV{^r{YZtl*BS$^_lElXv3Kn*Ny1?AI-Fc9nS4Rms&j}63)uLJ%KbYYq_WK*B@WK#%hbw1?E`ruyiL1vC z(=F6|uYRMJe-*AD-dpyslmHWFF`?hYNJ2{U{k}s(O(d_s^EUgd%nvV%^&O)gozN~T zOnG~k#NT%K|Ng8%nb5p;)WmMIYSVGkM~ZLcYy<-NJxPF72C!;%b7?|Lmd|e5yI~oI{4@4N!k%1YwZ*81 znr=U<7$LIJ*ZvFK8Gt1H?KL{Uj$DjM#=&U%fD&JYIhb- zhL{jH?wfZgh)%~+FK9sSxo$Zgw8TJ*JrCwVp8EHB+g?9n>%Y-CwZ80Nn?7UqGdwTo zTfgA*(n&RmOA64d5%-yd6ogQ=D0UL3gY2jE+3<|`!N3^E4F#5ztcUjMz&DfNXh&Pc zJrP2F%R==6N~TUQ2B(Q8D|Mrrw@xY-!D;*Ges?qSaSnA@Y3P*idRx9 z@lMJY?{~FJ>O5ao{%VA(=kJQS5uXh+N0EPz31cv)SKzuQZ!EqjWpPS3pfbkn0Es4 z#s8&K24*6WxZYV;PJ#Gw>?<^q!7at^k}u%|h5-F)J&WK;oYgto6lX?%)gLbkkx?6m zAh``ke4D5XKR#a^v6$+UwpY4Fasd9ME|WT|H7TXxoR|j-5pee*x;mxgYf?PhNXdA0 z*kDLLD}l0&yf@`aTuZn?!Dg(ljtaQ?{i9>!M51HFFC-~M;<-7yF~KH8wqXI`xvGK&xB<>j>#f}gW31Dg-37X)AaLnK}0vc8U(S>$O zT4@FZX3jSJ=fy6xkg*XWVt0ycAnSj3a^K3_QpTqWd5SnOzY1ciA@H8(*WF}`H3qMH zpEM{T!qdVm*@w3p5gccDm4qj;q5~e3E#9@wts-j*s<)x!H$7&(BqwxNB1hfr+pX?Z zT#cEbDT-;iuwLoD@NzZjwn)O0tGch)do>87Z0Lv$Y4B;SgT!Eig8Ho>Qv! z`Hg2k{QrT4)<#xJ+Y%xCF(TEzv-OipV26(IDV&#*-X)1WO-=qL&xVqK$uW?kZ-Yw3 z6+kMixwJ_~`qO3#hg23(6#k~Un7 zeqrlx?(aqZf6ij&p^@N%(Xr%u^4dy~seQ9$+&Tc$@R({08&& zBpiW5ejaLiTtvf0EL~MT(T|!Ar$N^(8*}4e6y~NCDPU$|1r73P1_PL{` z*{fj~5tfz>yY!AF`NW2Hk;cp~C%bmm33`tl)94qdlfx>+pe(!lmw$H*QTh(vQ0F+P zyU314vFrZn$JfOu(&8m6is>NHIIpA)FB0+gNb&z9>DFsn(w5FDe8^J=tA@3NWJD}n zq11Px=*(-kQtdq7^T4^)ztem;l>Bm>1!!h zJcWa5DwrBea`$|U79pK>JNIoVLid{-{n0Kv6Xgfkl7I^bV2JFc_I#QDCwlYr5EY-S z=gZs+H-bBaIcb<@(XFQ?8YP1oTk3fayQvJroixjjhX6PJ(^{14QwFVS&{PZk}Jhqg2)S^?7gEm+I z*r%tHMwT;G%eaZ?Fe~@51QLvTR+tsS?Z>NL_{;T&iF3q+n(@HY$1)r@swyEr+KTP( z2EU8o8EjiDOB&5E{(M38tEC&#jMz@1mV%^bj2s-Q zT#Lr{h$vT1YZ2hV9=T*f`ObcEW|;p>X@0f;0FOG65Kgan*hc8i;S1j|G8U8jbKaXI z2WBOgoY9e++s=n0J@~}(YDJfERi8Yzew?B!XOEss8x6%0t+37<=|&7eCau=j&ZwFb z-W~3(SYg?2pt>MM-=LdC6)Tvu_g$hqz~3-yyr&yWx(pT}5<4&*prM#j^<+kb4}4;2 zt)lD3_bZY@ey7hT?W+5@AAxk77fk5XD5-uvx$l?#L*y>VS~KV0Y-`7k3(p7`U(7s{ z>>MFa#;W@BH3FgTp}hyV0R1v{(Y#|R{UPt^ub9V_t7CK)2}xU&q>Vu&g5(iHiE?Fy zhWQ!Z^i;bW-eRxUBQ=OOqB9&xH*2_7^)v*^e3op~gaf(l=kn4yA}+FWeR08VoCVdQ zTpaDnK63OY0%iO(SN+I7H=k?4Kg)iXZ^OG}#2>^io-AX2V>Al>&puY)J<}b;fMcgb z`t+fbj{3Hgq71>p_ri)a5%vu_uG0B|g$;JmGNtyHG*`P?cxcU?yfa>m7BwnD%>dzK zjk2?_F};y=+4aFfk8V)odV{ju0u1lEBhC|qEPMEnu#`e&dl_za07?} zvTy~6SstJ%CCde0F6YY=Z%nGiE#|GU!~{_(05VXyP)28s`mLSX;(!U-!fdW=5cpw4 z=uknJzK&!i3#Hr5U;V}E&GKS{uq@?9u+mkUF5DiD%f&e5@-xcB5!_OYey3KBA9>8Y zG^CC@4Jdba_dL$n?6=Xq{&095R@{-$)m@I+4Fo+$-FabtDdc^%7lrM<+EGlUet3m% z=+zPt0gPOgykJHE8wLSD`K$r-@&XjSC@T-$es9FFP;|;&)K(j4CmfqZbw@O&6VAgF zfaH$?X{S2OC8jnE-E(OBPKZK-LYckcpW+}Ma?z3*Y5{WA#B4>;!w9D!KzrPsSJ3vJT-r_~}dbLP76vah{u!S9QQmy^b& ziF|&vfG#;qHu|+y5%UlLsBbjGfqF`~LnF35RYUPds6;9Zk>7$5HIl9NDOKy0h}lMv+=-1@-O@i;KmvjNkgg?IuzjKa>P-p^&LUc$a*Ewe9CG_;9kzoLD{?DS90^xTEpxR8|#@!EXYUL6D}%$t^7}G^@~dUK(-xb)Dr4Vk8;Q6>wvD_O?Y?8C4ua2OJzf3JzU8a@7nMmw5?b!b+q!M~(8DXjQZbgG zRDf4XZJjr3o%cnT^}dfJ-7gP7Z&qtH>s?pEX^#m*PNI zyQm|otu4uQd5_ymI!Eo-`o+dg1K{3?Z%$6Mx(JxcW{8!U@z)BL?uLO!Hs&lWll#wq zU0J98Vqc+{xk>(=NQ$lW?C4N30%pL;<1mVXXZfrml^A6{*7PMGat4<{32=E3+bs!h zR(lDW9>PS4|D^9_p^^v_SS1v103$v5+sCar-E9ReAO(~%N|}kBkP=rTX`&P2#Y$+) zEZjAmEMV(PA|^(ALHis3izQOJ6L2-Uxntu3|Epm(MXT(b*;M^c9h{J4(ZyyFwICyp zo{UP2qE%M=qZ&w+qQu6mHnLB!#U>HJ=#IC1fm@TQ5=s=NTwC|}Y-c18wJx3bmWCk2 z>;{6Sm@%p&DClBUw` zRKn%p<&qLbz4hSXiUc~$vTee2FnGJt{10E`1$d|=R|mpdku_&wy{^v(fy@G#Q z2AaG2`W0WLvm+5Y14Zu%ol7lJd{d66&#j?Pro)`)F;Ye%NYOb#5`ArGF3;x7%{KjQ zQ#xiIkAd*P3{~H;c8wIiusXM`hhu+fUSxynG~ZVWhUpN$iWsg7Y$GwfDg9*BkRxj% zr0nwM-IpGWh^WDKTUE)O$~IeIw2}z0#^kh8`!2tjHiTw2;O*jpHL5lO@})`n+0PDh zOA|j=yB+%;%C_gmd$+6=yY%IcSB4Fz-tp!z$Nb0*iPAa_gO3A=l4vGb)uLx6c`0!km)n6Io3=t!dd&e|P! z=b%s_TWm7tiDsx-!zg}{>1dmcibWBC%G1jnu=q^lG&4)PyZJwW>QIr}6l?T{uAlcW zqOY>ID}!011u5Z<^*1rj5RkOGzQTCMYBLnb&Nhg&`EtRt5URcfNiJ%|Nhl>v#r%1F zd8;dOZZaG5Hjj%)f>I7}x5iSaBNDcZXFGJC9&G;e0>dZA*4oCbQSiiz8$cV(^e`0< zBBH=SR)#RVV6Lg_D|9w#fM)S)gO-M2tybYBEkx#tR2giiq3K~Fm;W~a?0@pAg++l7 z1>G}MH{EpaZ#<|7&8)~d^By!4)Sey#643D-P%Rz3{6)E zouQDP3aL*9znz&2N!KS&!rnt$l*Jn^sMcB$>-S+S0TX8$#`yfMMB;yHjUgj3?f5q| ziJu#gIz2em6OsHUYXU0qcNg(D2=h(~GG}u~0xz_Yfhm$aP)BaF`_&B^oun*pOzD{zwJ@r-bjg`9HtxgIk3YeD42cl1o0u9Y`4Ns z>5J$7QL*Sjmh^{6weg3E;Wl-;{kRGM)hecJ6>>vV*ZFhSH{a{F>p@$;j=xLsoY!D> z(KspM)3P##jsJy!ES5{yIRQs{8p8p1;a&e>KqPS}h%dfuSfCUmoqxk1riiC}@2&(; znVJC1L4wSx@t%5xvPuqUr!5Ox8hTIG@h_M)+;Ehu`~_<{yIbcoD?ZkN0w)qsZQi7f zsR|k34~Bc=fPn>kyxA^stJ2{O#%TGRS%f`BKsTO+t|iAQ%#Ym9dD!=H9wI@dLNc-e^|9BA-f^feb*kR|1DP0aw4K54EVq63- z`jr(!wsBA}GHC^D&IJ>|xm-ha_kA<-9Jdl4Oc!j!oiu;2&=2x~Z6NX=-{Tu*2gW@gG^9=K91?^w6QE83r86V*jqP(klzpOe^kwvgiJWm5rDmHe zY&ofG%t-T6dZ`pEJR)=HnBM;R*$h7CV4jF>QRvvMY%7xjJ0OJA39$22r(Ie#q3+n+ zNmo=E`q$i;iY6~2a-P(S4ex6FRN<{h3;sz&Muu|B0Iz@FxD{0vjkge){g5137$ehy z<&70@z^&7+8Qb7qCRsQQo)=gj7207NuB;+l%NJxQ2NZo$=?XQ#w8$xu7^^F1Rt zcTaBF4~Vs(znQ=D~~4WQ}m zE}e1d9*PylTnM!XSg&e11wc-Q%fnN>k*@d;VH%XmjUDj_9wJ+b`j^amF%`d=M3UA9 zNY;Rrs-kqWDG;Po7jrN1(yFV762awf!e(78Hqv~6YJ@;!e4juCeM|ifHnvl{5QJDot*iR$E?moC(qwh-p~YN%-uU`z zXH!+c7Zbsv5yS@D|CCoC826HK?qFICMR29n-Za=%NFD-6HpHtgDG6QgZ=jy$ngg7h zizGDAr1kRowhvRilo7Fb-uC+vmnnHtWhak)7)J z4btd$!>!8a(ATC?Zf_mkuYmx7{Gj6o6ER`vM<&O5Tx- zVTsWBKszG|XcVYBlksXQH#5JJTAp%61_uW`q&W|pi5wz&8+&O<*V}6zTK@&ub)#ykeSmt@XYxBr zBo6*(NN8HlhdBL`L@v6sya|+kU_whVe2P`TJGSpD6H~MJkZia1sQpC~I3BlAfX`ux zJYzkI2o1wDYq@tg{FL}C;6)aN3~E_v_QV7JqG9TSQv2B4mrXb!8*6wrKC!iDi2tXT z9wSRA8gJqt!_8F42yA43lM65Vh0>TmPxIP`N<^c;%(41WQcGq~+dep356^d^wH5+m zP|l5epg16*nMJcNy{-MzDQ;*yK94Dh^Im?QdJfw1!7ef3G!fk%a{m`Rb5?!5aTS1l zs5?Si|JYpbt~>7;;KA>~AZDOrB7{W=FT`49)`@4FZ`1TLL#<@#f&o>1WqveZ(yn_^ z*ykS%O=MYZR@S@g=;#&^9`sG*p)Z1=xP!S~m!5;mSs54#_1d&0K!;_2#n7y`IOJD(9zOB z-qfv-y7hxxbbrF<__3Q+IDQr;`uqhx0J;{P-=({<*IZAt@5$|DmzNi?xz=t&{6!`P z14+dX-IOGCj515ELZ)KnLLFW4bWmvyQpZjiB1xcneyv0o#JIKU;zdYuep>a+lrRE4 zc!St3$RN0ydm6Gs_KaQD*Z{b@{P+OspWO+y9e(wMIA>v#gctJ)l9jL{L_(0&LHOU%;Bl7P8$_Guhha@k={fQM8fcj}b-NWC z4SlYVJpGgKS*>!L0AkRp430$Skzw+6_eaWKD6b^#3!q3@h%k{)l_Nl1{a(1fNkUTn z=>nbY-z|y%qHCc<>&Dk&vEd+yaWrzoJ*n~8m`xh&_L-Zg^ZfJti^HpJCs#A~lYKk= z?8E>DhGiJ}PNj(F+rH|?SUWy+@yfWX;=2mgH?!f>JQv}`|G(tE?K#)Fl1)>VN(!{J zxVq3!3tt9?f%PM6@dcYWAL7tF1he7z_s+*$|I59(7^&wvi`Jh=Gk-b>?&%+=(nD4? zptxo7U9gc;$2eC^DkM$sntp!=AX=5VL^`r|U0F8FwiYxa$w*K%Rc<}H2(nvZg^wIb zApe{BG$%LHHr*zCYzA(<88JyrF1TwZO)o54{ zA;%mKl7S;FvtB1&kup~pabXH+U5akFSyZT2E@wYmqR)yQ)Gsk-IhQqP$oqF*zS!wX zjrPoqsfa$;#r^JDG|ObITL61zsr1X30vf#ELx$FQLFpEV)Bs|_Dr~x&f}(pM;!L7@ z78f@-e*D`6%4z&wd1s3t%QK%xiX_gn+OlPNddOu|3j5g81&CXd8VslSHa50OsOu+M~iS!+0ug->0&`K8R&o~_S{ z&N@S2T&?3)-X7T)%lVJ#5V|>_Ebl-Wd(fIDv}u|UzSG0RsGF#Di>*-n9XRoB5Vk|z zpbm)kGKBG1V5waCjUltrOcH}|k+u7HP(_)|Yluk@!E zfI#fz0ZwT4_48%of3Rb$?!t@ki>NhL+_>p*M_ugXyilDo%jdHCTqAaZru+7f4dUlyo4Ns zH3`sckHbCoL}glfw4Q7s)Kk*IfLvSqY9LM#Wv*p7rP4hDWk1s-&~w9=DlbKoe3r?F z#QsNcEw>KZp@KViu#X1Re#o5WHpCD}XNd+V7xQd{vnS5(Ri^VUhdi(*`5x}ggg$Y% zhQ0U(RGr%}J*CjaTtfAr)+pRaG83Oej<^i$VJo?~ilIuxyk)=L>y+%>R%>6Lbkc>T zM)BbH4uhIX8H&r`ct!6+H&QXv#`JbnP8#@|tN|L%FZRX*Bx zDWe>Op!!DNfc@59FJfp~opCrV^V~K7t-j)#hsX3}`aV(J3y3O6g&tZ{g;lfYg*b0- zzzh@EILDnlAzW-dawMZp$N}xQV(bY8YKcY@5FS~n7->cR?wLS7;C)U0w?OKUTE%|+ zIyeh^DXd{YN;$wk_?*YMC`gNp>6&DSZ&3$+fK<#yygJ5m$kduLk8%{#-23Zr@HIrNMm<#3 zfcMs>jw8?gQL!`z*Yf(b439Ud42Q#{Vs^#j=n`DzoY{-!=OxV%B)z}NN=DY#|J9)) zy=Y?81W#C+$x$^LR}}!;P2)tbA5aHR7_fkS-Zjhi9S()J3{+&zuHDx&{!iv24Ht7# zFjuD-YlO#Gn$~D)c}|fw(7E$ySM?|#y79|IgoS8Vw3Uf z9ywjbE3Kg5k?sE~e@06px61A1Wmah$d!Hu+d`unypUbWUkpXm?D0 zFtH;{Z!~BGOy(A<^k6-jsMUA@UWS~%j>&;HJO`B1qMrXc6}*Vuoj(AIb$!I90X-hJ0auZ`ca6Rb4^6uN&)xLThAEQOMd{kKQVb8D(Bl7# z{^n7kp>7V;T$NXKyJx|_DL^OHX~4^Ae7`if{;b^H;HUfQ`@A^E%P~pVmP2@rpB-7W zjD8>i3d4Kqd(ZL085u75*a3r+8r3id=ZluUfRl(*IIZrbd#T`Y58hGrK2TJ){CFGM z45K){7Q8hQkm(BYsj@-WDQ55zsT$t{p_t(9s-+MI$UT*fZGP&XB7iQuhSNJGR)eq< zeL8GcP}NTaNcVOg;X^6-iD=VU+`1&!=o#-}!NW$*;E-&Mt0T+Ux+~Q@9`I7=YOXqF zgN}de`doGVvH#ap`?{Hei~_iIhz(UNi2NbBN#{8U{&Y>u^TMfKE3b0G!vLD@C$nac~+?_KB|YyeFZEGU=eqx`wIlR=S- zwnuI&T5y!?P?uj~!K)#uR%~hk@{ov!p9!J-#<+5#%ikxC4Tfz8f_*p2&S;T32YAQ9 z{EAI7+C=hIr21m9^#f3Ct`iGfAGdF|Vrb=K zP&!Tm&`*mq=6nS-we(t}@?+SpB5|4Ax^V*HNIl@{%Ij*(5e_{A7QTm zz#>Tvdcnq8PRaGznvZPYb_oAro=3_~FuVtk`urmxBI9Q!{Bq+8K_^^IQ(V9_^9hSW8qSnT>W&rt9+@794Rw6t-St#L_LubipdwaWd}GJuFs@t$)W8Kg z##N)Sn_#gGdQ=czezSgE8fkShIcw|Lc9N22033~n9|S?hRER`aH5ZB@oOs;UsB)+=wmnZFA{Z`mPq?0d->KT}%Yh>V( zW*fZ>EB@_(z1dVZ`~`^W_SkJ-z2I!Hfvr<46pO59<*m(o(|7cb`DtI5?e=ZOkYY8c z`1DEgX&kPCr8Td*q%3!j-A4IMTzngSjgq}6ekuNLZBwt38jDosNqEeYKG~!dIgWUj6xaF)<0`_9ltppVFIy;*EzkykY!m_ z&t^jU?-i8RUjVL0LT>6vT{|v?u&*Xd4VUYE z@pdNxQBcqx0tZ7HwSpy)%V|Flr#fw<_~4rn5^AnNlwY@gPkVSG$9UUF<+AaWQT5*O zu(ssAl92R6<5Dd1QfI#eCGwJu9b7+}`6&q*@Yfo6K9hzIQy?R?dO770&AY(6SCf+g z{VIk7KWrETDjgb&AyXyUBJa*hrfy(~9$k8S>xJU^d>=ykQjq$Q`K}kI^+L*XP@VKm zSCbP8DOBnJ#@{FQwA!S@r*I}`CO@mi<5yd6AMDbqIATH??qkhEht3D;c*3ojHYOx2 zy<8_KTy5L288s8J%1#geg)(-)lmI5iaV*gd{OoeqwoqW^h*HEI$jiM{mHC+aY?_U;2zsFwG?UUbpENdN zitu1^t6H9H0B=i7U&zbA773#09acV-rl$eZ=2?VP*#Zf%gpYNPAm7N(AWbgaH;{dF zj}{}Yej5wg0RXM8ET#5-6!-Uj?*RPl7=&m*i-d;ChK$xCEY?}EFro5MmgKsskXd1K zZg#?ID%_vuIRpFDgqX5~9k_AJ)h#blRWnCawudG;lZBT8RW?79f*`sPiP)4ZkyFT9 zP1HHAEnXMFWq)IE{AI{LT{WcR)HhJ+bGgvt33sG=E=Vosj|+MEjsVt^a&pw(DQa~Q zSvI`*tEjwgoVPnroIpueFmkeuuyBP$qeLq37R&!s#`Ce_B3+1HXxRt71aVy0zh9D2 z9J!o?3V~z@=MNJT3sY=c&Y~EGp=|ht$-Y&OIy2is{)h=)tPd-L((A4)h44!=9K0}d zIF|+;dnG-F&l&WZ$oHvo+QSMt#Ybol`B!vt7*C%ab5J-udSN{+t4~sLbmfo3k-C^V z3;MRtf4YFq`~z$t%h5A?%0%XN=gheI`Pok5GvM5^oRn}_sQJ2 zhX5yYXhWbxiO-Se;~?FK1904q>Yv8RlWpcE-KXddNHyKbC|N!V839?=$t~+*?s_f$ zdXAcN>uGmVdc`dPFNJp0M>t2-Lkv=tpxh=%NBikU`Z(Q?cxRJc84TLD2=q+;(Rgol&=8)P+Ouj-_7`-ahg^M)NN z@s+tSwN{RqFyzR({Vwz@Hg;n%ahiCtpBO`bh%@?A<$#O8`n3M`%@7c6F3)Lnf#R(_ z;r&rHkW9)2mR$jif_B=Q{Fryrzgtv6e`~kL{dUIG+1IZjeJIj=)_62-%r4EXW)BaJ z0HMhVS8MUW+2S@}maQj|Y97qJ-_ybh)8UN%Q?DBOVPXzlC_{&=Bq=_eovI4NBXMKX zf)JKIHPPraDJsT@Sdz|a=ADld(Iq|s(mtKj=@Akjs%5`DNcEo@q9BDECHvy>par_g z9Yqk|*H(OtC-K~i>}50rR3Zwjn1fZk9}8rVbWU!-eQR<)BMg)SMuDA~(s=kS!1mRo zBv?hO_qP-$WXe8P(8o9qCQZ1H?~#_OaPTHQzxJSCWJ6c>I^})K(n?&quduC)Pb{w% zN}N8vS7<;WF%Ek*$MCEkURHI%@Pus2_@$#;gWe{~Hl6TlZucupFaW#eY;aj(MJYz4 zB5Zm@CU+@oT`h$CB6ScqFt zN(^&)A-5AIS{){k#MWcFTE&KABI45phOn~AS;EPXdE7m?t4O4*kbKrjuxcN{eRgsQ z9_*L8;_RrMH+`vbNibkHe8_hvFp6)rT0%B2=|B>g45#c>wikX4Yu|S_LPRvxOTdXk zCTKY9PC|v{+p>mQ$ufG%_9&ht0bh(`7D9Q)1;N+_Vs={btWo;&PLfQ#HNDrwPH+Z1 z#aIZpI0dwE<5qP%iAg3{xd0L>ZQV`r7S;|7}BUzA9_wN@Ru^Y(KW*Zy403Hzzj=T7v6nPv89n>~nq3(6mMbOVeaAyv^86~=Tz;Lo^O)-+; zlOd@Dk2v`G7AaR&fxL? zle!F5LP$$6EezQ{&)uriDkkSzHghS|I~n$3a{TB33V=En@rEkv0LphI6K(h^m))p6 zd4zpwiVa7)R>aW&JGPoRRXKlAh_KxPfkVoRLYQm`c%u4}fMDgnQZ1sVlNZ^qeaYrH zPcd}O_E&o&Pi1;U6=@5&3Qq7Cmg z^KpK7To5u>sAZ{MwwBpxIYvSk&!NJ3?|&m$|7?lew1Omwe-BkQF+tG&np*VM#}i6S zV;|oqF^^6q@+Owat?J;S*slJL3e^XnVp}5_EyNVhyGCkI{i0gfCZS?VUJy~Ggl}cp za3%HGTD9uMUdL6QyvPy-B(ZuP8$Yl5Ux7)N5&!~5KRm_9ULwssHTsR@OyVFr71)#= z0miXnoUV;oWCz6BzF>8h+@fi_&8cqO?$X#TAy_bkc9|>GOEVsLOKG+;Bp~9ODQ~ym zfXx)i795fYDM;$Fs5LGW4_NBJlh9+#xHNM!x2yo(-t$YAuto7whzZFy7gc5Q(hu2H z=N3&Tk8}~p@*(|&kaeda0@%i@mW>a9&*M99-lfwhGbn;Y(pEwt!OCX z@^)p`?+^j@wsehc6m}(iI5chSZ(FK1%6Q`oqC*v;)MsKXg23@4E%g6T zn0mgg#3ksYq9sOjlPVUYx5s0@-0(*tXVJ00gS1I;*ZWYK+GmD7LgWMUJy%dM>mI(C zwf~+*<@rVqGfm@jG`|@m4UPM;omJAJnuDF)9Oz5<~IN!{tp0n1FlNMbWvuqGZjh{^u{d zNn!XNM3-+!LvQ&m+-eC{=ZVb6lP|ldb)*dt#0Ugln6U(00-fUnrOB>W1qCg+iLXpf z%pvw|dK6ltN{juWIEsq1$b#q>((u8A4AaXA-|P zA;ZzS-OVpoE+!v;vAvj!XJzm~{y)`;5Xy-vIz{y;-SBW>3f&C)H&W=4<*;UyF26bN z9RWqQ(3>Pmfr|K-ds}+}Q}Z6Bf9mX7?tVUj*b9yJGO%e_X9S(couWf(I7lCJgn@S(q35N7TR{yRgk=OdGSomp8d3`lh z_5O#CV8I#q-7cqVN?=+o~lgd}z}I|`sND#cOa&4~4VmC!?(8;6g$jMDiH>cEPnm*; zOPP4g+@X(92SqUPQPE^SclEu{n4+{$rl*K>vBMnn3Yhk3p~YZ!xF^o6^WD*q&T(k$N%Qc6O}!8ETTkpmR*!3~n&@)p4>c-#xn;HbtNXOMn8L$svz=M_ia5 z=k20uKGW%BzAfWAQ}#(bMPD63r54%*N~dLZ+!YK29if+FDAJdp(j!rANq@=r?5ynJ z5%}@xkF|XJReR;IM^-c-5dFG<7%#4fUvb#2{lC1>A-#|P`^AZFZYu?29}9=kso)nO zF#KTVE+(CKjbS1yOAGt8xSn=~BT6X}Ymht#M{)}Vy6oD5URn$Dl(C(7kZxL7Y;EUx zdJjn!GJI{;e({~`Mgxg$VD5O6m!c~QO>R2%p(tt^9u!dspKkUj@OzUm6l4AyE`Km< zy%~_bN_JgMm}4=C?4gh&I%&&9LIoisy56O-;&7r!2A2GI>Zk`1_XoV}K|7<}0T1mw zeN2Lqq6>y5Z~RvAFx7&ZrQwurgjsZHjtF=QPdN*Wm2*KBMF@*)UFAaY2GMjZx?M*B z3mQo{VxPcY#tbK%r+|(|owq*yo6BLI{~z1)ksT9rXnM#DyJ$J5=>77IPB3c$|4-su zDMqf@*14~CbroYFkE2GjwFNj@D zWxFl=eNqo0fNbOaK$Mc>e^Cni#Q?{Vh!0a>s^0W_4LXm>p9RdbSRmtm+w0Qsgs%5(o>&$bV4bTLzQkiDB zm#7R%gY(?kpIcI<{F0|AVd%GEZNJl>%BJY_{DS8d2!&u#?Ru#O+y^i_f7}%N`ECI8 zJoY?4BfFH=~i2Y=` ze;nC~oF&>)vO3bJxNYkVUCEdB0O!ZIIXKeau&?^dt#Hx{_=1E%8b~=`*}!4d&h15* zxaepLLvd#>asZIuv|+U$RNll6kyS8o8dE>7u3t!NTTt8`g>yhJjAyo*eqMi8t6+%y z^#4&3i-!bQLur6MKVn!iJo`A!yttS81u1R()j5zmZv^Qnb;aa(%jXy1B|Dg7 z&Cgpa%?JEcBrgrIb4ET-h)S1_&5|jPEq&>qHb8Y5lzcLAh&gH{pC$TTUdLF(_4eEg zCF*g`kN|y@?31vGot`QI9Bdc@Z}VvBvtaUTZV9>)v?*-K4pAi+hn>dM+4Wf9iT{`T%@#Tls&NBMQDfb^H-O%86B8!F{rXu5 zV(TCc8ISBIDEv;G3T_$NJFij!a$)g{kWRA)Lj9qDGrR{b){8{2qHTqha{N>X*VbB- zE(Dqz5+`pRoS5O^;lg?#zguVC79W4UrI&YQ?*~RSWOe|gGdWIGYqi)h6Z}3>^=0&* zM;IJI!$y@;9Q2-NbqP{WBByW)J*7a-gSAz^E}KFtDPuFH7NL+1gnSd5QX#m6Kj)6? zPvgXu3Czy%Z79FyixxSI4k={H(tqC@T2ul`Wgf-R^$eUAKv`~qFKOz==J7lk< z)~{G=9umrNDcukw*q1zQ{G9Q-TGuweb|DX#X`@euTJ9-V61d!kGUwY!D7`>}TrY=gi=G8n7v@z)XwD}m%+mu?xD`fF?H!iV-2X=YC zBnr>by4>W552;Muo}sTlk8@WOPQYMN`2ot<2UL#}fFXrUO-L5LW(Awc8R(h4Bh4o^ z$Y%hw0)64;0;y*xurydS*6+i3V4fgLrEHp?L=%J8ikl0Dbay5{F(X|Hv%y)ub1v;Uu^%R)Gjp-HUkb3S?KU%x(43;?Lf3vwHs2?{+q!^6B74t8TVC{62XqCvNz-wYDOSknR5 zd;o1C`XVqaI<>A6IjC_bMd)8w70{~dAT_VW8YMt1!vUAct?0jOs~eyPh>n6>2vqNR zzLHv&AVBD@*8%ZSi@tTA4A8}@foXEbiB^pq91+nV^|1!`v--2k><{pCLM;?#*e*4_ zW~nfp5EwkaJq7vPFJEEocwW}%m9dlj03?!NJR*az<^=JuFvKG*B`OL%pC1>-vnpH~ z|4;Q=VP$C#n90c`O5rH9K>|xoc6f+%YU)vn?dCL+f%gXIBBfn2K{-22r#)pgpu)$b zIl*mwR=DiF3YZp~#gUXywn=}cec;TCx1u`9~JR(37^Jf&J5qt%hOu6*dc z-f(JrKU1H12+SDaw-PAX=x4?$dDy&gV@t6&=3I<(i$Gj)^gY0h_L;=vc(suLXa{IV z(4LD5s`(9FB>KZZvtZ0Sz_s_GG-J9n3=dU^D>bh_Ese1INw@XdQpgzc*i{I2-k~cF zmG1bslnL-7-9+LF0u*X9O@2xa$&Yx6Rnx#8F-#<1m7zNukQdgvl#=S*(bD>48U=QM zx~yt3bxVuxPO3tLkeL=aoUJzaT}U;yl_vU!?!#g=U-$|tZ(?7+_a;|rT!IP zyCDrTo)1T`Ib%3B>P{SlN5-XvPM0DcpJ5Aqiz!joMzKq7i;!6661>5lsTBoX<}8lJ z>OY}+n~e`UwD6ycyY)v{IMr{)pLIx|;Vq}nZf#4JUDE-VxOj#-Wz(xi4K@*}-EPMh zLT1eeYAuxTqKBYjrvOqlv97J)I9NC}oOh-V;4Y5Q4mVGK^D8O0&vpwF=X-~&(|J$m zEiSb@r_LDi-3z9p#NsLipGFz}Mamo3?}DRSbp!aJKl=*83P{QcQb^18<54z_3jLmS zaVKH4V!n(U@q3jel3@d%c;L+pE& zr$`!npObT}HEQ$a-i(bt0LICoY;2l0@mh3G@ic>s*HYy0R1t2DTl?O#EvpEXSR1}M zcPMLf1j19^=&VFr-BEh2AzIHHwO62Y00y#xPB7L=9y(TOVA+wBgdb+ctDNhh+`i}vT} zg=Cpzo5L;Wdaa<1T`)g1(7it4{$=5>X=Bf0w?=DdP0##E8H07@w|56;pHXEkcH94H zm{Nxy;M0nCvYvgQ8a(w7|NVpCyth+a==-zdZp%gKZ9uTz^f2b~HvA&j4kg2q}J zg#fugPgxuuzJ7Inw^#G{(C&?CgNMd%+(n2=nt&MTf+A2}3XdQeonmD?I!#;otKo=e zRi2Rj$}CjCX)rboGyp4UR_5(+^~4agnz7YwD0jJ?Kv%0;_8fK1p|PdhJh7%5pCO#X zZ^{9(1K2tDHy#8^g=@32A3&HuJlYqRC>9Rz+0_lyV1;*lwl5$qkpS?9(8$Esa?624 zu=qpHo1Rb%RveNM-cR0e`c+klf0jxHw4zYWpNg&h8bj5k*K9Cs*KUeSk^4k9UK_=k z+CmX65(dcM&g*Ku^M+T8U0E&}-D{_(OKO3*ejyV@ z#n!Up2Gq33FgxnZ23OA5W=@MT;-qN-M-QWMxe&UuYzjJl1c3HYP1a4gSm>Hw=O*CK zPi}iUeM)2aAMk8`%UFU#m)w8RZ?S+vzgq>8W^d*{jO5sYz%MPooo?#-yk~R62(AI? zJ#elT9{}m@Nx8~%`!N8OFr4LtT;=s*QYgWah%&O-%UG(bUv3?G z4WZl$HI2N3u2w|akpt*2R`+U%K&uj3CwDfCWt*BuQLZcfqYjZFWc63lI^gRAII`c7MWsaN}oPh1XHoWa^`w^RkO-b1`{% z?RYc9eG@ojYC&ag#>|!J(@&7ZZ!Ys!_ljZJsu%iLkpRyUIq<3u8^Qz$Cke=Z30SfS z78Uas2F*eSk4eZAASYbX?3eL;)Wt67)UP}^5Rq(GHo|g(5p0&OKNswIm}}gIOQjA? zbzB*-v@%A%shr2k^j8S5giU?IDy@4QWO5IKV#|{6|E)C%SXeR9`gQT}C!30j{)33S z!%5K1H9Rc)r1+eT7a=M<_U9;eIGc7lamO6WR8$u7wABK#Wtis)WnN#HlU7#!>;m4eI~rWFR1{2LXY#5^*Y&^JDZ zartm_xj2Xg(ue0AvpMbvFr1u!3oIM7WEZZNV_Up*eaR3%&m>}Tt;dyBZ*87AC8G zz)@#?c5#$DKplfF%EfuZZi7}vb7Uj|hm*cV+ijQnw$H>|ZPU1^NBc*cg#OUlQViYE zWOwS<`fa475KZINjy$Z4$Wh)#vx-{Pwes_<>PgR zg#ezU2B2M*b?zv+0SaDUQxP}@anOT;X!??c3bdsozTet~c$h5-+uRNawbW?;a`#Af=ui`EJhhaeSGmwLr)q-UPv{zECuhNh#N$EQe zj`9R9;Cs3wQ#gYAT-0qX-@)hFw4t3cY&HDG>@?UCB{D?X)t!1*NvPf!)=p%XsS}%* zEihC8f-BAb3*xl2bGW#dS_a4L*quq@hUj`iHycV+He%?0`JYewXw7ZQT%J+>bYHn} z>3);3!p*LlJ13(*A~pWb8m{l{EiLypBNr}u=Macb9rI$u60r)7InY;=jx`{T?M*j< zxlz1*!e^*+|KyN6#V!Y1eUC^kAeVXCPg!0Od~c+~Ynl^WmBm^f8w908=YL%2#G*im zi+X!e*7Is4tY~zwLQ91ii3-7x-)N-v?TP|oCV;CP={_>FP*!-`9Xrm0GEG1*0b}6c zGj&y_fmkf+YWNzl0tD!PzPDhi_;b8v&+24bQ7iAF7@B^t|D!$*=W?qdG_m)wttxPFydTHsWH&Hp!qO3TvZIEd>|b_esp^6)(hC>+ z9bM~A5`2kZ-rX+j89`WXDAPsTkV?!Kj|{98b2LQERRWLvu?K37*)NR=(*gYot;LwSwYpm&3Ntv;f^cnI5y zrYi$uKyab$m*KDSnuKwC*uVOwYY-ZNX%H6ADdh2H`bze(Z+moV!dsVYofZR!ba+9T~By<1WMK%bS?HJ3Sp@oeoE9L(3nu6BahR!gpxj)4XCZo{Lxh4Uxy z=JRbmeXaT{6yP!F?t{r7=49yls_K_tP{i!p;w?-gs#;)l!m54Z)EnS(PPb;0{$bkG z5$D0!4vrzi5tnZVkWqANN1q&{re|9FicXt@e_g*XQjJB&k7`8QDO9LN^&qOFzxynX zczlU7qyNMPw~C(yOdKZg+3Hw*C(mPoct@(lyo-hUdCQ-~;#Ka)Yw(38z><3!y2ced z_>Y>H1&kzxfIz>hE9^R!c%qqHI8vpxMSB*O7#r=kRWKonN=c4Sc)26CWf*1MO!jzgyq{Y$^t8~j!O zchnf-k*#p|y3qc$#)WZVrWa4sf(bp@X9|I#<+`LGPX}Hr2$@TmrQ`$yB$qpW&I$S1tcrNbf=28Zudf2YK4!u#--N9njN8&{@`rqTUJ z!poLA4Uy65VFlNop*;^3q5O37eQwK=KjNMwUeBMMkke>- z-EGq8FFYWr;o7rwwItWRC#LB{U2yzo%lP=FqQuByARlh5ad!5Sj&{f9XXGmZ6)4(8b5Hl9g0kJm_Xd5ZMt42G1cMT zT0l?|_aP_;$k9IGCmQ{Q)8qnaJkU7J-pwgJ^TYT`0`a=1Jz0`3TbktNS#$B-+Mg*b z`HRIZO5BrD`-)GVB2salCRG~!v=u6+XFkE=sG?VxJHA>xRWlQ^b_d`Me;!^U;xTqs z#yDMYX`|`6PKiW9ldhCUG-)oBM||N3;Z*#&?d-|Lg*dLw!?XZ|ja$<<7N*hdTr z8RUUC&#-p$C!1$p*=vE=`K*Wr3Z@$hQB=Gme}_4g`Pjv@HNe|&{-)RqR0Q=+F!P2& zKb(xj)d-8cP>$4!1Jj5Si3>5G?(6(sDyhCA{_{<%)mitx0v=?lA4T1C!+s?@3n22D z8j;n?s3oCC-i|{vms77PK|-NngL=w}ch?FGBq8(^SDM%M1y*kSKjA}{bC2-NsWK3= zL1IpW$~4703PRbzk!FYR~H9!-622JEukMfl5a3;O_O{{r?%N`qbP8f2*rj9RU5}JMg@#^7Y?NyLtOFA_GiC7{tNvD zDN{mS|GdiawkkHjX0h`%t6*}*rY|~$@eJ-tR%=lXf zhxsD>Y7=N`-$;g`)=(4gIG^zhc`A2CWUGnCCxiGHQ?vwyfSsHh;*yvcei^G$G9v4i z2>uCMUcX5r7gGV8QHhm`2@_f7QtzK@U?ST=>u83W5m(-S3=gbn_6@soP*5<6j1+ho z;ZKnvifp+`0QBTX$?J`aA{@>IwIO|zDA3SH5B1=a>T79_W4~u0-C4B&&=wiCq}+gCDm14@cQF{0kNom!oG`#%qyZ43?tW{&jaF+7 zab^c+hBUM^?n~)9G|_1H10_X=C?r~{_!M(S7nt=&2D$euUY-px3xu(asU#jj*1|Bb zRaxXc_`~?gd+#|C71I%g1{*lG-1y?eCy2@rByVSqXyFLDQrosfcpZ=jal_MD)Ejxz{opXkQL+J$_+<4Uu-W->6+du=pKcpE7}TK$277{) zCA_p&jpEv!qwfZe$;`I0v2ctm5Q-qvi-u51MXa2R-NtE|t2na|BJ{kyf>5G;L*Jo) zHgDWY$js!?>Sz||VAd+4=c9ZzS2XDTA3SiT|LdqqJE4N7ybW{AbW>~q5|=mD;(yaa zSoCG($X6kNTW%PJPiya+@@_0=X2yHzTT28+!|sL?M~Aa`HiB8kIARbo&>%R<@NjNV z6HuBDzzBYRQz>K{sq+@e*9eCnbrh6`EM;9wuT;0ur%*Ve{)gkOj;lr1{ow&}36g0a z0%%2%DQ&25u@+e!JNx^Vq~N1nM}MUiuBytRsxN?xgv&nV&5%cH)iLpo$=JY-oj(;& zN+D(Y)uweNDTM>9 zOhY&=uJL+>CdTECOohkKfYf`e6EgJBM=0e#CYc-N2f76|7A=0#WQhlJY<7dSE!=9K z1N~9!JGdKcr~W)*G*_T5?qv9T9bSG@EHO%@wXs<_$tWzn=e1`j>UJ;Nf9k>o_1D{Ca!+1CSQvd+%mXd3vWr^ zA{@&NA%MhU-(#C9^$*`^g@U=oQ-OY<{(dT}jg~?2%~IeL zRR(0M*TJtyIUK5zdE@LN9TJj8`TAq%LnYK z2oe+w$ZTMwZHGj(MoW+$VI;s%W-{f>4m~-algbllnd|uJ2=)OInG$^j0fKepa}XX3 z0y1TZi8}ms%c*oM9UmtIqWJb@)7ScBIY!{Eiw%iixuedbFi$fTJ(LbkFFLUT1vS)_&EO`od*>DXEtQm`EaU>kB5a@$NC)UWbA;( z+m|6-%03Umt%goEAW`&HS3d?C{2y+x1^iSLz%{w%U7|hEUR%iKRopl0FG3mmajV&u zfdS3`=n6(P;fuhBvz?H4iX-lPHGos>W{IAh^R!I5jjOF?@l;Ir=a)unS`NX!IXz8k z+hg^jYjof{RRsC2${D!G(b0nGsj`7;CDl%1w*|Uk6u#tuxh&mBjeMxLsTOiBa;>$m zys{nm5Zt^O3JUYRd&*mOVy9K)j^csBoCy;2S*5vx|J#`|FxWa%Q&1ZNwnXv~!D>2z zL-16j%2`SRy)O^9Guu*wZu^G6cM( zuj&2o&Lttlt!QVhAnwhWvR}jjpr>1EsrfkhfyToT>UQ~2)v&c+@BJTIfzU|GOl<_| zKbg~Qv0XQFw1m_;)KFUq;9FXEI#zI8(Y}uH=7NlP0NlC2l;lHgfF40Ij}mt89tiq; z3{l5Qt188HED&b`Hx!z6}gg1zr~mb4x_$ zT-(!**9U%q$kQ|!g^}a^UJFE#o0@!PG@FDpA!epQ;WsTA`d*z6;xb$o{s#45Q;kL6 zIJCQXRiktJo)p*XW07Qa(~h(0b|pbSj-jt{u5xOat`O@rDPXo->YFqV+E$~^^66C< zm@lXYiLJ5HJNuI-E&gM>ZYNEoNwduZ`N|VwKQIDMeKn~=-@n%+IfWRzLj4ON7~6tbN+;g^X9Gs2f$m49ydKii6;Sf>^3qIjf!I57%=l#rEc8DVcE9C7J~hrmfLo%o1q9HeCp%uS0vd%aow1A@A`yv zF_RM_e=fvWiftxEs*x$47(o{iPLPOaeafowPvrTgF_PQ&pe#2o(3TmjWWyfu?3T@*y2eLbbJar-8{ST(nO^ zNm7vj-pSj#o`-N>(|1B##=jXd1nUcA$Mf5G`hial5f1((fm6>M7Zy&OME}r{5&=}~ zgioHU3TY-{`xatiof(#+95Aj<0v`7T19u+nnV%9ges?Vxx#=EV(H@eiMFUlrzqs4> zB&j2Y+DCc^08{|tyhyE0r%)tHoHy8;qCLD|M3Hm#9_zq9yFl+&ef;wsmdu++riTa? z#i-1J`_1tDW^jR_VVx=MNEhVX+Chr?*!+*oBWZI}UUnQ-q{TdS%n7Q)Zdjo~oD^Ru zyYnuobtN2c#H(^3Ahex|!SA{>*tabtBWO*~kQF4wx%&HZ`FwqdQ40Y_9!KA7{5h-H zUj`#CFo^0{Cqk~tXdZz9t+BWJA|aWs*lf!9aI;#R10S%A)d-!IDt2101xz*KURKTd zdW|L5(|`>{^0DP)|MlUuVdt6F`&7r@+Rln&3`i&9%s(moFcudgO1mJAqO;>qP??t2 zChHS zRn7V^Dm9)6@3_7!BY}6ROfMSdi1w=g10COY3D%2B1R@|n&B4d`J3?D?9l`9s_g@pv zeTBx#WvBA7dlmsMEd(wxg#LjSo2d*!At#j+W!&KGn|~t+cHPG(h;doA<0s3jpiKx^ zymw73mnv}}7@o-)F)&Kmb1|hec7+F=Ku$l-L8h^Ft-nRSP9#XkuF8bECcEBA@RB9O z#>@SnjM8cA%pwrYtLk`n(`WkaT_i(r1uXPDlhdlP#5{GRQteuuoO@y%Hk4)afHB>K z9=agvug}!;jC|Z_%Q4prHdAExp6L_Vxj*QUoo%`vhwWFpJ6}t2ZNu5aCGWki<(FLg zY#cLwup?c%h~Qir-6c^Ec67xcN~f&f}_Y>d)kV z%KOGB-qLCU*&B@@E*bsngKfD^$T6?l*I`Qzn->q4{4J9)e&rd$Zz^^V<5c_q#$fWs z8o?=V^X(ih*GWpiA9LW7aOKGRzRLq7vUv9%)PfeCaxMY%=3Js*!m%9;xQC^T7UnAG z19o?>KxBVtV8I#${;|N_ut&JRKO9P>n*`~(6@IqZnH#xRmGJ}|oN3-kO+nI*Hu^%1 z`A`|TxP!PX@?RN{s?irnC8q}g@QbkJ`Fd=J8GgREvc%IPt5K4Q-aUx1 zW)(%6w0kPTsuv6mtdQVY{+_qbG%_En@@4)H4;q%;eSW~ewrP152o{rgs$TM3f8{Pj zjPK2cl(7%P-zYgVU;voRBE4q1vvlece(xQin9EY;YnRWFC%L~JkSQ1jvdfxpl;Tv35g;4UtuZ;A66;G&N9#S1hx2(xpz**e< zL37ui7x@+pk?|KpYXQcz6tE4qbAO;hCPV)6%=H^mYK+ndoHEcPL#yD*o|i2{2bl^dUmZszZKEWZwgE3HvXc zUco5~gPGH|KG`PNu}u91q@$8B!WAG4#y@RkN37r2Kxs|JZj3 z%yAydT((6s4O6Q`Dw2hgM1Lf}I1|~*{hI^k7>)u1f@gq8tk#^>mHSpV*Lr##a8IgbYeA_ zKJmsu*OBVKB73DxR~W}AeVAWEQo0t)dL9~Etn6c-6x*)sUEe^Zy^2Ki4i4+VXOF)f zWn0)Fbsrs9mqSj}dTc&;Pv_@ente3{uJ`Vhx!8qJ7#9vr`Dp+Un+W8shcL{Yy>GYa zFGhp4ML@0in@4}NY(Y50I2HO?+Vd~A(>{be*{BWf+MS})7cfTk%sa2@3VKA1BrDt; zcJBd+mutmstcKF5&G*IV5DHzQIlzK;>-zWSXiki)kBVvEVJ}UyeXSGKUr~O-etVqM z>r&Xz{^g#Cr?6lL`pf}FjwwZfg<@BQFvX(gMFp%m4%=kPLRgm?_CCpJx>gln0)#NR76=vnn>VCWtAP~%`i4|7bD2c`{CRrh;|Gx~n zOALE8F`$d%M4#?NTHRa}K%1U(4mp03K8N|#JYB%9!zbW0h@8F{+DGhj@w9w0K7S1W zSpum@Y80Ag2-^P~yW=*thQ#r`0_rx7}NartRHOugngXb?}RG%xdcsuuU=XfMP!brbbIFkO_g_cD9jjV{Ke z)i2joGx~7H|C`sPYp1PdS(~WCY~P)cFtAjtTMnDs^)|3yFFJaW50&C?_QO96Oj9-4 z^Zld#93F+U1yE*0HA;G>l|OJ%NnjXT!Gnd2tVdM=`)`c$Pk+odXUVey*>M(jZcJ0( z)R0s-whd(upQ5v?d`ZDl8=T!q=#5Lr%^U%Y$SZrkwdmop&6E?;MqWa$E1K@;ikOs> zic{|*Fa+vDwUDYmmP&+N<(;YP%;G{tr-*+<1FKtrAjna_0%FTzk9{7?WGG%+jdbi1Aq9DFHf)TOV>C8tzpD-m2HbpQhQ6CUD&+{EH8;Bk0j}D~oCln=) z({$2M2kA$05e~DYZR>0UH+iJ_;=YWhor!U-*&a$zTTai_3E1aVr*1%B=Bd!}noXWk zKmTSLfI!^0Jygi(f~h;L%{a3r^R@any!$r?5%wwm#0+-gJVKxEkQ7;-e>(>*aW`UCC^&KwW<6Lkd{YpIuM0f0~Ey%vXld}5*ry-$z(ZjT1A_P;i}fGKIGfhBtC3mAc8`cx1_m$C2z2lB-orW3b9QOP>5v!7R}delhM zD;|u6nCBF*a7V*ko#rP0`zur+m+!mS73HoHLNv43x)`Mo z8-g3=Fte$cgX&@q^N-c-emQ+s(9=jwl;V=5g_HEvK#k{frIZP~*+aAen(s55%RFND z%Gm0ugsVSiV&?~g2Ms%?1HNd#lQC%*kNS3mr9?FsTNUDf>YEv0K~7#P4|M?WY1Rz# zfn2j_WEa9W)k0J8z$(D`o}ec3slYRHZuAm*@gF+XRIxui=C2Qtd+}F!tUf{OnwTl9 zaC2767j8I)0>uk_gEDRgZ|Zu?nH7D@Ju14OEIM@Q4|A@?wVRHjmSo0O>uZ~Yn*734 zWi=P;x^_1R6}R`VJ;h<(vxO;|crEak^L3LVzoF=$AFf9!GtYL#xc{ zq!HO}OU$>vXIBaD+pJrVv(@}h5t4?~;eWZt89z;f&B5&V?c+6Q3W=wJQ>1^7JvZ`R zscY4awRxT8t437Dy_R8#Ar+ZI^vDt{SJ%WTQziC1G35AG7w&c18H;n;=O5A%OK5I< z3Ch%p*v%aA1Rt0sZe`b~N_779CGYbhw8e1;t|uX1j--0d{GX+HoL>Uyg16BGA6TxM zUvV_C;sZW`fB5L4USx$x^Ycy0dv0wrK_aizgkjZ{s<}QWCyZU%`DSQ%cKQ1e^Kda! z=1L)$FWQ)_pfzmt`(v8Tb3WeCXGp$ymBuzDy^NmRXaWLcWCcJHTaS$(j-z@A<%$;^ ztL1X@8yHFhRhrm|ter(WC>uNymHBCb-Nl|P{&NL=1rvCuIwM7>K|AWj)GBFDu`wd;BBY3ND^!F1 z<~5#=1me$}aG8tdG)wV7`~^Tt^M+ANaj;IBcz*02Biaw&j7&?A%m&%AP_Zt>gZfn` z!Yo4tkUXVDyj%iAN|(*4W@=$3=mRvya!8UK?;3#Anv=$d(w&GH&qFo5E!_S!#HaRu z+tC``|A|Q0i7#qh8Y<{sc^KX^EKvZnA-M@8_v^9^2Qz-7 zykQkapOMQfjv4&>$9Zpfc$nxS3VtoeBKZvNVV*KH%lxo($1J2RHqqyT+d3;|-Y@hX?bezr_?KU|z zu2jA&#?Nd2Qbs#f;F*(^Sar1{QkM9T+0M>GSE6djUG_b&AwyqlM>4FcDw?PBk!U{k zH%u?koK>hYKYt~J_PJF_b$pRM^A+)pYo#2(wME>wqpfvQ=yyeJVh}6rHO>B9xQRqb znmoA^-;^Y^s{}mm)C|WlCpO6GRTfXEHd6U9(nyi+TDsL9Jn$WO0~aK716jzvjR?TX zluNqj^))69zFw%Noio1GIJXJT94!Xdr3O{ji04JHPn+8-=DQFQ1)lBbu7Kx zq`2-d0b2b?ic*1eJ6DD=k_YG-v}VsD7fWCO&x4kTyz^dXp|&gS#Bfz3o&?_k%ujWOVKdPVFtJmZq^1c|(%JeOGVgL%n%pFH{d2hjdI9oRCf+ayXMD89- z9aQa|v;O!MW}F#1jO9@EY_Z&>DX`+f@lIksr1iO+H3;0Wo3P9C;Pr5t$|73B0~J&K#$kmyVZ(b1MB(E4?fZ^ zrBNO$d~F+ZruEal*+d$>6X`NAOI5ETLCAe3*$w%EQg#W9$m3F8>*8>?TKDk;sJhKKftKqDbiXpm7!QlQ!+dwy-^ zGzMEd{s`~ea8*X=At|+Bo6V!#{5+KS_*Sa9k*Z)1*4AZz&cp>&woW1x+ca~ri-Tu6 z{VM?PaNdAnY`oUj!=M2{j;L}im|;LETB9xcfKMzjxkN(^Be9qH_btHUdDqn`yNUBu zU!RI^+!%sIRp%~{o5jfL{T>)yOcV9vWJ-^}`dpyJ=jU3Clu8lv1W7vB()&7qKkJDo z6EI%JqoK7&GvXQ0D~|%~cwdU7G7`kY2dr8vh_+R2J!Q+_?}oHp#c zhSuBP(_~;`uk!VB+{*jRP-*n|M%xaL&lnv5AJ4c_$ z;@EASp)d+`2!}5a_#1rPFn>MFMgy}2=2ThfbOpv(f<2f+K%5^$PV<@%B__d{0;6_RqHmOJ7ifj?x@l4k(Ct!Mm z*b?T?<@5QQt<&T3ciB@BGsOLeK>ccBn>J~v%AC-1=arpL^`5&;-8lUHLmZwCECF|) zybcT9gXF(9RCZ*+c6FVmJp)-A0m0%wr8u6s&%rLM%Yi`GMl!G+Ck|dk5Z1u$RdC3k z<;`sA|7&6RHY&VlidTCzxp8!#vySq%0M1ac6`ajy+r56@yJ8`5H(S*P88?{CIHLuq z0b;xqxU~3M@!T310Nk~PX=IFz1}g^yW*_rqdag%6Upf=_mL@32b{Og0)X6 z#QO4h^36I7jf!M55`Xgh5I31G!?SY;L0K2<-%++)_<}qe`ba8mrCNNh`po?xOr+?{ zS{u+kGW6Hhs?q4(5P0JMeYv4ptnETzu&WmaYlB(eqrp;1PL%^ZNeIY_P%;z=a% z+(i$ok|ymv8KZY>h$~0It#`#|Qbc9N{^crX(sxSXuiw2K%6&BHB=gTyZ1TkpX1zK| z^_2x!+#bEVx*EZ^oxQ+TT@=YMOM3YK^8gz$QP>8sdoBe+^ii{bi2i7xE|*=ws7;Ro zDnjhW3d&V`+5E7ME%RD!gYtSi7g>xa^X*2+d%bFac*^+k^16|Bp&N_Lk*7EBS z6LHg&Pl=G^f~g00MK=t$xv+{C^QPKTfbO#1v?Zk#ns31#TW0 zly^%FnL6{48%i^kJNF<}vR>f=q`=-RhV7x8mt-QRI=3EMV!@uxqBC8;o z8WH;+Uvd$|k>s0^MbSQsTBk5PT#6TM#GqY&lm0&QM;$W-sv)EKx#Bop zaz`_)p7xD|sWTZok_-_AA+&8K?8U@V9hDij5PSt{C*=_J6@tNdmkY&fO)ufy$kvT& zuxQ77gnq@JkVU|*6uoZh4-&$2o$Fy{ADAmr7?9NE?7B*w9Fyig%kyzh_j5}rx8?fX z9Cn$!6N)5WQ0uryZ`1dR6mgp`(lxRp&Z6*skbcTt@X=~P=rCV-i+?PzFUg$eL4uNv z#huk=20qOap@^)@oj$`^nTc6D{;C!rV0Jb5+6Ps8Pj1BHK6Zkt=sZ&ASoSH`^&ww> zE`NqIaSQ$%(tcE?J!+v>ImT3pH~;P8^Cr(R*o%E6Z(s~J3Zd`w;4GZ}DV2*2urFI(Z>aeXc}`` z#T#kT=do#wtv0piRgU-*TIj#hl^{qQbw6;x4NFd)=Ej^hAO1JWS_RMJK0+H|$HK-J z&=$NdyYm$hN1g3*(U2}mh{A7&9%Kj-O-3>hA?Meveha$OVDz7Qk!wI%*|ET#^PrX; zb@FI--_@NdG+9%HarsS1_NEK6cfLbWJnZ6BJn1uKg#v@t&QA<2>XIYqnop518&>kz z$)h*t1|P-zz z2RPE|q-}C;AniF`fYuz2*Kn&z`#nGeQ$$jY**C}W{YNm-CXp?o1y(Nj-q*4k)rpheag|&-{UsIgfX-7$bMwg0Na}wsL4JDJ=a+Fjk;Dv4RCK1 zi4~`yHVcyp!Z>$CZ^1TsTIjM6VL2v7n+~oKjBj@0N$L$;JN~ZOe*4`L>7@u?f+vjf z>sTe|Jw?DL<TQ3q+iQL%Nv>h{vh@{?g7BxOJm^y|rkevhsgO^wF9Be& zeu)Y*b}6;*)K=%$XaEEfeM(|BY>j!^S5Ap3Kr74Vhu1E0> z$Aa!$zWe%Ao-7JpggtratW0V+1NE#ayah+5dKn)8yr=U;vDP?z(<3)} zzJQi)gLfH6B&Dk4D4lpA)~kw}0ga(&4b<@}s?}=9*u3X3Kb>uCB*H)YxwB5wqp}!} z|1mle*@yNSd&3qf%JeHcKQY3Hcsw!g6F+qT8sUp| zr7X->rT~B{mA{&?wGNB;6tl-d7EBlBgjMqw`j?TJPodEZRq473n&tWJny z{U_R$RU|y$&(CU8?TmI&{XtxO6G#%3`FApfdzY5fO|xD34@GwGKIp|5Li)EILydH1 ztf{Vt2m)>~tH@l=c_q2=(E1~mzs@wfKwEAs^mf3cqrM;d&hg^Si)?I>_ke8=FLVAC ztP4zWqZd1$;zbDiArSs#0QBk}95_0y5XND%xHjh9y`RLh~rZ>uz5a*}{O#$8PQIv)f2AnnWo(T0&qES-?& zZV3E6c+|Xf2L>z?d?7NgxsSm8Vqw&Cg0 z2=A&Vv(to#5@`%tclMFa)miL-H`a$)ecnOznDJ2Lki~0h6$6Z^B!SXWMA6Pk zC(?{8NPd~g^WBt$G<52*b55>W%2G>4*E{^F2u1{;KTMOU$1Z}n+h?#ef(FsF8x>W| zvCS>SD@0D2H9335O+<-gre>&6WkXVrA1zgRCRdN!t0O>0t4x(`J@P09als&iiV}@< zg6^YAuAw6 z8P4a4riqaP*2+{jk9}hLNekkX5Q+$e7JASehbfTV`@S8N)ve?o0I5NQ5s?itZR1Ji zAIr;uF(cLWg7m(K^ba2N{#tReUA}2ACPP~YGOrhYT{FE+pZBY893YBF{Ae5W`L5Ip z#FKE9TmnpihA8SFr-)#7AG7a^SVT;*7Oom!>~~++O*cj_w2GfCn|4cSbdq{|`qsI& z03&X{QEP}v16W_j{>;12`RJ;=il=c}=WO()cr{Ut?Hb6cT4LB0bD;im1F5sq(Bd-B z&0__5q|eT#K&}3H(#SEOI8g|E@#2t~88y@2lKQ#78}ZJ+HRuN_GL!YaA$O8|d+WB@ zXB6;cyXDhW%_y>~thDQDMlI@Xyjv|>?Y|0!c3PWRmCWB#i6Ss<)Jj(avJ5fsHAv=K zwv~>CQzt@+U4Z?h@$M78C-Y0=$TvVEGBYmaFA|Q(6%doz$`p5w-xqwq5iXT+6r;-K zs*7_zj8~Gn7w)Z)3XKe%mdfh=w(~QY(bqV2^gkkLPym2IvwjZg>NnWC`>aRniDJvQ_m8Df$V!wvgRnO{Ys704D;4X%U#~W(_|f6 z>4YQ8b4KgT0<)}5Ye>VN?f8wfpV&b5j&#yCbauFv!n1;WO(^AKyI*uXvhu=6}bd_;UHg?y8n8vg3TBY>WySX zltcML#XR&8J)TsQKM9dx>RR%I)`%jQV5p65^Wk|cVd2Gb3dQp6QolyxuW^1vXK?U} zqK)p!WJnxIVpd=lnKv;&ZDa!H1u6u3jTI6)<24T+N|Us{!>Xph;Tl3f;(q41rUN+B0TW?or~1WgHta`sJOL7>lsP%bRlYB^*rMn+9=Ejd8=G80rjU zX+`l`PVzw;r6r+A5@G_|?eB>lg8%g@+t4icCCS5d^)5!x#MmjG4yTgE(|BjsPHPUM zrRB`tkj)If?eK~IK$@TMnDx_NHo_(-v7eM3c6ZPKleJi13RIP(#2pVovXtBco`pyF z1WUdG6#A*o8@cE>ivmF#*~gTstBY&mrVk4xh2y5=QY>~tlJb;ZBy26PcvWj#t7u{MVkso{Q2}SI8-?WPm1o9f*ZCn_G0+TVfy=FCCcWQj_eUM(5F(j}nvh5JXHYoU}AcCYaDLfkqp9-vm3P;6u?hL;_<6#9O zavxN(b|WZptCH%VuFibJUXQdO(tswr-y@(Zmy18cT$0yYIngG~ojZ&{Ahn-M5iK(2{mi9XCbG*T zTTsv-*2`6d^vy6c?Yx*66NsTrPdRTW%=PZ@-2BTd#7uNW4y^dc4dG-2l4Xg1(4LcW z^X0!6tN`}fJyP-S4E)$R%&UQImH#^uKn%?|kNGxs5G>$b7`JxIN*eEU#x3tZ%QU&6 z5Q;i)sOG>c@N4`V9}^RkFl;l?uLX zC+GOidhPD+COCOgPgOdPIR74ew~K$Al99IYd*4Cuom3A^qR3 zexAGHqwtl7!1+5TV}!@z9T}Kr4#Qx;rMpJe?330uSqxHZbLfW#xkgamY^zP3R~e+G z?*AnJ-oLKSwx7KtB9Y5&n>?kh&%Oko)!v~WSF?&~?2iC2$ln`>nl@GXQ7jp z2&GLg*ltF*Do+*t;Bs#JaX^^|S_f7(Y^VvQxQaw8^1`|Y*wDANR+JKj_x6TYhT^0! z>Ag%^Xd=oe$|ux)JY3*~s4*LeXF~w!bQ;H86pV(muqOZS#YeyiFF4W#+P{i|?ra>! zncRnPgXI+vh(`c`hZ11TjSluBv6SJV{-OEuP`rGZoxbg>3Qk|uvi{_^;65Z=G*oWx zD9fhgl&xu}7#0xH=%==Kw6$9NOtIc!Meo1Iv@x60EoSAcwz+~*eMkvF7dZPl+g8x^ za=}F-Xa0NUOw?W-mIdf;;OHcuiN^JmR2-2~r};9=M-ztB-vqg4U+8tGK`eM>@(z`g zTwz%0N7YuEjGA;~sLOK#3E7eb*_MNOO?CKHa;)J%PjL?+)*wu*X}W{PxVmsVaV{pm zG42!ls_j@b!99(7d+CW+7E}fVOe>7}DY*|k^T5Q9As`vlfoC|L(Bw7$mHCzo(nbIu z`T#Jc-i!2kiY3QEs12 z&c4c9Z$Gdtt==k#4MrMoI|Y^ziyH&hEf~!E4bsKHqZQiOvn+m|!N2h<(}d@3IPT2i z%F`K@PB&vvLf|9q=atY-0?S5^$#TqQ?sVT)DoMZVpB2&S2<=RCNJJ5xI6WS{>V2m( z1wXiB4E_J@ABf0Jb>p~+Gbi3iIAU=3D<{Sx)8@*8h&iEd<+V+yfuw=j9<<)(FX%>a z-K`-W_8=i^A+^h|$q8_x@ex!hYyz=?jxK&6)#;x>{On>IehRfyo{951M%~E6i5XlB&%Cep7p0$hgmum3qL3Vs@j=8=57Cc z_ej37XrTeNl_7e)3X4yQnGMD$zH8(r;Ovbxv@^!%AnN7I#(^eThyvZ#;2rm)=i@*& z0reGGrH2_zMD|bT;KnkQ*TPT#8$d z|JfW+p~YXqo+gPnK6P8_TbT97h+Qv3`>6GGRB98b(dg%&77K(IFBuz&65zF=(TAWn zSj>F#jBO&)X$yb*59uX&>Gq+>JxER}{4Ob3Ep$d|OT^I59tG*t&Y|qvX%1tf1+veG_?cu?qRURGv!{ z+|R$jODvGv`8k)pF{j7i{MM3q%t~YL*-`{(c6Li;UhEB#5^_PPo|SUBP|3OD?ZBSs zB}YHjgR%nMtE8h1tf=`Mk%COC80aMbOQ#)nEF>R2tPaqSZovJ+yzG#HW#|PMuPIsw zLj&NZw|&$Cb+6=A9hMDZ1#!eUSK@)OoBC7EtA7R6sI64E=_W~(BQE~$9WLK2ko>7u z?)=LvqmbE5PmIz7LW~oxb#IqEZH8CroxIg(rVNNe>_xewA-*WrRrB)>O6tt1n)}8W zl{qa$>it3N11NoG0KWHdY0A`XiV;zf!xnd!?g382#=={}ngD2Rz*Zbi8$-fdxS6DOJBc0fKueT&X@kQQxomo)7IAdZHcx1saoxf}W)VQ0U=+nF z##T>73)Q*P&9dfpdBmQgTACHi;9zJTtBY9d;$HQ0*%jtbtrWfuq9-BQs^-w-)i1uA zL+^(iC#%JE`Q-g3X5aJ(BBP3*fvCwkQ{{CLVae)DPmf=`swutGYz()3p|dWfZ$77k zQ;ognKdaOP%9aur?4n+Q{3A9~KvGUC{_CM@$I{AT|6h zm88ud!OlP_2)DMh109}KJk>COE;8<{jSUM+XL2Nfp!bf$2CmJ|hCD0)?Bn4%%=TN>0nL2EfOd1% zvE^LMap5blFW*RY8q@Y67jRgiLRY4n8kH$~N${b42x<;D;1Zg?6wmw|U`&WMj@oX^ zeY-?}rPw_`FUqyMAsDj+C3h}_#2oG_wQJ3+@7bI1`mPJe_GFOa+IS0QN%gmn)|}qG zCUu!&01gEJ(O z6wjK?|2!4oJj8Z+G?9Fzj$axBFc%Gqwg*ZKHPMB^hk=*yaQ$fWBP(SEFopf;PJRFY zR_vYb5vikws-= zohB;ue)jjfH6u)$O0TY)q|8&dLf-N4?HL9Q&?I00A}6EGg&_pv{L{47IQv^H8Rwv5 zA4;s(xTtYE!MIe9OmtrH2gU?2S z+vD@>c-kZ}tle0PuQ}A@A_Z6JfsR3FmK(^&pS=zaUyF*2RdM|;m3iRqAgG7f-@|C1 z3$MGJEpmnNnD}qU#?f6AQ@CgF!zLQeS4{)&OaB_C<|MuFIA1>l0eN7;Mr9Ngw+u;u z!g^?C2_Y#JnpHCAeG77RaYkm=x#J*9ojqD8Ge7$BoYuWwxKDjmeXTuZr{&hW;%i==->QEfPF6C`50ruCo2KS7G@YvX9X)2N zf{#{v?SckRn=D&baTX*f<5ez+Ma$3WJ_{hTNQ0<#$U3pT2^(~xd3BCZbIi@o89R-H z{wQMOB8~YfK|1mqu$p}*98LI2SEJ1?@NO+oaEcB3{T)Axn#f(r=Pk85&}p7IoxM6k zcZi*FQ=Bc(_Ku_zQIHVmt6#|NGZic+thVwD84AOQ&9dlZ%v7TD6s7@cU8z&;rxFP* ztaX^uS>g)HNaV0mN2Q2w^=dGX?)vHilSxIgKTkmkJhK}xExl^;K=?MeL!>p(b0E=U zo++DHSf4$>Y2?AY`=6&V9j!i(Vk&?5f{_VN@0eDZN?(4^Kr#IF_M_ahkks%8PNNv{ z#+gRQQ-nFZ3zh?IMt{2`F1ZGn<0S+gcM;92Hq^s$JI6T$h$}2B;jBY4iFr1J4i3lW z3rJrX`j#>#WElld9ks^Qy$G?8W&yQ|d7|2aKSA;HLOF)1=ppd^^Gq~~yCn`I1 zu;uh<772@xmwit!kt1ble$S*>I$OZ!AoIsEGHXr^>6-H3;FqId%TB-c@c&BL5x&B7 ze!Q6(BXLv@{s_Qgp^6mMpwhS2-hK3}N4l&6i)ati zPP)Serx_RpOf3XCDuJgl1`t=+fYUV!nAS&|tKkff#Y@mF3gON-joPX3nW=)3syg6focz6pbg)ZoIpR8d8e5E*UN_ zIs1Be7HS#Ng=yxq3$OC{zjb&xe79k2sBM>1V^!UoG^%_s_hntLTU*z+!1TBU5GT3B z8Ys=~VGighFiujt&_Y}9eHsO}jX=%sCU}Nek<(2T7=dfyu*E^MhJl$P;30zc7ISq# zKsd~rA#p0cvD2~)PWMW3J%O|+v!A%(+772NMsKx+S<}44N`wfCoD(7K{E)P?+34@1 zq#=}Hv~;YCCol-Tn6VU_*sK0bP}$>uB$B)~bYrstTQS;6?alB2fLQ4AX%R7EEKOQv=9H^|VFTZ(`AlCix(9pSfxOgh$ArF>dbv=L#7!7arPZ+Lkc`OoIyyN&#g?7zY`g1GV z$m0s|YPcnsF3-bgrMFbu^TNqJiIm&^p!0UaZeKP2r0yKDt=Yj8G#JY^PMyVwzu@2p ze@P0UhjL&L1Z=byuSNUWh8}fA^$3DUgL1jyC#80sCxNb&paetxdQ7Xz_fkMOZjxoSgZ zVdEHGj%|(rC3S=`E~kV-&oXWsXp$PWLHUHD8K`pLi_ykd3WMYFx?n^S>ftJ`i(z!6 zYKgFq0NUSsTwH%>4w1xlC`w;B41Nti(OcMtKYSH!LrG4E*x^bl(jr=$ni6`sQ@u1z z&zMnHgdAgByZ)72O##Yc3_mZv{oTNKNZm@YTgCFF*2NPi?cMWnGc0gtsf$+(BE329 z;bCFcnrIi%w^26R87(!PPbk$A+`EUybVW+ub!W6Vk>9qvQuP19z3FK}MOMY+H3-F( z=D+2W^{LmNn+J7%VV|?zfW}yFPZRXypdfkh*%eO6#ikFGidzXws5*#;>E1v~uBEOk zb+W`Q3efGx{m_jy)sO6t>#5kz@~mba6&8&+0unrQT|nx|PLmI{Dn`H`0i zjahlw!Qv_@btD+c0DDaWj(7%7IL9m|czMg1sUMQB=hvR?6&dm;8s`cdDm{Dt3Eaj} z^2d0|=|IU@@$COaZgWGU&)$t84?NODjw(A3ZdUN7t(hgM)VuVF-HG90=H<8|l1_m& z&Q_IFa_c`#HM8rUA*#Z`dgC62Th{Ewar~JiS*jHaeiYIipgyUoyE6HW_>dl`mZxo= zKm*vR#B^4a&WrRSquSTt63 zrBUj0@+q(n?t9|ko=i%VvIG07C+=1xY4d@z%7K}GRuD}qFOQQ()P2F%k@ZyYz?e-~ zQE)u*Xk5)24+U0lT1R244mxc)SN>y9t()JzuW;QBBT-ffeAHXp7GqZfh12C6FY!*K z#YSdW)qEK(PzVO&y<~4^EikC@xMvco`_OR3jvIOOPM7qp9K5^+JQQuYvQ$~I_W%j@&}Er>!aFkZ{^WES|B$+*;-GYz7S1#F1R%ejX5>K7H#t06 z^#wLcoOX;w5b8pvn=;a~V@qFY`i(-mlp*rA1o-zjYK~GssnomH!$VW_aYW zPkPaCEjjM#hXfhTj+d&)73m~7NS6$oual`!S+=Vk)qYifSOn+}7%P^xJfe1dYk4YJ)qf%Hw#b z27h{=&Kc^gpU>pWJCFjNu9unXAs#+Y{8{sHOBkezax##yPWefy;b4$bbeWvbjDvq~ z2{(HX(e0u6Ex>RH2dCt<2<0}t8%2|69VC$sLE=FI?*RAOf2;ioJYP)^{Iw}+N(ORe zm{@|&(ay5NUHD)==~$dE09zf2Sr@WtkPnLm+Cn7X(lhv3~A^X<8Oa?(@^k5eD&p_D~^9t}8w zO{jP6P_%~z!A)g2^JbUHu65_V+gN-W5yT}PBwZHiRGgC*+_q1mhUCht`oGKUJ~tgi zj>%hp*>@~O7^c&xg+H^6EY0yr*`Xkj%p!+8!c?UTtg~W($SF3LL-#Jf>j2_zi7@Iu z%_F*J6whgbV=ggShMl}^$!2888C*0>nV#y`Eu04fD0;G~53wro>ew=5TQTdVXin4V z6N7pCfkTk?6Kl)cIG^(G>@qHLw*%t-C1aPXi3J52L`+{k~Z|I^w-2R)c? z0dw32shm0KWYzbEIgIic_m5pPn^SmuxQ%kH8gBpaE_ho*QAJzUoMUu>XJE&3qCqVlvn?LGnsL zp1-YaUr*||i7W_+pLcK9>ijIX;sppz{)Qe2_Wp#~heRL49M)8>NxI$K$IC>WrohGK>3P! zOwv}WfN_^uqB*Ls;8=T9E)t&v*ckE_1NQ@>-W1*U3yc z=T#nn^L!1Ue<^7M2YrN_$lZ26B{ zC-(a80I7lnLoN3hrZRA-K6L+bXszb{kW~^16hE&gs-{3_0yJ)|ZTH3%xfOKRLYjym z-tvH$y^dkiL?!f12;Xwpp(}nPQg^M?EP3I4eWi=Xiboe*V&4!}H;R}$k0F>X+$KQ& zLh{WbL_Xf*hiQ7w2#^(AlAUs`VOi%a9tq<9*34*Hg3{ z*Bd(X&E26sKkq{r$jWRR-~+Lq&h5g>pJv>&eP*u4baVZDbx#2U!!daK3UHQi9ddA> z51INR*_`zUpik%keWMU2R-X9t0UV$tcKRJ;wDV{FqdH&eHYh zQh9bu;tEopv#P2xJu??g`?)YR^3Gl28nWYDQw_?dj?JAJzXA5w-TeiUygUa%i~SA% zJy|@G7@HH^1E+wtE@Sg_V1Ef+#7HEibA63Uzyv4ngpvw}cDLcD@JQM$x*vs5M6vbl zI7JQ)U!!j@GwCa9bO1^!yBtHd^9Nq1#&Ni~3gosNu)}ME&lNY;FXZicf=);l*V{V0 zrqXRPp*qq$X87atZAMuJj_%tPdyJEmQ$P}UPzCmFYUiH4pb!zQMagjT+vVYhxa<4_5&@i_J*`nj=p3S6lLW25} zo%h=|mB1!?vNd@ymhw@uREfwHo+wwVV2PuycHOX850ZI5G+Z*F?_h@QWBJ9Ct%kg} z{YcgD2;f7qiP$R)cu8-JhdGW;#&kqRcCd05C*^fn+1>z=(__G%)@gmnocJ)-*=ah1 z#f7h46(x(2TXys)iV!Zs$rejhEu_hy#$efzVvSQ~SD(8LE#Q(ks2_&auLrDsXG?0#*BhsVe2_n(Ri2kjM%rLtYjA(#*lNGy*TMS>;La@>%1jI=*XAqBD1%iH?{O_si=_ zA|LKzzhy%U{m~X!DHb-Y*L#059(f4OLo5@ zi}1~C*e!bn82Cs|&`qhObHts7S({E-8Z_{WsbU5ksK>Qpl|^u#RU-C3$*AR#s|5LK}MelD`o9%Gcosd2mjC%KJIha6V7XOs!q zX1JO71=ILFK9AIUO9+pp2(@HfGOS75oNPu_pR}YwlsdBQPZTzy%?Zp(LfBX~1lLpe z&06u6L9!6$!<8_AS|Yobu3TgCT~EUpgU0;IK=L^kC7=_-PidP zTA5Whk(DSrTPM6f7_4b-%fGQSiO&_41}Zt^HeG9${AI;ljcD~IoC?kJJfD<9>GZ0% zHCBk?EJ;27x((6fM7K2bk@c%^){#-yyB8|cPDunIx zG`UwKu`qS6wz7`CzvNC?Cm@MD79IvTCEgDcS3u>W4-JEs&cJDg96kx%Ii#ikk4c78 zYCSGJ=?7wD{H7FV;9@6jLwGBgvw5&(3a6i#QNFaKbg3UgBYg5 zt&;>zg_+IefD~4eAdE>+#dNjK5yR&ndx02+5-QVqVc4hay)=S7SVi2$#s5^Fxhv)} ze>mFd)KZ|3I}hm->J4m$$deeyp(%we;D}8igsbVJj8c3*D0O647)Hp60klTB%|T z*duDcFFKZhjuF#vQ64qqJZB)5*845uRe(J1ZAsy7c=g`LKCOO4ZR;4J;%n+Jp38Kh zsp@NBr+)ATAl<29GQ1kbrBZ|5Z0*BCk_Ca|VJ@OGTB_0?a@P;7aT;&B`Wr#1%-aj} z@{vK!_`rJQ5?pM#!Xj$@Tu6~-O#ud?V8)IZrDSm23a!hFy$DQ~u2%ID2X|!t2%sTf zK31k!6y`Pa^;IPv+C{WOrx%yJ6G}OCOjlsH9M;aAqhIY5<|M^`M|5xm72&-|sWbU< zh_k>v5U!fhGXT*%O^Dm15Zm?BPDEmhQm(f*lKx&5O1CLdw29QrC0$kREVqqoP`4RY z5~zoT8IZ7K;m6ZqbrqgqBPI+4jeWs^VT}vAQtH`?1Cuv6Ku7=2-SBx#g$(re+Fw(s zI33_vBNjRG;$kvDruWe4tf(jyUMQM4wo|dXils$h!(|-`oIE+%IeKW-c3S~|*taGU zw#8KpQ_RS&5yb?tUR{t~)ueR&4EPGI^wtL+9K5h3@V?nsSc2+hO>5HxgY$k~KgVJ# zz&?hv8hclJBkRLtOic|&nhe40z1Khk?%`s2E~FSyKi1qOR~pd(T-AK>usPP`OXMlz z<_RLpQ`SktD~R`h{%L#8((TLXg~uPkF(bjSV^9e{RWQHM6uFZ(?UE)4l{m6S+#m!s6Cj)$F|s{onUdXQXg$|14mQNgli1v&?GGv zPiHxX(-GJZPBF-B?%k9xtPeqaISg({6MhixACD-O3v;`pvZb3GGN>Yjp>5Qbbzrtp z={?=kO~xwCd;M<$%Uc@KacLi8T38V^^-i|d+uK{6Imik{!sfzc3K)bsa3^yo8lkxIQXk>JiX&r_gp1Av5!yYMDjFWTC}R%@>!waE z_yvVn@t4TsF^}j6A5G^n-j(6lls(7Bp#^6hitqU?ugzv@A$=qaM^Bk z+D6JQQxR;`?=*Pj@|Bf9KrYWo0FrM2?|XqQ!;VpFr*N9SDZApaKB&9 zKr`kvqA?JJK-i@Gb%w6=Vw2OyHLrzP zA|^z}B+&nOrsui%XNBb{^1E)fLzPG&DMZEFI`P@r_Z*qlGSbNOve&ZfE@Pk8Um?oz zTmOiiB-3wN>r$h>*$-A0xvWUsnh(vvpK~W|{LmCz5f9O+lbINWob_-VeWiGYBGEUe z*FQ+|j_nD*^AFg0*I%)204qh{@sF7Dq76q86n}^DeIUn6pVFQ)M!h+%SPGx$PGAsD zurqj!PEXs^PSKOoY~r zU>fiiE-H;HUmGJ0WL1Ztw~{B{vogwS(41?nMOK0rInb@_4Hm?F_UO`I8)`ni*W!{B z)F2jl5MKn@T}|?f#Ua(JKyU>dBM^R4^Fe6Ks%n=SG7inahY42891io)sw!dX60Fnr zwaCakJ|)NIg~t|r5~+DAa3KGIfN>=pkTG4#q7`g>Iw+n$dzQ^+YCsJx)WAjV=J81o z6kRnCZ?HfmB3cdq?8NgJYs4w;<3EvqH_u2>=ImCKqr7n+R)gtSmpP0hgOY zJZ!saM!`l=M)`s4&l!e$LG&4XH5l&omuN`2mQ;Ma7u2InS!qISwJDPy%JSD`gkmUE zg>l|kFb#gK1eNIyqeYxcvcjyCcq7NIsTdWD_n8oMWBZfBG8o~VB}t#e3U+3XUmX~- z?oEG`cL;75FoD%SsLyn%O+SG$^+L__T$Ro*C4JeG9DVbnv?t;?q$e?53re^l2#0f+ zajR?U&mXqRi@#t9U>evHUt=OpOfYU`-39TF z`<`{BfSA8ICI-15SA2tRe`BV;x_JtFGaDW1cqA5wEo1A^Lye-b`q(;fP2IJkJ`g<% z#KqDK5C@AJ=||o5${k_eL+3J#j;-<-ZUTKu@-Fku=Gz(yLoI%Cm^K4nU|t2k1i80I zP@?p6So`elBxboz@-&d=Z>J2@bH$1X8g^7#qYO)QL<8ED8RUn%hkltDTF^m7ojoR} zO(Ue{eU)$v4%O~R>8oa2f^i#;&AcoNOF53GkbLG;%1NL}4XEH2njxj=nEXv&S^Cr+ zXI?kx@iVn;BKGxGAdLV3t=vM4uVS{cMRa9~b2KiQH#RW%$>pg?DNAnr33jp%I@&E# z%cu~NN#92-8uu7*m?7zFn2FtV2 z!;CV`Yxf+t=OL4kO&)p!wJdY;C?qm;u-JOz;V%F~^&msjiMN0A^>?8S`Yfrh@b*KZ zt9{0a0ozmHE$lk-z?X8Gj#(9(K2tj-2EBI+AlD_KxIe)%wPpAEI_snwEPsV?n7I3Z z;~KKbLsE|Jvm^6`WfnHbaRyJ~oiCC#z=%%+!@FNOQ&d;!DTbDjc`G##eZ?`Y+=^}| z5^#RNZ@=oh05w3$zvnGe2Pw8fwfCS!n3G784S|Ith{*4gWYxNuS}sHJ0p~DL8XN^_ zNdpV?vcBZZq2v@SnmSwi+_`_83n)-D;plkHKBr3?C!~9Hs>c)0Lze?w))G|fC~m^0 zKoiA2m%1g-evPp}1QY)iei57*T&4L*NH-%B^#Cd;?GQU@$D$yVLramDC>L5&8ja4o zJFuOX$->1S=?v#LpUC7h)(Fklp(r~exoR? zCJ-4X#&*P3{}bP^tn27}AM+cmlE@cvIkw_Eb$-?M7grk;l|4Vze?AUXlv}r~0wx;7 znFNMDFILobws=Fp`@~FvRT^a^$<24JPNf%VaFb}Df|GBWrm*YCJOj5SX*W09Rq&%y)vyo^!G|7$G)!mZlO12s$7##k}PmNNQqW~^in!UIg# zrm*aW3FH)5@I_%Lk0CX0wwf^_ft>pZ423e#jRwUEKvjS|$u_2(rSN1Tx;Qa$LAF2I zJ>G=cMKNLz;T^$g7*|OH;*13R8^1`7z8`2c5NKX;@8!EIdP?kStWliTuGX4Zpx#7Id&odupA71L z>_(W(%+w1bqp=)0(csR3c{`OVJ|3P<9f;yH(@;df9?}m5X&G29GTYUeg#g@7Edn{g z=Zgu4TrbL|&bqWqzm|0%ZpiZ@!NvKY0_nWj^ndRTHSo}tarx&*RZx!jg^QOR(?hPE zWvteN-0vl+OK0Up-Yfg3LBDR1U`tCbKl)!Fl+38N9OGXPP}82i@l3$p8~*@9^EGsI zJWE~=)lszQ=<2HQQBU^A=i_fSLZUO|JDtd;-_ecA<43(3kfUQ{wk)v>3+1S^C@4sI z1srwrg(8k)*+Sk|G;#J2!eKgSS~A^}C~J=EyqV~zLRk^`Lw+$1umE}HHDO2dgj3E# zR-tp6wWu9Ub+Zrc$kG#A3gpYa?+G34&55@z{domq z=HlzP8(=y#^G@?S(W3f3BuThAB2BcGMvX9rzY;K6)o=CYAu@meA})dV4}2o8w%`}$ zry74_Rhgy#Hvl9DNfIH{Hb`5qL2=cG%!h2m=3TlypdlX}B#@Hgw}Z zRr~Tv+FJtP0xCHfjy~UT&a~c)4KR7%A^imuK}LI*syW}<&|ZkFny4-JB=%%`r@NJyK!V+%i|Y0AGMs_mDOB)xN+^F@-Ve9I;XUG9FI3+afx#ypQUfDJcL-s?j4Y`4 z95e!wf|aW|S54u-CtBgb-SeOJ-i6C~VC5qo&E zN*V-)qhRr2MJgoz16$<`0iFSWqiwggT@#KiM7mpDVYt-atBU!>f zJI2Z_j_xzUcKXm4t4Jq_q+t0r;g@5N*nXz>W56_<^XH0uJ?TR(hzN~A2_7*E$YE;! z{VZl$B-gWLmL8xx6K`@gwS+*aynC0=MC4)-`C zJk6ePK$aMC1`U4d-wD&gMc?x4)jx}Uw}_bXY`uynpibNPDNmwrd4gsJEJV`PGkI}i z$s$Fa7zV*F9R|*d_-~O;iw0`DRrAcEgHEF&mPYr1UstH(C5EMI>jxNwz6I~>{#Dzn zJ&g+!w81^PZZ{i76DWRidt+%h5(Fe!Sjkr|Gt`#;$RNbOhY-zH&;Ikb607nHYMq(I zL(cXLo6DtL!)5b)$eAl>x#pHQvk0XAjT^W~{(Xh6Fb94twL3W2@+Gi8YI?I+FsTH9 zgQcd1apmf`o9u(jkryN_ zwO;o~W|^0^@!;$FgdIR0&WZS6c8!M1i43~?pj-YyJf1Z2*@5l%lf9UqR-gk2(|Uns zwYE(;5b{fM_&=WJWea4vy>P3nC?&Z`HB8#e^TSZo{o16Hd}mJ0ei!JoWgD#2<;g{& z_w78kSwP{6pc$7Bj_aE^LtNI4eSx)==OBwyMBs9p7xm_N){cZgCp;*FgXrmNc?4XU zcHRWO<^IZlRn0C2oy3bDcrb%v8#hrG=eAz8q*K%jH35Cf*G@F46&qrC^@Jiafol#0ETXx*C`## zGptY8j<665NG?}qzn305=K$-*F<}7Lj(u{+Kgbe-)!E#XKj36R6NRzl1=VL)FjZ&h zR3CkWqS31U5)d{ByVA1a9rtHtodRPvy>nKN3Jt!B zD<}2e1b+bpVRx;%^V^Dswi;T%9j_r$f4)Gek!sqX(>mdKmpjF-RN<_yd%iTd+!VJ&u|*>N7Azlse@j83N{I2ie#+#D66|Tz%%y*dJ)Th z0`9o_0%p~APq%@ennk7vY_lI6Mqd9_SGr@*Zn)v>E_>7*y%>ITRM1#~WO`gM95SxO za>%L&X$&BqDXl)rN>-Ie2M3Uov(x-P0CJ1??mPkTtV(59*!l{znp<_!x~6vO_s}Nr z{2Y;tn4n@4!#1&hsO^{B92+^*UR-Bt1F`3YV!T-O2$rQh)ph{lwAv^dPYqWO+<&z? zq9KdwKn}#MwrgiDK6I^J);NqC*lW_zi1Foy!wGWyjKg@}e~SAUiFAO2yZ z^}($^A&Yq(KYViJG?Row_Jm!0)TuAv0MLG@dy?`JAGHvN8T~8cKYeBqY%l)FinT{` znA{aLj)h=@1SznZ*5RcZQ{>SwAx;BjMo(5M|@4AD)}D!3w)vUz4xC}sWfj(J4n&Y(GBNq1n<0sAR=q19!<0p~0f8U-WNDXykVlXRXum^=6tJMoJ= zU!A#{msdxI+#$yl=V_wmPiLoO!Yqubu946>0AL)iq#aqI!QEiv@gC4^@2X5dXwpjj z1r+&=FHm}V_!>YsG-KST@z~~%ZKyr7CSYH%v@t`=@z#lvcyE7f#6sLJb55d{`Fg4G z?Jd6qSq~{sGa!cSq_aR1>BAJ=j-?^0vw3ov(%2|+VW{suiwjc;@{*;u4izBB$ASfl-+~i$bn}k)J zZy8;EN0am$gm+n=BXyN-(Wvg22Q2LBvfsBiM_X6WFp6{*x;|h#=1!-h3|xD)KnoCp zUw$h}JDkyF2mvFY1-IM3_nhqB+x=V<_dZv1T%u)-7Is!={{JbQbvJNp&omhBvz--k z8?qdjRo!@6j81fEpSpz7lwEhCEi*7uzZ z|DeHboo|cC+ieX|d_!Ibyni$h%H$2!hT?9G?5If#{S9t^)6cX|;Tk7mU4O%jB#G3W zoWBurf$waED=LIl=J^!PjgQ;c=dPPU7Q8E3`xn>wE1Ib8;g?KEJN5WqHdX5h*2Fm# zQ67`uS_37WTBF9?N&8`jrY;}+Vx05hFr(%<_eCX}qbs0mA~DZd#>0 zSrs2=2t&?1#2gS55Dj!Z(bCQbn!&$c%Y2?&oS|27>`*Q6$Gj77cje<3;Ob)rV1J*YHcws-N?EjISmrYF823!)(>ykDNZRIAL&N=}n0 zM%1q0vDx2u$>rx|uCUVti3|0n1kZnfjw2HZ;Ds{?s%FlV1(b_B-`JN953Xq>zgd1Wl{rlkibR-Z~r*DO+b#?wGr)xZVeu(t`!{ozg?f zT`ar;^X#M``wG0c{J{XOR3ZK*%*bpqOf$UpFc`v$n0w9jkls?*3a)zT9>*|0LA-)TpsmXiMPc{C zpuSCv&N)&i8kDPs1kq9g^0^AP(1A50P%Vtu0%Cz}LW+4dJs`(ydbcQHzhS2X;zNS{8?2 znqWe49+>+4X@D~1u}~7mjriwG zgXBIpSa!=?j;GtCz~y_wAR@b6>n9ydoGYRN&{{IkJTHkm+({Q&nS*%FG}G_I1}3_3 zltV!f0_Z|tYwvab{_DEcu!-~W_(JR3!8I1=zej^138j`3Y*XGMypxZk-b!xk?_RMl zWB=;3jDu=gPX$OavG1Hd2&(3NQPWYk(EK5G&1pS8n^Yl`>l(M(;x84=pZn18DWQ2} zK(I-BXVS+@lfe`9ZJ14vuuuXMVz%B8SbQ^HBX*ms<>APesQ|>w6ckABv9RDS{zEy~ zYVA{IKA$1z4pN%DLmF)k-?l8@@ul#Y4K_1R4nY;otM^0|hHWzgA3R(zVS*1ciFKM% zt|keWit;6(?wGmf-$e;+26i=}V1_igz0Wlz*D2Cx&_65yiyWehV7(R)-aSlm3nIk@ z1C7wR7HflDOFw?OG3kK=aKf;a7EvQwWLZqWe2~JWgID_}7Tl|&GG;vhJqL@#3MOSV z0M(MA5uqE2-q+Vg4e9Fzi7d(u}&(4Oj3nIsC3@x?Gmol#4Gwml`@pF$so6&n9;QA%}$bc>a7{8 zhE|A3XMSEoD0g9<#kewB1eVZr-mTqdjpz`49GP4CliZv|Tpt$uFsrfl4wyF(1|$>- zP`LudfhuI3`A#Gta}5L1uBnq*jUDv#M;MEOl_}a{arM8+3{*ZO32pL*KkxE(2BXB+ z5=aL0IZgE<)nli@6jOxhO>$n9uX_Yfnv(m$f#(#FnfXEPEJZB$FW>zEs#N&Q!OB@R zMYdksS~$bo?1b)14}R_?D;wb8LJr^rVa9PlB}Y-N=aQB=12|qkr+*JoO-G>5P^T@7 zS&OYeJJAD4@!VY5h zrsF}#ojCe+!|$FJOKtU7nbqH44+Lij*8OYa;zd%JVRuUb)jKNEHAcxl7=GKmw=M=E z*lE=O1EQawnejn2e;I~ACrG+aiJ%!41{(do{!WgOP}dz>Nx5M*I(M9IgiOYph5WO6bTk!z;-xx6R$M;BG-_&OIR zQ-Z1w?l<$fmtUe7JNPT2?G$(Kzlh#V#R?+G5b6hdU?Iufv7d4dYcczsMY+vL;R>PBMwwvG}xHst1%vKv*E1)z_o2U zjfGzO-|VTyKbt8Y^)L8rD+1UtZ1h#d6Ohkl{XQ0AO);PB6&E1UfKjX_H#2sjEq~z*g4lE|UM7BAfo1BCUv@TAzZk*kTu0bg%bId{Hk+ zv&YJKjO4{}0B0rR^}a%OE^@TbmfdRM3ku!%LGr{mrzc)<^ASxwa$|}vsjcbT75!&^ z`p?*$yiC#};vgmSxauDyrgu##?&u6BaaTv8ahw{TWp)-b3hO1PJ~LnjZ^nJ^53Eq~ zt?Yrt#$)IffFby*4M-L$+dbCp9ooqezOL9Wh+#*QIpb)TzK`iV>?jduFXJY;l(YB2 zctqSbJz|gI*Jlo_MuKpC`!YmvTsfKOBW_H2EDB*G%C+{{iIpckBcOodWH6oecV`YV za>c>Xs0>_gW{{t!ZI6j+O zUA#j&&%&$na%DL}`Y{Jp7y(XXj~AF-Irf=2_{0518S=u%i=oqD&oNK_${!mSviuFS zZwnQT4zYk*n%M%iR^%DB!g+On?e#ne|Io}KCO^cgu~Ld1}} zq%Mz$y|IBQGV_n-DCZS;)jn)ri8V&)`s?rqXBy|c1DEXI{q*J9(_Dk0T`Rz~n$FVV z$@2w*IF_Qwppr5Ia4oeTT({8?(!vYqxO4f4WXIG7_5C6S#FcNJxV*<|{e&1UfUDvl z3v5P`kApAD0Mt=~QaO7;PTZ)En!QzYe-Et5tEY6!LAy-*B0Sc6ANkOTP%=JSRpnP* zkUNt(+`vI&?jBRNL(%g30&e9AODWuKSJldciS_>t?2!)Up?l=C9O|>n2D~U6^UqBj zfE=7@se^ebxx~4Mb@Rtq=D^+o^ppIM*8CLHuSejCMu6I!9g94gyMbdDmPM*ZU3jwr7OQrAJv(YJOThZ|dHE5!dQb-6&H zWAk;!PA15ZP83F>Zn|p3Q?F*}#P;GWBuTql(rOBxPv~9SkbJttiNbb(fBvN!2j^d! zM`^tcr(i`h;5_dMQ%$MX_54Co0e zMW?wQsmlkD$dzCC!VnUp7ZvL2>+_tob<{;j5rb5W!S6BpI?d~SVfxQw+>7Jx$(>4WGD&noM z^J_80curZe`2s>qIZ76f6rDm8PxMLUQ<#$==SD24ZgYUD=7kIDgw{L-U)w>Z$J@i4 z5q8g&FU}L8U4Wx1Jh^q^k2JB+iqpOCDE?)UNPPk*(vpDrbb8(khSD_u!0-Zc&5G!=ED41_HPv@(1`s{*;{$e0w0E`O4`JHAEuI2gH5!~c^y z=wA-$(F2^-?OVEhL_0E$VVs!|Dt|}g%*m=;BF4C0xt0Q#iZ5SgI>~LvZeRu$K&&}3 zuG10%V0;c%1PP@nk?L#F2e7_R+Pb9F0-JBZw@GiGJD6*>A#FVlw&oeS1@KvdoUn^- zmn%?@*r(RPCfo<}Wy*)WfbJV@g8+s+guk#C{s$h>dn*(i@uyq~O-7!)wax;;$f@jg z1%n+UGxY7jR+s|0$874zRko(r)Wy4-?I0yMcec&y1f^n^V5gn_RF;5R+~g3DU=(ow z?=YUv5Nsur@zl+}LwZwBRVYP+cCFOi3QRu0)6>%071-VbrE%$NbI1>*kZle%Puzl) z{D>Cx4WS2AZf0o5JZ^%zBB11!Wk@#=3(kw4-OVGzrNLcrLuSuSM3YV$lmCYEIR>Oc zrAQuJ^k=kwiJ3}N3z3}10_GlQf>#hdCk{XJr(mY&gRA2~>lux)k3n%R7fcc!v&v0A z*cd9y%B?iI+HRQ3&f^`M!hPpH^w7AGI%9oI1`wLRem$48k7`TMcj~TR1I4`bVdyq2 zzF?D2kAoZ?C#P;Jq~q<#iS>KaJG7&@sH``YXuSje3xCO-uARdm#@Up3!PoJv2$8h= z6NcY#Xv!(r!(kac3CWI#q*{k#|d^FW~Ez^R|k42bh zi3I2Wgc(20KW>S3E_5y{@HLldB6#>0i$O8qr$-YvmM+#X%RHm)&n7z?9V`Bz$VV-L zh;!Pcu~P?%Fv4uU7Q@V02GNne2I2sahzE^o5QBm?%--K@J%aUQd?T)WvIP9_kXXzS zSN?WaED;qdQmd^>tXsWT%njYz8*gsJT_4{=`#GSxeU6c%S-!}3C;4Jm3FwovdOA_P z76W8x=)Vu_Ri`ps3M#DV-M#SidXKiLahOAEOw+W)R{Mfr}6; zWKT2)n1B27iL@**rj;jG(@9vZUwZ|{gE{^*Lu|E%ae0s(Aiu-c(hwCJP*+%&9ebCI z_8|g>K}5u!Ph8)hhw#FaU;@&x=p001??AvRyZ*HTFjvla4$6vH{sG3aUXttBj=_cS zg!WXaTg(uJ|B3}~*8;4MggCU0U0D;M(O!9rqDj@{;;48B@ak*JR4}*^*1%i5%}sqJh>gZ z9QK0X`7P}zz^HOV91IcS?KW_syxzsQoiFAz=*V2UrIxqG-V&7WEXvU3gD+TfgMI`2 z{GA%VL5h^)>VzMYBgS#)E?~2Y_~(zm7v+a`8PhjwOkO=79!I@4ZcyHQ@4MOOG(fE^ zTPBykcH9Q+0*dF+g|YKS+5_$B&z%L7)_1L|QG>|h z#12>*t4=_VOU8N$fl31|YMOMY&7GMO>84cJM zJhQDQUL^@nnuqi-n)h9_gI*yjO;HP6NDH6b;!V>L?@E4ii7Pxx|3w!HrDSl^jTIZ&R&i16}<{Y<{+KzdYu#E(q z#X*$hnUz9WZOvU%*2rqljDq%6Vo5l!Yk?X38@R9u6RA>^9G0P*ZgighjzdD+B^8sr ziDIn6X*~fz%~AL-_ju$%U{@7YC=%#-{11Kd|&dr*@qtzAn6cJtB@_Z~by186rNHR28N$ zNaxV&d?oQg!d+aFK)dQL3YSvxW5{Ni!!R8~>IV_I#cf9g4IMJg_4iRb4$vvbgAYn$ zsd0hLZd>Q{@^jtrHoX&nuwuO-|C}ivyNBAR&4<_C)qQv@e7TaOON`59Fp6A9n??T4 zWcL;{eeS=NSRG=MXpUgyFY5e;u6=j&Wwe-kwVU0}fMH8`3g<@j?wJP#RaJ!)!Q-zw zE5$}Wm+{*J5RrkKF5}AJc~MjXQ2c=GMsrBz6M4kVwUB4~fRS7nE>vYs-?IrasrgAq zDk*(Et#{(AMY1dBQTrtE@4OnBU*l4yJ$u`5K|!U-K%;G;?kFL$n%q;b{ZJlM)*@&+ zEZNl|$J0t!KEq~Wu255=DCd8X2-mp7RF0eoCz4_s@dJeY;qBnY=Sq=)B}Vd4(Z+A$ zASCRg4VikUx$zNS>jxDBKD$rJ^cus!W_ixZt8%SfEFcf1K{6K`$(|H$ambba2QL08 zn8gOUh@DM@t9xklOQ~zApE5+NuFN|EtJTT`wj*52slu`F0dd<{MxOl1-R+!K+Q))S zP|qZAN>V^est;JgWbPrrIQp&C;{b$K(3BiLF^yw{_aYF@V3G?E4Dam)@sqOG;<^N0 zG~VX%{-GC@A6JW?9J$r-8p-P%FwpRjK+c#bX`I;@9;%80*N%@9U4K}UT1Ihlb)!Q! zpH2^2-(6Z30Ndx}iw6&GS!xjg&*AKu;PsErBr_wbRel3RHdi8okXkZLY-|}NOfCWi z@4`e&ww)JrY3dcP6$)ALbDfqT5VN6g4Qf39Li5cW*?JqVTPohP?C2}^vHnY%73s8s5(3J1IM%5A zaf%NWm9i)OvZ=-$fS+^|{>BIZq$Ef|RIF`T=fv?<3IqJKq0vAV-z`Gxjd@G^l zdUNa3!fY2}+wi)>2SW@x?+a_;e26cy^{i_lOieb&DwpC{LJV}(Q};GZ4t3Nj(p(0c8lo~+~R+!bk-|F z>xtVYdz+e2sRNECBSd3y&^K5EH^I4q*U?jVWlB`&EelS&ha&$=GHytf#EOh7#`|Ft zvA}YXP+(OOPXZ$@$7gU14AdrNy2WL6AMCrT$(HMR7hKsiQ-^))kIu597(%T;WsP6g zqbKk87qx`?Qvqxno6mBM8;$VQC1p~=xEAGwcU#K;O`vHG>Tm=>{r&XVd27s!R%)xN z-~g%3l+}O>0wzNnJ7w09vDy{ElYKefO52kt1-#O=z16+R;@C(l+T+!Sz(eTv^#u~2 znjE#@aC!QkE!b^ATtc`yDP$Ij@T0B(y=MEip9=)479X%_t`!%GW2<6swDPbwLBI@= z85g(jd~&Mo=Lq0L`TiAATDa<;$@R(;N^6LE_zlCt**mBuNyNVyW-3x74-Z?_+{(S zXriP0Z%G$ogy;J-6NvmpA(;#&PHcKWnU~DT(_xByHP4;WM*DZkK2qOOE%UCV!ip>7 z*fXy%4Nx7;{5I$VJ;1?JjE%&w;V>m46}P}yR@6W1WH}k`&3-A{pdBQiMdTD6j7oMM zea=QR;lHN@eps1EDtkjV#qzGt!=2Oiicswc8~@`d7?;bT*0yYmtG0Z5&kEFJMLttI z18!8yhnx}<+4_^d2$vIJml)!x*}hsJeBOudCo40q3MXa}3ha&h7f$UjH~_1k?>DE_ zmnk9Un45)pO!53|Kh6q5@>rek4><#t7LiphG7RA zXvbG~K~ZVy(u!e)B;EdLxE+^6(a=m}Wfdpd8YwLMV;%!#;LMc_5adQ_d!kBW-qcqc z7dbDl#FDdT3wv>nsEHVrVQu7Pu;fx7Y{NByhuW_JCbGr+C7xt=Iw3h}B_aFc z7KCG}9alM1m7$^>GVFf=uZODY-1ea*D&U|4;$F-%8!BS)AgF`m!41@)L6nyB^C=}8dUX>F_J z@{Sxa*d`=H+=TC8;`aRREX+7sh*KuoE*SbDBtBU)<+QZ7 zIID~761amf)tru~pw3g_U*?r*hbh-U;(EFt;!3lYGK7FOwT#~L z!m=H+@Z)-;RTDZ8UbH*6RV@_O-(2NBd8~MXvRrnQVYL>=NeB z{FB4Me6^3@H}gWtLy1HtafVdR&eZ~YosIi_-T=7sd(408A{gxz2bloObq#VU?1xZj zLX9A<09Nka7$<76C^g{|eOu950>E z%QXHvQ!AGFQ#}Tkj?&WaK3*a3dehd~)D#fYaQI3|TL>9s62X1Vn^Je_H+QY*LiM&o ziv`dPWuT?3cjb*LkU(9XvYeg`WWtsgP;XT1Bpwi%PwRd4m&L}!NyzhU{LTE2z%TB9 zc#Ys^*HCL)+XfJW(I?Gg)Yw5Uu7ja4`x`ETOQ+Bh$=1(%xvl&x0%f23qqeYd-Bl`M z*hD+FSMr@3KO3@o5L$KDsx0dtVv4oPPi0dNJ93V0)s(=DhtnH#gRb&^#kJVm4oZh+ zEY-xshCp=v&`wn~hv`_V4o0%JY7`QT=qy~}t!q@gLtdzK@v#FzTDS38khQ0Z4FWBf zUzXo4A(!GKP=E|)8mRp}3+AX^kmz0hj{1~enojFG6LXv9u#}0Pp}1IsJy+eIpot9M z**1)Yj+3np-?s%ytR{SQHb?JuT-RVd^c?06z0}N&UeE}ra10Wu+rDJI%!gxJ*#AAH z+m#*-X^mM9j$vv@%-(i)-y|iyTAQMreU?lmj8i7cQzNf3LfpzdPkm}}Bq5!6TtsiZ zuH8Ep&GSL>Xf8;A9SJrX`fCMHXKtP|cw{?B7Vq$$^sJZ}r&7qj?j9;#6eDjT=QX*z zMMzOy_ORY;_qB{)RAXYSOWtQ^P-(GwctyP8iWyt1JoQT?#=(M45lkBd4&j8Xk9jA+ zw?8)ECdsRW)osL}Ln&lLQy_!TiB^a&Vgd2=y}Z;M8x3*=Hn+HmHeo`+0^`^f=cf2v zZ@~6#imcUsrGGLPgR9phgUGJ;8#FqmMS$?Z+T>~IjEELelH+x3za#ANFe@{Z&)M-i z(Tv+JXs#_%fj_z%qzDR@o7FyTsY@0`e#D_R|{0oV4E}yaR;3L zukA1U9A@06Gz^>mn^LB{jc+^muiv;9HH^g~hdOl`zY)Sce}nzIGE)1EJD!2$0T*Dt zjHb;w6dN@-s>SBf2`3t~*P_4W49+8jex{E``el{`T$j9K!gJQZh_BjTG3wva#vu#S z*I%l9pP!%4o$nZOwtk%rgATMLW-Q)>gfGW)drs;&AN{T38<(^xul0Z6Jy(7k{T zwEeIZNQ%!oC>>0!33(;^Pyoa4vD%mJf!co`aw98v;b-c!fUwQ8ItbsWa;K%PLqm*N z?KGQSjSou46+{12=8EOhN~1+h84KtqexUvfDMl@?_{@*xi?oNsz^x2nd=3k#oUt!{ z$(`Ez<-o}hALK=X{&v9zN8Ru~2y~O6tyPM(M70b)E@aAr^eP2Ivhahm(cRv; z(e&c^i>80TOfW%#$Kf~|mE%%GXEJZH;TP4Kw8IR@jf6S2bz#@5@|?mdct!AF8Z9Lc z>qEnuaHdf1$XU>=i*5$nAs^$*`H&Pku>m3yT<2&AZV|@P{XFEx@O1r(x|+c@)VnT! zXdF+G()x(=C11}tW-uG4MtFaq(^nT#oXnVC_i3!KXq56SsJ}bH9xPu;M3)DNwe(># z;(g*C!#Ty@?&?$d$@d;g1Vb`kDHO7XGkW!>%sk77{j|2}`+CuNA!-<@o?^(@U&%P1 z>R^o4fIFenZ*M0H(wAmwUcV?*C?5|HUnL4a#)Wak>cYnDIho=x#04Y6>|1qiOY`rcqNg~2LTEpN zALCh{?#r?RLb-a%SWg=zMO=y7KeNmUCvi~9*h6Wv zoLH0p1Zor0&!L$dD(>&xxP1&~wHl)Fv+hS5G)K$J+?{bApvH$*OKI*c`>18?1CryD z6zQoVWej?7Y{nYy?}%2Ze@>5)1X5fO^b8nUb73b;LPk5=Jp!DiU1H=RN;7@xx_G`w zI+UNvW{Jtx=q^cCED$=L(bAVFw^_y-jeFkd0b=Wo|WKQES0a_tXDRb;3f*KNL5( zh;d_D5@`qAU9-SLLx0?Z2A}uK9jq+C$m(~&`X$^1{&53Rc}lka956W9qi9BM6qJvh ztV8#deS@(4*giqpH2;2U8A#OP*#NNr^5GUFIFuzuhpkXtJjue9y>X|GmNS-E*&Zcd zuj}}nuctlV7%v&e8id0NteSzYdl6=NtH)_sDCpdEyxwUDc@0+lsW-jdgN8yLc{z%T z@U2etB*ly=b0*?}E;^Wt^^1656QhoU1b~Q=Q{2r}DkkhAdJV#lfveoSpkr}L%K!w? zM7exIXJC=X1Yv*R3H*9RLNb2VUlFUKfn7P#m49ZGSwbHCY!(#yxa--K0a?jZPO_(C z>~)q4V*rPiomi(*^&#TbUq#=66?zC$lOEUjD849{Aj?X3n+)K4ZH@-GGG?tK(?A79 z61z*08Se7q`ZKE(qB0jhIZtIz45%hS{_Nt`tiH~Tc6jMF-RcG%4HmuOiw{Pju>Ej+ zWj?l78j*{unuouOcpzT@0_9%nKTIP+=~}d1Xs-w`6zZzS*(7KD)I96y1Tn%tFZ6O{ zqLqZAdfp{qd$i1(BJ*8BkP4*h9R;(U&2cM>YqLsca+v)r5*Y zbJQ#f6zvu0=b?ln0db@5`peAa6iq*HVB^A@imm8PzqZF6`l&2LB-B

NK_ZLH+
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%0DwEMYu?IudZyf
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�mur0wfD
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%0A(T8Vd%VYNCph
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
  • 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 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 0d883c394..246763804 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.17-SNAPSHOT + 1.0.5 jar 2019 From 6e9d2022fe450da1920446fa1fdf59391f0e7d30 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Feb 2019 15:44:54 +0100 Subject: [PATCH 0131/1786] commented not needed setting --- config/travis/mvn-settings.xml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index d58cf8172..f6a5727b8 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -18,7 +18,7 @@ - + @@ -31,17 +31,17 @@ - - ossrh - - true - - - gpg - ${env.GPG_KEY_NAME} - ${env.GPG_PASSPHRASE} - - - - + + + + + + + + + + + + + From 0109d8c15d66091bd9b8345b375d9a3d726ff295 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Feb 2019 15:54:07 +0100 Subject: [PATCH 0132/1786] testing --- .travis.yml | 20 +++++++++++++++++--- config/travis/mvn-settings.xml | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 04a9cc86a..e6e0bc0e2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +sudo: false language: java #jdk: oraclejdk11 os: @@ -47,9 +48,22 @@ cache: # on: # tags: true -before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml -script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Psonatype-oss-release +#before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar +#install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml +#script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Psonatype-oss-release + +before_install: + - if [ "${TRAVIS_PULL_REQUEST}" = "true" ] ; then + openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar + && tar xvf secrets.tar ; + fi +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings + config/travis/mvn-settings.xml +script: + - if [ "${TRAVIS_PULL_REQUEST}" = "true" ] ; then + mvn deploy -B --global-settings settings-4-travis.xml -Prelease ; + fi + notifications: email: - borriello.fabio@gmail.com diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index f6a5727b8..c642df99d 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -18,6 +18,37 @@ + + + travis-profile + + + + + false + always + warn + + + false + never + fail + + codehaus-snapshots + Codehaus (snapshots) + https://nexus.codehaus.org/snapshots/ + + + + + + travis-profile + + @@ -43,5 +74,5 @@ - + From 7d12c11ed9f41e4da4bb525166835c0071fe1baf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Feb 2019 15:56:45 +0100 Subject: [PATCH 0133/1786] fixed key path --- .travis.yml | 29 +++++++++--------- config/travis/mvn-settings.xml | 55 ++++++++++++++++------------------ 2 files changed, 39 insertions(+), 45 deletions(-) diff --git a/.travis.yml b/.travis.yml index e6e0bc0e2..8c09c85b1 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ -sudo: false language: java #jdk: oraclejdk11 os: @@ -48,21 +47,21 @@ cache: # on: # tags: true -#before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar -#install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml -#script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Psonatype-oss-release +before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml +script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Psonatype-oss-release -before_install: - - if [ "${TRAVIS_PULL_REQUEST}" = "true" ] ; then - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar - && tar xvf secrets.tar ; - fi -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings - config/travis/mvn-settings.xml -script: - - if [ "${TRAVIS_PULL_REQUEST}" = "true" ] ; then - mvn deploy -B --global-settings settings-4-travis.xml -Prelease ; - fi +#before_install: +# - if [ "${TRAVIS_PULL_REQUEST}" = "true" ] ; then +# openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar +# && tar xvf secrets.tar ; +# fi +#install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings +# config/travis/mvn-settings.xml +#script: +# - if [ "${TRAVIS_PULL_REQUEST}" = "true" ] ; then +# mvn deploy -B --global-settings settings-4-travis.xml -Prelease ; +# fi notifications: email: diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index c642df99d..765863d15 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -18,36 +18,31 @@ - - - travis-profile - - - - - false - always - warn - - - false - never - fail - - codehaus-snapshots - Codehaus (snapshots) - https://nexus.codehaus.org/snapshots/ - - - - - - travis-profile - + + + + + + + + + + + + + + + + + + + + + + + + + From f6021e21f13eced12f07e407d3790e2bddd62743 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Feb 2019 16:24:16 +0100 Subject: [PATCH 0134/1786] testing --- .travis.yml | 5 ++++- config/travis/mvn-settings.xml | 14 +++++++++++++- pom.xml | 23 +++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8c09c85b1..bb240a788 100755 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,9 @@ os: cache: directories: - ~/.m2/repository +env: + global: + - secure: USuExW6ln+ylYqnHYHM8UlOmlgp3p67mo80Ld6AQt6Asvj60axvarUAaNfw9HlEGpCXGgwkrMwXsmdXIjJNv56LzxvEkNmTRhrhHvR/3nfGLK0E4fm6Y3V0abii5d3Lw/qSu9iwLv+Sv9ZbPidj0pbm7kuID7CzetGmv+Ux8aUOLhInifCHujby2LUCsUzupghtcsoVkOdKICqsTMajfbbQBIo4q2/huan1q5bh37BDSwIkvhwJg6hwhAZ5Zf0MKvWxAfjv/PYe0+MntJGtZUAHog0irzMhoi/Od7ffhIUr3M0LCs1lzKBUiVloh7nrZRVPpdbkau4i6CUfvmfnz/l6Ruh22tvAHA/fKynvF84q/Qf9sQEKkWKR++y0OS7WwV85J9GfAEiaORa4JYuqHPtsSAacB9QcDMJkZM2HbDIqn5q3air/smZZCHI3yJ73xozgmU5Woxyu6YbiM6lJ5KHUbE8kl5xikFidadSyRDYUnQf3Y4YOBwUqgOZFMTNcFwBz/J0arV3x3BX3NFtc5+8rypm6M10tVHEqu1Qej65jkP59Pp/m8bM8FWJdxqQ8mNm8ulG7BO+SSdglhqyHQ9pp0ZuTclYvjIOrr866+pgh93aEHaTbZCCGes1U8K00qaCDloFiZULxM502IVTc/kupsL9R12nJ+L8hpEdZR99g= #jobs: # include: # # If the branch is not master it just builds the application @@ -49,7 +52,7 @@ cache: before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml -script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Psonatype-oss-release +script: mvn deploy -B --settings config/travis/mvn-settings.xml -Psonatype-oss-release #before_install: # - if [ "${TRAVIS_PULL_REQUEST}" = "true" ] ; then diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 765863d15..871ea2437 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -69,5 +69,17 @@ - + + + sonatype-oss-release + + gpg2 + false + ${env.GPG_DIR}/pubring.kbx + ${env.GPG_DIR}/secring.kbx + ${env.GPG_KEY_NAME} + ${env.GPG_PASSPHRASE} + + + diff --git a/pom.xml b/pom.xml index 246763804..2f83b98ad 100644 --- a/pom.xml +++ b/pom.xml @@ -329,6 +329,29 @@ + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${nexus.staging.maven.plugin.version} + true + + sonatype-nexus-staging + https://oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-release-plugin + ${maven.release.plugin.version} + + true + false + sonatype-oss-release + deploy + + From 4a41166347a9870cb0fb207904e9b9c1324077f2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Feb 2019 16:28:19 +0100 Subject: [PATCH 0135/1786] fixed key path --- .travis.yml | 2 +- config/travis/mvn-settings.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index bb240a788..23acf49e0 100755 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,7 @@ env: # on: # tags: true -before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d +before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d -d && tar xvf secrets.tar install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml script: mvn deploy -B --settings config/travis/mvn-settings.xml -Psonatype-oss-release diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 871ea2437..4a242d4f2 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -75,8 +75,8 @@ gpg2 false - ${env.GPG_DIR}/pubring.kbx - ${env.GPG_DIR}/secring.kbx + pubring.kbx + secring.kbx ${env.GPG_KEY_NAME} ${env.GPG_PASSPHRASE} From ace3844371a33900c2157179b28a7ffeeb0ecf7f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Feb 2019 16:35:29 +0100 Subject: [PATCH 0136/1786] added plugin --- .travis.yml | 2 +- config/travis/mvn-settings.xml | 27 ++++++++++++++++++----- pom.xml | 40 ++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23acf49e0..c4086c4c0 100755 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,7 @@ env: # on: # tags: true -before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d -d && tar xvf secrets.tar +before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d && tar xvf config/travis/secrets.tar install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml script: mvn deploy -B --settings config/travis/mvn-settings.xml -Psonatype-oss-release diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 4a242d4f2..2967a30c0 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -11,6 +11,11 @@ ${sonatype_username} ${sonatype_password} + + ossrh + ${sonatype_username} + ${sonatype_password} + ${github_server_id} @@ -69,15 +74,27 @@ + + + + + + + + + + + + + - sonatype-oss-release + ossrh + + true + gpg2 - false - pubring.kbx - secring.kbx - ${env.GPG_KEY_NAME} ${env.GPG_PASSPHRASE} diff --git a/pom.xml b/pom.xml index 2f83b98ad..5dac768b0 100644 --- a/pom.xml +++ b/pom.xml @@ -352,6 +352,46 @@ deploy + + org.apache.maven.plugins + maven-source-plugin + ${maven.source.plugin.version} + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven.gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + + From 25f9d54ab9dde14f73464ebf82e8486364d186fe Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Feb 2019 16:52:57 +0100 Subject: [PATCH 0137/1786] deploy test --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5dac768b0..7f8b6c47e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.5 + 1.0.4-SNAPSHOT jar 2019 From 53b52a5a68c13e952b6ff3d76a8d36cf4c95b887 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 08:52:36 +0100 Subject: [PATCH 0138/1786] - Added a detailed guide for the project contribution - Improved issue/feature template --- .github/ISSUE_TEMPLATE/bug_report.md | 6 ++--- CONTRIBUTING.md | 34 +++++++++++++++++++--------- CONTRIBUTORS.md | 15 ++++++++++++ 3 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 CONTRIBUTORS.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea782..e60cd75c1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,7 +3,7 @@ name: Bug report about: Create a report to help us improve title: '' labels: '' -assignees: '' +assignees: '[Fabio Borriello](https://github.com/fborriello)' --- @@ -29,8 +29,8 @@ If applicable, add screenshots to help explain your problem. - Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] + - Device: [e.g. iPhoneX] + - OS: [e.g. iOS12.1] - Browser [e.g. stock browser, safari] - Version [e.g. 22] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b30155498..decec42c0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,15 +1,27 @@ -## Contributors +Contributing +============ +If you want to contribute to the project and make it better, your help is very welcome. Contributing is also a great way to learn more about social coding on Github, new +technologies and and their ecosystems and how to make constructive, helpful bug reports, feature requests and the noblest of all contributions: a good, clean pull request. -### Original Developers +### How to make a clean pull request -* [Fabio Borriello](https://github.com/fborriello) +Look for a project's contribution instructions. If there are any, follow them. -### Additional Developers -* [Andrea Marsiglia](https://github.com/AndreaMars94) -* [Patrizio Munzi](https://github.com/patriziomunzi) +- Create a personal fork of the project on Github. +- Clone the fork on your local machine. Your remote repo on Github is called `origin`. +- Add the original repository as a remote called `upstream`. +- If you created your fork a while ago be sure to pull upstream changes into your local repository. +- Create a new branch to work on! Branch from `develop` if it exists, else from `master`. +- Implement/fix your feature, comment your code. +- Follow the code style of the project, including indentation. +- If the project has tests run them! +- Write or adapt tests as needed. +- Add or change the documentation as needed. +- Squash your commits into a single commit with git's [interactive rebase](https://help.github.com/articles/interactive-rebase). Create a new branch if necessary. +- Push your branch to your fork on Github, the remote `origin`. +- From your fork open a pull request in the correct branch. Target the project's `develop` branch if there is one, else go for `master`! +- If the maintainer requests further changes just push them to your branch. The PR will be updated automatically. +- Once the pull request is approved and merged you can [pull the changes from upstream](https://help.github.com/articles/syncing-a-fork/) to your local repo and delete your extra branch(es). -### Other Contributors - -* [Giorgio Delle Grottaglie](https://github.com/geordie--) -* Hotels.com's Checkout team in Rome -* Rob Light \ No newline at end of file +And last but not least: Always write your commit messages in the present tense. Your commit message should describe what the commit, when applied, does to the code – not what you +did to the code. \ No newline at end of file diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 000000000..b30155498 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,15 @@ +## Contributors + +### Original Developers + +* [Fabio Borriello](https://github.com/fborriello) + +### Additional Developers +* [Andrea Marsiglia](https://github.com/AndreaMars94) +* [Patrizio Munzi](https://github.com/patriziomunzi) + +### Other Contributors + +* [Giorgio Delle Grottaglie](https://github.com/geordie--) +* Hotels.com's Checkout team in Rome +* Rob Light \ No newline at end of file From 970058c257453d8522c8f9b6f02afc9dab8ec595 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 09:39:22 +0100 Subject: [PATCH 0139/1786] ongoing configuration --- .travis.yml | 9 ++- config/travis/mvn-settings.xml | 138 +++++++++++++++------------------ pom.xml | 2 +- 3 files changed, 71 insertions(+), 78 deletions(-) diff --git a/.travis.yml b/.travis.yml index c4086c4c0..a586bb973 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,14 @@ cache: - ~/.m2/repository env: global: - - secure: USuExW6ln+ylYqnHYHM8UlOmlgp3p67mo80Ld6AQt6Asvj60axvarUAaNfw9HlEGpCXGgwkrMwXsmdXIjJNv56LzxvEkNmTRhrhHvR/3nfGLK0E4fm6Y3V0abii5d3Lw/qSu9iwLv+Sv9ZbPidj0pbm7kuID7CzetGmv+Ux8aUOLhInifCHujby2LUCsUzupghtcsoVkOdKICqsTMajfbbQBIo4q2/huan1q5bh37BDSwIkvhwJg6hwhAZ5Zf0MKvWxAfjv/PYe0+MntJGtZUAHog0irzMhoi/Od7ffhIUr3M0LCs1lzKBUiVloh7nrZRVPpdbkau4i6CUfvmfnz/l6Ruh22tvAHA/fKynvF84q/Qf9sQEKkWKR++y0OS7WwV85J9GfAEiaORa4JYuqHPtsSAacB9QcDMJkZM2HbDIqn5q3air/smZZCHI3yJ73xozgmU5Woxyu6YbiM6lJ5KHUbE8kl5xikFidadSyRDYUnQf3Y4YOBwUqgOZFMTNcFwBz/J0arV3x3BX3NFtc5+8rypm6M10tVHEqu1Qej65jkP59Pp/m8bM8FWJdxqQ8mNm8ulG7BO+SSdglhqyHQ9pp0ZuTclYvjIOrr866+pgh93aEHaTbZCCGes1U8K00qaCDloFiZULxM502IVTc/kupsL9R12nJ+L8hpEdZR99g= + # sonatype jira username: OSSRH_USERNAME + - secure: "nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg=" + # sonatype jira password: OSSRH_PASSWORD + - secure: "OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I=" + # GPG_PASSPHRASE + - secure: "bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY=" + +# - secure: USuExW6ln+ylYqnHYHM8UlOmlgp3p67mo80Ld6AQt6Asvj60axvarUAaNfw9HlEGpCXGgwkrMwXsmdXIjJNv56LzxvEkNmTRhrhHvR/3nfGLK0E4fm6Y3V0abii5d3Lw/qSu9iwLv+Sv9ZbPidj0pbm7kuID7CzetGmv+Ux8aUOLhInifCHujby2LUCsUzupghtcsoVkOdKICqsTMajfbbQBIo4q2/huan1q5bh37BDSwIkvhwJg6hwhAZ5Zf0MKvWxAfjv/PYe0+MntJGtZUAHog0irzMhoi/Od7ffhIUr3M0LCs1lzKBUiVloh7nrZRVPpdbkau4i6CUfvmfnz/l6Ruh22tvAHA/fKynvF84q/Qf9sQEKkWKR++y0OS7WwV85J9GfAEiaORa4JYuqHPtsSAacB9QcDMJkZM2HbDIqn5q3air/smZZCHI3yJ73xozgmU5Woxyu6YbiM6lJ5KHUbE8kl5xikFidadSyRDYUnQf3Y4YOBwUqgOZFMTNcFwBz/J0arV3x3BX3NFtc5+8rypm6M10tVHEqu1Qej65jkP59Pp/m8bM8FWJdxqQ8mNm8ulG7BO+SSdglhqyHQ9pp0ZuTclYvjIOrr866+pgh93aEHaTbZCCGes1U8K00qaCDloFiZULxM502IVTc/kupsL9R12nJ+L8hpEdZR99g= #jobs: # include: # # If the branch is not master it just builds the application diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 2967a30c0..e12750acc 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -1,20 +1,9 @@ - - - sonatype-nexus-snapshots - ${sonatype_username} - ${sonatype_password} - - - sonatype-nexus-staging - ${sonatype_username} - ${sonatype_password} - ossrh - ${sonatype_username} - ${sonatype_password} + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} @@ -22,81 +11,78 @@ ${github_oauth_token} + + + travis-profile + + + + + false + always + warn + + + false + never + fail + + codehaus-snapshots + Codehaus (snapshots) + https://nexus.codehaus.org/snapshots/ + + - - - - - - - - - - - - - - - - - - - - - - - - - + + gpg2 + ${env.GPG_PASSPHRASE} + - - - - - - - - - - - - + + + + travis-profile + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - ossrh - - true - - - gpg2 - ${env.GPG_PASSPHRASE} - - - diff --git a/pom.xml b/pom.xml index 7f8b6c47e..f21aef79b 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.hotels hotels-oss-parent - 3.0.1 + 4.0.0 From 5cb9a7f7bb0c7528be77ed91391c9790594a11d7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 09:40:45 +0100 Subject: [PATCH 0140/1786] [maven-release-plugin] prepare release bean-utils-library-1.0.4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f21aef79b..4ff0da32d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.4-SNAPSHOT + 1.0.4 jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-${project.version} + bean-utils-library-1.0.4 From 67fddabae1d2a354281f8238cbd5fd3212a3b9db Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 09:41:23 +0100 Subject: [PATCH 0141/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4ff0da32d..d628ed461 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.4 + 1.0.5-SNAPSHOT jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.4 + bean-utils-library-${project.version} From a1ed2715cb56e24efb7980b5eb0cbca6e2a2d010 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 10:27:55 +0100 Subject: [PATCH 0142/1786] let's see --- .travis.yml | 83 +++------------ config/travis/secrets.tar.enc | Bin 524304 -> 5136 bytes pom.xml | 194 +++++++++++++++++++++++----------- 3 files changed, 143 insertions(+), 134 deletions(-) diff --git a/.travis.yml b/.travis.yml index a586bb973..f1905fbc9 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,79 +1,20 @@ language: java -#jdk: oraclejdk11 os: - - linux +- linux cache: directories: - - ~/.m2/repository + - "~/.m2/repository" env: global: - # sonatype jira username: OSSRH_USERNAME - - secure: "nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg=" - # sonatype jira password: OSSRH_PASSWORD - - secure: "OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I=" - # GPG_PASSPHRASE - - secure: "bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY=" - -# - secure: USuExW6ln+ylYqnHYHM8UlOmlgp3p67mo80Ld6AQt6Asvj60axvarUAaNfw9HlEGpCXGgwkrMwXsmdXIjJNv56LzxvEkNmTRhrhHvR/3nfGLK0E4fm6Y3V0abii5d3Lw/qSu9iwLv+Sv9ZbPidj0pbm7kuID7CzetGmv+Ux8aUOLhInifCHujby2LUCsUzupghtcsoVkOdKICqsTMajfbbQBIo4q2/huan1q5bh37BDSwIkvhwJg6hwhAZ5Zf0MKvWxAfjv/PYe0+MntJGtZUAHog0irzMhoi/Od7ffhIUr3M0LCs1lzKBUiVloh7nrZRVPpdbkau4i6CUfvmfnz/l6Ruh22tvAHA/fKynvF84q/Qf9sQEKkWKR++y0OS7WwV85J9GfAEiaORa4JYuqHPtsSAacB9QcDMJkZM2HbDIqn5q3air/smZZCHI3yJ73xozgmU5Woxyu6YbiM6lJ5KHUbE8kl5xikFidadSyRDYUnQf3Y4YOBwUqgOZFMTNcFwBz/J0arV3x3BX3NFtc5+8rypm6M10tVHEqu1Qej65jkP59Pp/m8bM8FWJdxqQ8mNm8ulG7BO+SSdglhqyHQ9pp0ZuTclYvjIOrr866+pgh93aEHaTbZCCGes1U8K00qaCDloFiZULxM502IVTc/kupsL9R12nJ+L8hpEdZR99g= -#jobs: -# include: -# # If the branch is not master it just builds the application -# - stage: "Build" -# name: "Build and Test" -# if: NOT branch = master -# jdk: oraclejdk11 -# install: mvn clean install -Dmaven.javadoc.skip=true -B -# # If the branch is master it sends the quality report to SonarCloud -# - stage: "Build, Test and Quality Check" -# name: "Building, testing and sending a quality report to SonarCloud" -# if: branch = master -# jdk: oraclejdk11 -# install: mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build and Publish" -# name: "Building site and publishing on GitHub pages" -# if: branch = master -# jdk: oraclejdk8 -# install: mvn clean site:site -DskipTests=true -B -# deploy: -# provider: pages -# local-dir: target/site -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true -# on: -# branch: master -# - stage: "Release" -# name: "Releasing artifacts on Maven central" -# before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d -# deploy: -# - provider: script -# script: config/travis/deploy.sh -# skip_cleanup: true -# on: -# branch: master -# - provider: script -# script: config/travis/deploy.sh -# skip_cleanup: true -# on: -# tags: true - -before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d && tar xvf config/travis/secrets.tar -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml -script: mvn deploy -B --settings config/travis/mvn-settings.xml -Psonatype-oss-release - -#before_install: -# - if [ "${TRAVIS_PULL_REQUEST}" = "true" ] ; then -# openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar -# && tar xvf secrets.tar ; -# fi -#install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings -# config/travis/mvn-settings.xml -#script: -# - if [ "${TRAVIS_PULL_REQUEST}" = "true" ] ; then -# mvn deploy -B --global-settings settings-4-travis.xml -Prelease ; -# fi - + - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= + - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= + - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= +before_install: + - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv + -in config/travis/secrets.tar.enc -out secrets.tar -d +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings + config/travis/mvn-settings.xml +script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease notifications: email: - - borriello.fabio@gmail.com - + - borriello.fabio@gmail.com diff --git a/config/travis/secrets.tar.enc b/config/travis/secrets.tar.enc index 0f5654fe78f75034de3d3e3e5b56febbec9e08d5..64809d4a50fb757d8cc01897fa05e1e050db54fc 100644 GIT binary patch literal 5136 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

    9pgS_AIcD3PJ%s zt9D1gp((b7hLO6Fm_55e$O?hK+7W_T+8q|_V#hKjO<;(Sc9;$G(M`b0fy%AAHlPEp z(V7_20Z-Ewnrf0j_IRQhZ}XY!FHb3dz{bjg0t)TJ;U&au2eL}>OTxzLqVm*VD@LENA@WI literal 524304 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

    <36#r>Izi*05rK-e*ellBeh(JC&nEhBpCz2 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೜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

    {;mrRZ(vRzsK$CJECXke$=)l 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¥k8D#tsLNU4hk-FjFqvJYxKwo5egH_p?)TRPA_`) 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

    NK_ZLH+
    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%0DwEMYu?IudZyf
    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�mur0wfD
    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%0A(T8Vd%VYNCph
    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
  • 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 diff --git a/pom.xml b/pom.xml index d628ed461..00494ea8f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.5-SNAPSHOT + 1.0.4-SNAPSHOT jar 2019 @@ -122,6 +122,74 @@ true + + + release + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven.source.plugin.version} + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven.gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + ${project.basedir} + ${env.GPG_PASSPHRASE} + + + + + + + + + tez + + tez + + @@ -330,68 +398,68 @@ - - org.sonatype.plugins - nexus-staging-maven-plugin - ${nexus.staging.maven.plugin.version} - true - - sonatype-nexus-staging - https://oss.sonatype.org/ - true - - - - org.apache.maven.plugins - maven-release-plugin - ${maven.release.plugin.version} - - true - false - sonatype-oss-release - deploy - - - - org.apache.maven.plugins - maven-source-plugin - ${maven.source.plugin.version} - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven.javadoc.plugin.version} - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven.gpg.plugin.version} - - - sign-artifacts - verify - - sign - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 4cc42d542eee2030be627f4f41f2a4a95029e29a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 10:30:58 +0100 Subject: [PATCH 0143/1786] travis syntax fix --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f1905fbc9..9945d24e7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -10,8 +10,7 @@ env: - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= before_install: - - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv - -in config/travis/secrets.tar.enc -out secrets.tar -d + - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in config/travis/secrets.tar.enc -out secrets.tar -d install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease From 4069ad7246db4247398feb3bd955ac03f27b40f8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 10:45:04 +0100 Subject: [PATCH 0144/1786] fixed path --- .travis.yml | 3 +-- pom.xml | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9945d24e7..e33b3e698 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,8 +11,7 @@ env: - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= before_install: - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in config/travis/secrets.tar.enc -out secrets.tar -d -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings - config/travis/mvn-settings.xml +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease notifications: email: diff --git a/pom.xml b/pom.xml index 00494ea8f..7252e1f4a 100644 --- a/pom.xml +++ b/pom.xml @@ -125,16 +125,16 @@ release - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - + + + + + + + + + + @@ -175,7 +175,7 @@ sign - ${project.basedir} + ${project.basedir}/config/travis ${env.GPG_PASSPHRASE} From 43ea489c1a1c58fc741541d186c55bd4b730216d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 10:56:51 +0100 Subject: [PATCH 0145/1786] changed paths --- .travis.yml | 2 +- pom.xml | 2 +- config/travis/secrets.tar.enc => secrets.tar.enc | Bin 3 files changed, 2 insertions(+), 2 deletions(-) rename config/travis/secrets.tar.enc => secrets.tar.enc (100%) diff --git a/.travis.yml b/.travis.yml index e33b3e698..4933a7176 100755 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ env: - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= before_install: - - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in config/travis/secrets.tar.enc -out secrets.tar -d + - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease notifications: diff --git a/pom.xml b/pom.xml index 7252e1f4a..bd026d334 100644 --- a/pom.xml +++ b/pom.xml @@ -175,7 +175,7 @@ sign - ${project.basedir}/config/travis + ${env.GPG_PASSPHRASE} diff --git a/config/travis/secrets.tar.enc b/secrets.tar.enc similarity index 100% rename from config/travis/secrets.tar.enc rename to secrets.tar.enc From dc29a163a9a27ca583f914af57a383a4a6dbe7e8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 11:01:33 +0100 Subject: [PATCH 0146/1786] added homedir --- .travis.yml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4933a7176..052cc66cc 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ env: - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= before_install: - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease notifications: email: diff --git a/pom.xml b/pom.xml index bd026d334..8599ce38d 100644 --- a/pom.xml +++ b/pom.xml @@ -175,7 +175,7 @@ sign - + ${project.basedir} ${env.GPG_PASSPHRASE} From 1ebe56d8f5e24f2b0cdeeae303012385a5dda20c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 11:11:14 +0100 Subject: [PATCH 0147/1786] changed archive --- secrets.tar.enc | Bin 5136 -> 5136 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.enc b/secrets.tar.enc index 64809d4a50fb757d8cc01897fa05e1e050db54fc..cafd060c16ff238bb7f8a40b97e8415ff4ce7e02 100644 GIT binary patch literal 5136 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

    9pgS_AIcD3PJ%s zt9D1gp((b7hLO6Fm_55e$O?hK+7W_T+8q|_V#hKjO<;(Sc9;$G(M`b0fy%AAHlPEp z(V7_20Z-Ewnrf0j_IRQhZ}XY!FHb3dz{bjg0t)TJ;U&au2eL}>OTxzLqVm*VD@LENA@WI From 0b30ffb9c1902a5f4d9883b72ea1d47218f71b69 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 11:20:36 +0100 Subject: [PATCH 0148/1786] chaged profile config --- .travis.yml | 2 +- config/travis/mvn-settings.xml | 16 +++++++++++++--- pom.xml | 8 ++++---- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 052cc66cc..4b653ed00 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ env: before_install: - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml -script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease +script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests notifications: email: - borriello.fabio@gmail.com diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index e12750acc..78ed51a39 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -43,10 +43,20 @@ + + ossrh + + true + + + gpg + ${env.GPG_PASSPHRASE} + + - - travis-profile - + + + diff --git a/pom.xml b/pom.xml index 8599ce38d..9e13415a3 100644 --- a/pom.xml +++ b/pom.xml @@ -174,10 +174,10 @@ sign - - ${project.basedir} - ${env.GPG_PASSPHRASE} - + + + + From cb59acad00484585c9c5d47f956a3698a5046962 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 11:26:29 +0100 Subject: [PATCH 0149/1786] testing --- .travis.yml | 4 ++-- pom.xml | 8 ++++---- pubring.gpg | Bin 0 -> 1473 bytes secring.gpg | Bin 0 -> 1473 bytes 4 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 pubring.gpg create mode 100644 secring.gpg diff --git a/.travis.yml b/.travis.yml index 4b653ed00..3579ad966 100755 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,8 @@ env: - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -before_install: - - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d +#before_install: +# - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests notifications: diff --git a/pom.xml b/pom.xml index 9e13415a3..8599ce38d 100644 --- a/pom.xml +++ b/pom.xml @@ -174,10 +174,10 @@ sign - - - - + + ${project.basedir} + ${env.GPG_PASSPHRASE} + diff --git a/pubring.gpg b/pubring.gpg new file mode 100644 index 0000000000000000000000000000000000000000..44eadba164885e16245e64234b5888f8d8c1b91c GIT binary patch literal 1473 zcmZQzU{GLWWMJ}kib!Jsf|$@CSr7)XA%Jxu6C;>a$H2hK&%neW!@KtMH`QOazinT2 zbH<5@H(oye`mGkILII>|Qj^aklW^3r9+4O~FcPD$6(w&SUEW*H0wG&fh!4{pY zOrT(Al4fS*WImM6z{<_Z!Op}c%EigS&BP+c#LUPf$H*k!z`(^R080U4M(qE~)Ku&C zFUWqr_l;Xl;od;UX{s?Z4q90S{*?Q_@A#Uye}5;wt619a@k6Kd}_m&xp9@^+M z{=4Vy$*_S996t;@kVvvG=U##M|=4#r*t+ z-8=Sg{cz%G`9;Rv?;dVB#$uY%EVZr_oNhZAZCE6L$xV$wa^ry{H{@icq{aTvK34Zr zl*mJY@SM|251en)w@~yuS-%GkAMVY%z_Nc+ zbn~ZMd()e=jxlANzV&1M%t^Nu-#dnCJ@(d8ZFPI4l>NJ@>cWFtFa4KjH`#8Q-kWYN zx%<a$H2hK&%neW!@KtMH`QOazinT2 zbH<5@H(oye`mGkILII>|Qj^aklW^3r9+4O~FcPD$6(w&SUEW*H0wG&fh!4{pY zOrT(Al4fS*WImM6z{<_Z!Op}c%EigS&BP+c#LUPf$H*k!z`(^R080U4M(qE~)Ku&C zFUWqr_l;Xl;od;UX{s?Z4q90S{*?Q_@A#Uye}5;wt619a@k6Kd}_m&xp9@^+M z{=4Vy$*_S996t;@kVvvG=U##M|=4#r*t+ z-8=Sg{cz%G`9;Rv?;dVB#$uY%EVZr_oNhZAZCE6L$xV$wa^ry{H{@icq{aTvK34Zr zl*mJY@SM|251en)w@~yuS-%GkAMVY%z_Nc+ zbn~ZMd()e=jxlANzV&1M%t^Nu-#dnCJ@(d8ZFPI4l>NJ@>cWFtFa4KjH`#8Q-kWYN zx%< Date: Sat, 2 Feb 2019 11:30:02 +0100 Subject: [PATCH 0150/1786] changed extension --- pubring.gpg => pubring.kbx | Bin secring.gpg => secring.kbx | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename pubring.gpg => pubring.kbx (100%) rename secring.gpg => secring.kbx (100%) diff --git a/pubring.gpg b/pubring.kbx similarity index 100% rename from pubring.gpg rename to pubring.kbx diff --git a/secring.gpg b/secring.kbx similarity index 100% rename from secring.gpg rename to secring.kbx From 12a2b36e173e465ba18cb41894f08dbb09f95f5a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 11:45:18 +0100 Subject: [PATCH 0151/1786] added unpack --- .travis.yml | 4 ++-- config/travis/mvn-settings.xml | 26 +++++++++++++------------- pubring.kbx | Bin 1473 -> 0 bytes secrets.tar.enc | Bin 5136 -> 3088 bytes secring.kbx | Bin 1473 -> 0 bytes 5 files changed, 15 insertions(+), 15 deletions(-) delete mode 100644 pubring.kbx delete mode 100644 secring.kbx diff --git a/.travis.yml b/.travis.yml index 3579ad966..359203a27 100755 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,8 @@ env: - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -#before_install: -# - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d +before_install: + - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests notifications: diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 78ed51a39..4d0778f05 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -43,20 +43,20 @@ - - ossrh - - true - - - gpg - ${env.GPG_PASSPHRASE} - - + + + + + + + + + + - - - + + travis-profile + diff --git a/pubring.kbx b/pubring.kbx deleted file mode 100644 index 44eadba164885e16245e64234b5888f8d8c1b91c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1473 zcmZQzU{GLWWMJ}kib!Jsf|$@CSr7)XA%Jxu6C;>a$H2hK&%neW!@KtMH`QOazinT2 zbH<5@H(oye`mGkILII>|Qj^aklW^3r9+4O~FcPD$6(w&SUEW*H0wG&fh!4{pY zOrT(Al4fS*WImM6z{<_Z!Op}c%EigS&BP+c#LUPf$H*k!z`(^R080U4M(qE~)Ku&C zFUWqr_l;Xl;od;UX{s?Z4q90S{*?Q_@A#Uye}5;wt619a@k6Kd}_m&xp9@^+M z{=4Vy$*_S996t;@kVvvG=U##M|=4#r*t+ z-8=Sg{cz%G`9;Rv?;dVB#$uY%EVZr_oNhZAZCE6L$xV$wa^ry{H{@icq{aTvK34Zr zl*mJY@SM|251en)w@~yuS-%GkAMVY%z_Nc+ zbn~ZMd()e=jxlANzV&1M%t^Nu-#dnCJ@(d8ZFPI4l>NJ@>cWFtFa4KjH`#8Q-kWYN zx%< zXnUp+RSpX$JkPPR9^eshc(H!wOR-c%s{sW)P>Kt=GF6Dy`ym7u0*V*x$53O<{9vjQiTDr?_0GE6ATr(jP8D5pkq$45iXqWqqG-={f`eXC@7- znN=BIx<^YCS7aH!OtsGXrYcGJU(^#Tq0KCDW zdU1|3_%xRf-nY`h zmx19dL7oBOc+m)1zPLgS=zIW#6P63MJhNoMDrAW+y0} zn?6IAF1EQ?V;%1tFOaaA#1Ubl47KZb6;*Z1^PHc)_bf{sx5n zRXr7}^)1;M!(BZNy-*B63OWi3$PGLO?*mT;r@nH2cAwPg`0Mk8%QE!Fgm~6gh1+LihwzFmyo!#!>#vFGOcqA9Iq!zCXIAaNfPsa z0H06QS&b!v(u_$MlW(2ZJPpX#^XgH{orRY{FhD~Af|cFgdi{VbI#zr&O_1%MFTC~B zgJ5I{3Coukz=~kyQDaRxJ#G~Ge)g5>n+0F)Q!xJ&T|&!F4>u5y0ap=ehr#sqsOcYH z-&t4q8n>`)4agXcCc7Hgbw9%h#s4L;^bN85T;0#O6{C`4y8`X%ESjj`3Qj>$ztQE& z-v>$*c)iX9?Wpr&86>@4!rtZqfu&nK#!lS_NE$f~xid1+V)s|sf;>d%M!Oz{Dl-S|yo+aE- zgVDB4K4Xh~J}8VJU7<7FZd}v>Iy*!oUy`X771BLhm+_@T90T^h^4Yezs;t22Qxe)~ z-?}x?ueHLa79^KpdNcm5u_&dP-mc7ca&2ux)Epr>FD=qaBrfhu-+g6BK-24klz zt)ueN4qblZ3Hx7x1ykTMoK^OPKxTuKSfykKJBy&1G8^3n*xk@2P=nOdBjMdgrw2Fa{lj^gjdIL$A=Z0~7Dv-VZ& zcNl=tcLXf<#J9Hb>sG`D&NO;_31fxpmA2)ws*o;6U7FCrsnQdA<}W>$nE-f=XdV2~ zj3-urJdTYSoJFt>QfUw~ypHkO6A#miEP2T@+EfIztUyzk;PF`Tv+nI8cSX-^u|hKy zDpAEmR+Qa{B{0HxA1NGXw&k1ch-=zzwGZm1-O5N+Wh_is!aT?)<&$M$?m}Yw7)tl@ve&UOzos zGDx5wcopoD;sdqf>tbM3>Isv@G}KxfS-{OIs1H<_YEUGek8B?zT8Iq?Rq0_peM&_g zJle7i{fBeJBmvA~$pkEwOdvhWwl7+s`l#S`z7`Txk$c|C*0H5_(U?vup=}FFd{|&m z>bBaYBI1|NWtUQIC<|RNE#SFUhL9c!@%!!v?nm4wt;N;L1TW9*vQgvSfSfU1kI;m} z*~o7bMAKHX30O6K46!Rxh<+|OwBhSFgd0V@20k#g#cA`}l!fsE%{jm|#bU1WI z*DdsSHrS-yP887m6eSp3ryVOhUs+8l)Y4%sfvZMx{R|wQ;Sqp(T=UBccr3pO41JUL z!uAWgV6py)IjZL$AM;U0&)|w`5OJ6E(RV+a{9q+9RtGq>;(A*#G6yC)MUVJFFU7U28)q3SpFD$fU+#>OpcFg>=$)cIR{RE_K!4ja+IB;G>l##j|9+<0L$ zW14MAa-c1P(?E@j=iXH6T!izAUr9LdT3Bs7y^n76N2bRacDqq^t@0mc`$B z!hRx5UpL$@hJGHyCs5K*g}09Wj-eB? zg7Q(=>NLOXE3-k}ZyYB298;QYxl(Cv)9Pd`PC8OJv#uPeb$D#}y0?4bOLaf52SFEe zsfeHho#c>%2dOo(7&r%=_>tC_1SFjjZ4*F0fYs6+28wb;2lJKxZe1ve&o0qVku27$ zrTbe1N&tBS2o^b#(IgS1bRh4>=@v}TxxQviaC~?eQ$ESUg|d;e4WX83apTQjQwE`A=PsBaxwfX{xf|Jkb>bhX!(5{x^hSbxB_xe%Dg1985P=Td^&F6kp0KKhBxBOmt+wk2l zyJ#{LArOWx=j1y*IH@zNGZ-US#UVnw-7W+SktVF@=20~lffwD}SXK(|*MAP%k&dr2 zLPbdcb%mE92gp$VvdCBpNek&(Gv%5>Dv9{+OtoqufCkYwJo^?Dl ztq+?s2-c)8YZFSG7dhdtcYU$+k;&kgCn2v8%Og+c1P?)6$Vi3POI8OyN+(bzC?<AxhL)`z-58qGvYBqBSkqq12T0KHU|N?~d2Lyp5ZFey6{-<0Wac_F%M#Mmj)k~u#|&ptjP!rPQ;oM_A`{2s?#=v<;_|l4f@J>k z1F)}p3YM34xs5BkmeSD|7;Ntw5W>=9T!EC*q9w8&4q8fYc{eD`Ad3p@L{>_ia+$%l zrRl9#Mu2yE1Cx20`!&Rl$Gg5j#?}&|UZ*tDE{-%yLiw4(1xauM8VhbLwr`v9NrDsv zmJIc*_EDA&Xtq!jh@1o5{{YdxI{jp#-sTcNydzg|Z8TIa0x1TUh7cS3H?ervTzdMa z?v70!di!-VQKF8BZ!xt|l2Lu9T3h4VW*L)2@%vGghC#glt;TQ9*cHSW?0Xv`hQJij e0uzp_n63E?+wqCvEK|2)R7NMLqkdEQJ>mKQ literal 5136 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 Date: Sat, 2 Feb 2019 11:57:16 +0100 Subject: [PATCH 0152/1786] added keyname --- .travis.yml | 47 +++++++++++++++++++++++++++++++++ config/travis/mvn-settings.xml | 9 ++++++- secrets.tar.enc | Bin 3088 -> 5136 bytes 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 359203a27..d18e58f75 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,13 @@ cache: - "~/.m2/repository" env: global: + # sonatype jira username: OSSRH_USERNAME - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= + # sonatype jira password: OSSRH_PASSWORD - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= + # GPG_KEYNAME + - secure: ZsM0GO/A6vCklSVdzBwma8XD2AWeWOtinnBLwtoLAp/EEpaNOKpFd9gUocI48+zq+5WAOxczXEIb5/qwpg7IhSSUDniit+yg9Nr7J6imUKGQAzGYtJn2iroYeK6qdHF1uLYPiMK2u7BhE81XoUc6Pml2HC2QnTus5yNXsKjj44IrESDoxnsdchvYrZAdTxWdAOUI1vU0Kapx8sbYpNCMe9pI07SzOQXsZSb/hwMQSE2RI5pTrwlpusSkzsVRFnC8W0tS2bgxSPfMylIywOPWbmolsSIrBsYksk+IsteR8KisK09/suerTeUW2XJOz/PLiAd5zZobV22SIG4T3VzbJU2a021NJpKa06Tw+e0fPr7coBmcJ7l6v6IS6bCTPGCDA3CLBlfZpYxXaZ1IrAY0EOzuafaef9javxfosuQFwRwifLoNSgZDWdADC0AHwK2ungiTwRjmNKSuEd0SgCnHH3PeGQDoh2u/MKn531Rf8Q+/aZXAFV4Gkklfpyw1Y3RJvtlr4ZTXOn2/vFCzVMVYYeuqLPT0IJtV2mt8SXheeubMWSAWJfQ/eQny+9LIN0q0Y4uqsHwLlqwnXL+oYQtMlHy5Cy4cv5DI1XsV5eyvCfpINJbs5/+54DT9+EWg1BIqGFXLaV/XmRffJgn6SFGxL1tEGurj2Db6xLGy1+ttNng= + # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= before_install: - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar @@ -16,3 +21,45 @@ script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -Dskip notifications: email: - borriello.fabio@gmail.com + +#jobs: +# include: +# # If the branch is not master it just builds the application +# - stage: "Build" +# name: "Build and Test" +# if: NOT branch = master +# jdk: oraclejdk11 +# install: mvn clean install -Dmaven.javadoc.skip=true -B +# # If the branch is master it sends the quality report to SonarCloud +# - stage: "Build, Test and Quality Check" +# name: "Building, testing and sending a quality report to SonarCloud" +# if: branch = master +# jdk: oraclejdk11 +# install: mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build and Publish" +# name: "Building site and publishing on GitHub pages" +# if: branch = master +# jdk: oraclejdk8 +# install: mvn clean site:site -DskipTests=true -B +# deploy: +# provider: pages +# local-dir: target/site +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# branch: master +# - stage: "Release" +# name: "Releasing artifacts on Maven central" +# before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d +# deploy: +# - provider: script +# script: config/travis/deploy.sh +# skip_cleanup: true +# on: +# branch: master +# - provider: script +# script: config/travis/deploy.sh +# skip_cleanup: true +# on: +# tags: true diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 4d0778f05..d062690cc 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -38,8 +38,15 @@ - gpg2 + + + + gpg + ${env.GPG_KEYNAME} ${env.GPG_PASSPHRASE} + false + pubring.gpg + secring.gpg diff --git a/secrets.tar.enc b/secrets.tar.enc index 50370d67ce77f99f39860bd96a0e7769b8b96a5d..161d255f83bca53e7920fb847fbb19464e18f0b1 100644 GIT binary patch literal 5136 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 e0uzp_n63E?+wqCvEK|2)R7NMLqkdEQJ>mKQ From 776ee054a45f21c2fc0ab3e3d370a38f6794b97a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 12:01:32 +0100 Subject: [PATCH 0153/1786] changes file extension --- config/travis/mvn-settings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index d062690cc..f3cfa0cd1 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -45,8 +45,8 @@ ${env.GPG_KEYNAME} ${env.GPG_PASSPHRASE} false - pubring.gpg - secring.gpg + pubring.kbx + secring.kbx From 3f37bbefc99998498f6ef4a7f45625e5fee2c877 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:09:12 +0100 Subject: [PATCH 0154/1786] changed key extension --- config/travis/mvn-settings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index f3cfa0cd1..d062690cc 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -45,8 +45,8 @@ ${env.GPG_KEYNAME} ${env.GPG_PASSPHRASE} false - pubring.kbx - secring.kbx + pubring.gpg + secring.gpg From 8dfd2274ed052e226e3bd1f6ba98864ffc8d04be Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:18:58 +0100 Subject: [PATCH 0155/1786] removed passphrase --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 8599ce38d..9e13415a3 100644 --- a/pom.xml +++ b/pom.xml @@ -174,10 +174,10 @@ sign - - ${project.basedir} - ${env.GPG_PASSPHRASE} - + + + + From ed17295209825c01b7472194abfd83e00c1efc49 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:19:39 +0100 Subject: [PATCH 0156/1786] [maven-release-plugin] prepare release bean-utils-library-1.0.4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9e13415a3..d49ef439e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.4-SNAPSHOT + 1.0.4 jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-${project.version} + bean-utils-library-1.0.4 From 17726a20ca32f641c00a179c33da6f13cab91638 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:19:46 +0100 Subject: [PATCH 0157/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d49ef439e..33d37ecc2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.4 + 1.0.5-SNAPSHOT jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.4 + bean-utils-library-${project.version} From 994f1babf467728d1d79737f20819159b3414f25 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:21:03 +0100 Subject: [PATCH 0158/1786] restored old version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33d37ecc2..9e13415a3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.5-SNAPSHOT + 1.0.4-SNAPSHOT jar 2019 From 210b3a0f504efbe2306ecd1e5866204b29ae59c9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:25:46 +0100 Subject: [PATCH 0159/1786] [maven-release-plugin] prepare release bean-utils-library-1.0.4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9e13415a3..d49ef439e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.4-SNAPSHOT + 1.0.4 jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-${project.version} + bean-utils-library-1.0.4 From d06f991e6491f3ac6b38b7256b31a453a26c530f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:25:53 +0100 Subject: [PATCH 0160/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d49ef439e..33d37ecc2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.4 + 1.0.5-SNAPSHOT jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.4 + bean-utils-library-${project.version} From 239c119ca014b0609fea1340b6d9229c0a61ca80 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:29:28 +0100 Subject: [PATCH 0161/1786] [maven-release-plugin] prepare release bean-utils-library-1.0.5 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 33d37ecc2..cb694e398 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.5-SNAPSHOT + 1.0.5 jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-${project.version} + bean-utils-library-1.0.5 From 7f23540016039d0437f73bc3c7d4b36c9c0c018b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:29:35 +0100 Subject: [PATCH 0162/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index cb694e398..1e2f200ef 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.5 + 1.0.6-SNAPSHOT jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.5 + bean-utils-library-${project.version} From 0c0772fcc0f181031ef0e8631d1283437776a558 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 13:43:44 +0100 Subject: [PATCH 0163/1786] modified before install --- .travis.yml | 7 ++++++- config/travis/mvn-settings.xml | 25 +++++++++++++------------ pom.xml | 6 ------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index d18e58f75..1d705b375 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,13 @@ env: - secure: ZsM0GO/A6vCklSVdzBwma8XD2AWeWOtinnBLwtoLAp/EEpaNOKpFd9gUocI48+zq+5WAOxczXEIb5/qwpg7IhSSUDniit+yg9Nr7J6imUKGQAzGYtJn2iroYeK6qdHF1uLYPiMK2u7BhE81XoUc6Pml2HC2QnTus5yNXsKjj44IrESDoxnsdchvYrZAdTxWdAOUI1vU0Kapx8sbYpNCMe9pI07SzOQXsZSb/hwMQSE2RI5pTrwlpusSkzsVRFnC8W0tS2bgxSPfMylIywOPWbmolsSIrBsYksk+IsteR8KisK09/suerTeUW2XJOz/PLiAd5zZobV22SIG4T3VzbJU2a021NJpKa06Tw+e0fPr7coBmcJ7l6v6IS6bCTPGCDA3CLBlfZpYxXaZ1IrAY0EOzuafaef9javxfosuQFwRwifLoNSgZDWdADC0AHwK2ungiTwRjmNKSuEd0SgCnHH3PeGQDoh2u/MKn531Rf8Q+/aZXAFV4Gkklfpyw1Y3RJvtlr4ZTXOn2/vFCzVMVYYeuqLPT0IJtV2mt8SXheeubMWSAWJfQ/eQny+9LIN0q0Y4uqsHwLlqwnXL+oYQtMlHy5Cy4cv5DI1XsV5eyvCfpINJbs5/+54DT9+EWg1BIqGFXLaV/XmRffJgn6SFGxL1tEGurj2Db6xLGy1+ttNng= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= +#before_install: +# - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar before_install: - - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar +- if [ "${TRAVIS_PULL_REQUEST}" = "false" ] ; then + openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d + && tar xvf secrets.tar ; + fi install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests notifications: diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index d062690cc..8ac213af7 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -50,20 +50,21 @@ - - - - - - + + ossrh + + true + + - - - + ${env.GPG_KEYNAME} + ${env.GPG_PASSPHRASE} + + - - travis-profile - + + + diff --git a/pom.xml b/pom.xml index 1e2f200ef..306c2d154 100644 --- a/pom.xml +++ b/pom.xml @@ -184,12 +184,6 @@ - - tez - - tez - - From 6f64fcd71ddb96be679632e84b6e8e921a8b0483 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 14:00:29 +0100 Subject: [PATCH 0164/1786] changed key path --- .travis.yml | 4 ++-- config/travis/mvn-settings.xml | 16 ++++++++-------- pom.xml | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1d705b375..949108707 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,8 @@ before_install: openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar ; fi -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml -script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml +script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Prelease -DskipTests notifications: email: - borriello.fabio@gmail.com diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 8ac213af7..e28ba8a37 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -45,16 +45,16 @@ ${env.GPG_KEYNAME} ${env.GPG_PASSPHRASE} false - pubring.gpg - secring.gpg + ../../pubring.gpg + ../../secring.gpg ossrh - - true - + + + ${env.GPG_KEYNAME} @@ -62,9 +62,9 @@ - - - + + travis-profile + diff --git a/pom.xml b/pom.xml index 306c2d154..39f74315c 100644 --- a/pom.xml +++ b/pom.xml @@ -174,10 +174,10 @@ sign - - - - + + ${project.basedir} + ${env.GPG_PASSPHRASE} + From c45f666d96e764c8933e8cdb2e71690609a6508f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 14:04:03 +0100 Subject: [PATCH 0165/1786] duplicated settings file --- .travis.yml | 4 +- mvn-settings.xml | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 2 deletions(-) create mode 100755 mvn-settings.xml diff --git a/.travis.yml b/.travis.yml index 949108707..53e7c0c17 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,8 @@ before_install: openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar ; fi -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml -script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Prelease -DskipTests +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings mvn-settings.xml +script: mvn deploy -B --global-settings mvn-settings.xml -Prelease -DskipTests notifications: email: - borriello.fabio@gmail.com diff --git a/mvn-settings.xml b/mvn-settings.xml new file mode 100755 index 000000000..c38fa2a90 --- /dev/null +++ b/mvn-settings.xml @@ -0,0 +1,106 @@ + + + + ossrh + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + + + + ${github_server_id} + ${github_oauth_token} + + + + + travis-profile + + + + + false + always + warn + + + false + never + fail + + codehaus-snapshots + Codehaus (snapshots) + https://nexus.codehaus.org/snapshots/ + + + + + + + + gpg + ${env.GPG_KEYNAME} + ${env.GPG_PASSPHRASE} + false + pubring.gpg + secring.gpg + + + + + ossrh + + + + + + ${env.GPG_KEYNAME} + ${env.GPG_PASSPHRASE} + + + + + travis-profile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a8ea671e52afed434b5e183d3fa7221c8a6d31ef Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 14:24:45 +0100 Subject: [PATCH 0166/1786] modified config --- .travis.yml | 4 +- config/travis/mvn-settings.xml | 16 ++--- mvn-settings.xml | 106 --------------------------------- pom.xml | 7 ++- 4 files changed, 15 insertions(+), 118 deletions(-) delete mode 100755 mvn-settings.xml diff --git a/.travis.yml b/.travis.yml index 53e7c0c17..949108707 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,8 @@ before_install: openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar ; fi -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings mvn-settings.xml -script: mvn deploy -B --global-settings mvn-settings.xml -Prelease -DskipTests +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml +script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Prelease -DskipTests notifications: email: - borriello.fabio@gmail.com diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index e28ba8a37..a3bd6ac15 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -37,17 +37,17 @@ - + - gpg - ${env.GPG_KEYNAME} - ${env.GPG_PASSPHRASE} - false - ../../pubring.gpg - ../../secring.gpg - + + + + + + + diff --git a/mvn-settings.xml b/mvn-settings.xml deleted file mode 100755 index c38fa2a90..000000000 --- a/mvn-settings.xml +++ /dev/null @@ -1,106 +0,0 @@ - - - - ossrh - ${env.OSSRH_USERNAME} - ${env.OSSRH_PASSWORD} - - - - ${github_server_id} - ${github_oauth_token} - - - - - travis-profile - - - - - false - always - warn - - - false - never - fail - - codehaus-snapshots - Codehaus (snapshots) - https://nexus.codehaus.org/snapshots/ - - - - - - - - gpg - ${env.GPG_KEYNAME} - ${env.GPG_PASSPHRASE} - false - pubring.gpg - secring.gpg - - - - - ossrh - - - - - - ${env.GPG_KEYNAME} - ${env.GPG_PASSPHRASE} - - - - - travis-profile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pom.xml b/pom.xml index 39f74315c..abf0b284a 100644 --- a/pom.xml +++ b/pom.xml @@ -125,6 +125,9 @@ release + + ${env.GPG_PASSPHRASE} + @@ -175,8 +178,8 @@ sign - ${project.basedir} - ${env.GPG_PASSPHRASE} + + ${gpg.passphrase} From 0877bd5a55fc16e59b1fd49352d7c1b22e536a88 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 14:36:42 +0100 Subject: [PATCH 0167/1786] adding same configuration working locally --- .travis.yml | 8 +++--- config/travis/mvn-settings.xml | 9 +++++++ .../travis/secrets.tar.enc | Bin pom.xml | 25 ++++++++---------- 4 files changed, 24 insertions(+), 18 deletions(-) rename secrets.tar.enc => config/travis/secrets.tar.enc (100%) diff --git a/.travis.yml b/.travis.yml index 949108707..bdc00668b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,11 +18,11 @@ env: # - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar before_install: - if [ "${TRAVIS_PULL_REQUEST}" = "false" ] ; then - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d - && tar xvf secrets.tar ; + openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d + && tar xvf config/travis/secrets.tar ; fi -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --global-settings config/travis/mvn-settings.xml -script: mvn deploy -B --global-settings config/travis/mvn-settings.xml -Prelease -DskipTests +install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml +script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests notifications: email: - borriello.fabio@gmail.com diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index a3bd6ac15..131492d85 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -49,6 +49,13 @@ + + + ${env.GPG_KEYNAME} + ${env.GPG_PASSPHRASE} + pubring.gpg + pubring.gpg + ossrh @@ -59,6 +66,8 @@ ${env.GPG_KEYNAME} ${env.GPG_PASSPHRASE} + pubring.gpg + pubring.gpg diff --git a/secrets.tar.enc b/config/travis/secrets.tar.enc similarity index 100% rename from secrets.tar.enc rename to config/travis/secrets.tar.enc diff --git a/pom.xml b/pom.xml index abf0b284a..8bb24355d 100644 --- a/pom.xml +++ b/pom.xml @@ -125,19 +125,16 @@ release - - ${env.GPG_PASSPHRASE} - - - - - - - - - - - + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + @@ -179,7 +176,7 @@ - ${gpg.passphrase} + ${env.GPG_PASSPHRASE} From 5fa4c1e135750c0d53c0a63220bb35140f736e41 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 17:23:11 +0100 Subject: [PATCH 0168/1786] added missing info --- .travis.yml | 28 ++++++--- config/travis/mvn-settings.xml | 101 +++------------------------------ config/travis/private-key.gpg | 60 ++++++++++++++++++++ config/travis/secrets.tar.enc | Bin 5136 -> 0 bytes 4 files changed, 88 insertions(+), 101 deletions(-) create mode 100644 config/travis/private-key.gpg delete mode 100644 config/travis/secrets.tar.enc diff --git a/.travis.yml b/.travis.yml index bdc00668b..7f4328b35 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,13 +16,27 @@ env: - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= #before_install: # - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar -before_install: -- if [ "${TRAVIS_PULL_REQUEST}" = "false" ] ; then - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d - && tar xvf config/travis/secrets.tar ; - fi -install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml -script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests +#before_install: +#- if [ "${TRAVIS_PULL_REQUEST}" = "false" ] ; then +# openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d +# && tar xvf config/travis/secrets.tar ; +# fi +#install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml +#script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests +script: make build + +deploy: + provider: script + script: make travis-deploy + on: + tags: true +build: + mvn clean install + +travis-deploy: + gpg --import config/travis/private-key.gpg + mvn versions:set -DnewVersion=${TRAVIS_TAG} + mvn clean deploy -P release --settings config/travis/mvn-settings.xml notifications: email: - borriello.fabio@gmail.com diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 131492d85..af652df75 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -11,105 +11,18 @@ ${github_oauth_token} - - - travis-profile - - - - - false - always - warn - - - false - never - fail - - codehaus-snapshots - Codehaus (snapshots) - https://nexus.codehaus.org/snapshots/ - - - - - - - - - - - - - - - - - ${env.GPG_KEYNAME} - ${env.GPG_PASSPHRASE} - pubring.gpg - pubring.gpg - - + - ossrh - - - + release + + true + - - ${env.GPG_KEYNAME} + gpg + F78F7C8A29B159BA ${env.GPG_PASSPHRASE} - pubring.gpg - pubring.gpg - - travis-profile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/config/travis/private-key.gpg b/config/travis/private-key.gpg new file mode 100644 index 000000000..7f8b4d5ed --- /dev/null +++ b/config/travis/private-key.gpg @@ -0,0 +1,60 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +FZQ= +=0ktR +-----END PGP PRIVATE KEY BLOCK----- diff --git a/config/travis/secrets.tar.enc b/config/travis/secrets.tar.enc deleted file mode 100644 index 161d255f83bca53e7920fb847fbb19464e18f0b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5136 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 Date: Sat, 2 Feb 2019 17:28:09 +0100 Subject: [PATCH 0169/1786] removed makefile --- .travis.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7f4328b35..98103fa30 100755 --- a/.travis.yml +++ b/.travis.yml @@ -27,16 +27,17 @@ script: make build deploy: provider: script - script: make travis-deploy - on: - tags: true + script: + gpg --import config/travis/private-key.gpg + mvn versions:set -DnewVersion=${TRAVIS_TAG} + mvn clean deploy -P release --settings config/travis/mvn-settings.xml build: mvn clean install -travis-deploy: - gpg --import config/travis/private-key.gpg - mvn versions:set -DnewVersion=${TRAVIS_TAG} - mvn clean deploy -P release --settings config/travis/mvn-settings.xml +#travis-deploy: +# gpg --import config/travis/private-key.gpg +# mvn versions:set -DnewVersion=${TRAVIS_TAG} +# mvn clean deploy -P release --settings config/travis/mvn-settings.xml notifications: email: - borriello.fabio@gmail.com From 724a9134ae527a0180ee0559aba1b9acce986fc4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 17:30:12 +0100 Subject: [PATCH 0170/1786] removed make build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 98103fa30..5afcaaaee 100755 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ env: # fi #install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml #script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests -script: make build +#script: make build deploy: provider: script From 812e6ff8a8a6f002007c99eb2940a008cc318c43 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 17:32:43 +0100 Subject: [PATCH 0171/1786] removed passphrase --- pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pom.xml b/pom.xml index 8bb24355d..e8f004623 100644 --- a/pom.xml +++ b/pom.xml @@ -174,10 +174,6 @@ sign - - - ${env.GPG_PASSPHRASE} - From 88e38a37868c421d117dea0f2b927b46c038fe91 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 17:41:08 +0100 Subject: [PATCH 0172/1786] deploying with script --- .travis.yml | 49 ++++++++++++++++++++--------------------- config/travis/deploy.sh | 8 +++++-- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5afcaaaee..506b1f112 100755 --- a/.travis.yml +++ b/.travis.yml @@ -25,14 +25,14 @@ env: #script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests #script: make build -deploy: - provider: script - script: - gpg --import config/travis/private-key.gpg - mvn versions:set -DnewVersion=${TRAVIS_TAG} - mvn clean deploy -P release --settings config/travis/mvn-settings.xml -build: - mvn clean install +#deploy: +# provider: script +# script: +# gpg --import config/travis/private-key.gpg +# mvn versions:set -DnewVersion=${TRAVIS_TAG} +# mvn clean deploy -P release --settings config/travis/mvn-settings.xml +#build: +# mvn clean install #travis-deploy: # gpg --import config/travis/private-key.gpg @@ -42,9 +42,9 @@ notifications: email: - borriello.fabio@gmail.com -#jobs: -# include: -# # If the branch is not master it just builds the application +jobs: + include: + # If the branch is not master it just builds the application # - stage: "Build" # name: "Build and Test" # if: NOT branch = master @@ -69,17 +69,16 @@ notifications: # keep-history: true # on: # branch: master -# - stage: "Release" -# name: "Releasing artifacts on Maven central" -# before_install: openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in secrets.tar.enc -out secrets.tar -d -# deploy: -# - provider: script -# script: config/travis/deploy.sh -# skip_cleanup: true -# on: -# branch: master -# - provider: script -# script: config/travis/deploy.sh -# skip_cleanup: true -# on: -# tags: true + - stage: "Release" + name: "Releasing artifacts on Maven central" + deploy: + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + branch: master + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index ef123d2fd..52448baf1 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -5,9 +5,13 @@ set -e if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ ! -z "$TRAVIS_TAG" ]; then echo "Deploying release" - mvn clean deploy --settings mvn-settings.xml -B -U -P sonatype-oss-release "$@" -DskipTests=true + gpg --import config/travis/private-key.gpg +# mvn versions:set -DnewVersion=${TRAVIS_TAG} + mvn clean deploy --settings mvn-settings.xml -P release -DskipTests=true +# mvn clean deploy --settings mvn-settings.xml -B -U -P sonatype-oss-release "$@" -DskipTests=true else echo "Deploying snapshot" - mvn clean deploy --settings mvn-settings.xml -B -U -P -DskipTests=true + gpg --import config/travis/private-key.gpg + mvn clean deploy --settings mvn-settings.xml -P release -B -U -P -DskipTests=true fi fi \ No newline at end of file From 6194eb3b0460dc2fdb9a68517ce7ce8e0a4e6413 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 17:50:16 +0100 Subject: [PATCH 0173/1786] fixed settings path into script file --- config/travis/deploy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 52448baf1..e36a55b0a 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -7,11 +7,11 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg # mvn versions:set -DnewVersion=${TRAVIS_TAG} - mvn clean deploy --settings mvn-settings.xml -P release -DskipTests=true + mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true # mvn clean deploy --settings mvn-settings.xml -B -U -P sonatype-oss-release "$@" -DskipTests=true else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn clean deploy --settings mvn-settings.xml -P release -B -U -P -DskipTests=true + mvn clean deploy --settings config/travis/mvn-settings.xml -P release -B -U -P -DskipTests=true fi fi \ No newline at end of file From 000da1761c2fb04f0d0ae6e7912afd0690f6c87a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 18:03:59 +0100 Subject: [PATCH 0174/1786] encoded private key --- .travis.yml | 34 ++--------------- config/travis/deploy.sh | 6 +-- config/travis/mvn-settings.xml | 2 +- config/travis/private-key.gpg | 60 ------------------------------ config/travis/private-key.gpg.enc | Bin 0 -> 3664 bytes 5 files changed, 8 insertions(+), 94 deletions(-) delete mode 100644 config/travis/private-key.gpg create mode 100644 config/travis/private-key.gpg.enc diff --git a/.travis.yml b/.travis.yml index 506b1f112..e2ceb6c3f 100755 --- a/.travis.yml +++ b/.travis.yml @@ -10,38 +10,10 @@ env: - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= # sonatype jira password: OSSRH_PASSWORD - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= - # GPG_KEYNAME - - secure: ZsM0GO/A6vCklSVdzBwma8XD2AWeWOtinnBLwtoLAp/EEpaNOKpFd9gUocI48+zq+5WAOxczXEIb5/qwpg7IhSSUDniit+yg9Nr7J6imUKGQAzGYtJn2iroYeK6qdHF1uLYPiMK2u7BhE81XoUc6Pml2HC2QnTus5yNXsKjj44IrESDoxnsdchvYrZAdTxWdAOUI1vU0Kapx8sbYpNCMe9pI07SzOQXsZSb/hwMQSE2RI5pTrwlpusSkzsVRFnC8W0tS2bgxSPfMylIywOPWbmolsSIrBsYksk+IsteR8KisK09/suerTeUW2XJOz/PLiAd5zZobV22SIG4T3VzbJU2a021NJpKa06Tw+e0fPr7coBmcJ7l6v6IS6bCTPGCDA3CLBlfZpYxXaZ1IrAY0EOzuafaef9javxfosuQFwRwifLoNSgZDWdADC0AHwK2ungiTwRjmNKSuEd0SgCnHH3PeGQDoh2u/MKn531Rf8Q+/aZXAFV4Gkklfpyw1Y3RJvtlr4ZTXOn2/vFCzVMVYYeuqLPT0IJtV2mt8SXheeubMWSAWJfQ/eQny+9LIN0q0Y4uqsHwLlqwnXL+oYQtMlHy5Cy4cv5DI1XsV5eyvCfpINJbs5/+54DT9+EWg1BIqGFXLaV/XmRffJgn6SFGxL1tEGurj2Db6xLGy1+ttNng= + # GPG_KEYNAME + - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -#before_install: -# - openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in secrets.tar.enc -out secrets.tar -d && tar xvf secrets.tar -#before_install: -#- if [ "${TRAVIS_PULL_REQUEST}" = "false" ] ; then -# openssl aes-256-cbc -K $encrypted_4e2bc30042f9_key -iv $encrypted_4e2bc30042f9_iv -in config/travis/secrets.tar.enc -out config/travis/secrets.tar -d -# && tar xvf config/travis/secrets.tar ; -# fi -#install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V --settings config/travis/mvn-settings.xml -#script: mvn deploy -B --settings config/travis/mvn-settings.xml -Prelease -DskipTests -#script: make build - -#deploy: -# provider: script -# script: -# gpg --import config/travis/private-key.gpg -# mvn versions:set -DnewVersion=${TRAVIS_TAG} -# mvn clean deploy -P release --settings config/travis/mvn-settings.xml -#build: -# mvn clean install - -#travis-deploy: -# gpg --import config/travis/private-key.gpg -# mvn versions:set -DnewVersion=${TRAVIS_TAG} -# mvn clean deploy -P release --settings config/travis/mvn-settings.xml -notifications: - email: - - borriello.fabio@gmail.com - jobs: include: # If the branch is not master it just builds the application @@ -71,6 +43,8 @@ jobs: # branch: master - stage: "Release" name: "Releasing artifacts on Maven central" + before_deploy: + - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in private-key.gpg.enc -out private-key.gpg -d deploy: - provider: script script: config/travis/deploy.sh diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index e36a55b0a..c09fa613e 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,12 +6,12 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ ! -z "$TRAVIS_TAG" ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg -# mvn versions:set -DnewVersion=${TRAVIS_TAG} + mvn versions:set -D newVersion=${TRAVIS_TAG} mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true -# mvn clean deploy --settings mvn-settings.xml -B -U -P sonatype-oss-release "$@" -DskipTests=true else echo "Deploying snapshot" + echo ${TRAVIS_TAG} gpg --import config/travis/private-key.gpg - mvn clean deploy --settings config/travis/mvn-settings.xml -P release -B -U -P -DskipTests=true + mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true fi fi \ No newline at end of file diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index af652df75..f83952c5c 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -20,7 +20,7 @@ gpg - F78F7C8A29B159BA + ${env.GPG_KEYNAME} ${env.GPG_PASSPHRASE} diff --git a/config/travis/private-key.gpg b/config/travis/private-key.gpg deleted file mode 100644 index 7f8b4d5ed..000000000 --- a/config/travis/private-key.gpg +++ /dev/null @@ -1,60 +0,0 @@ ------BEGIN PGP PRIVATE KEY BLOCK----- - -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 -FZQ= -=0ktR ------END PGP PRIVATE KEY BLOCK----- diff --git a/config/travis/private-key.gpg.enc b/config/travis/private-key.gpg.enc new file mode 100644 index 0000000000000000000000000000000000000000..d70f6838bf46fcdd53d225f85c67ec7c00e9e86d GIT binary patch literal 3664 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 literal 0 HcmV?d00001 From 08595f8aabdae1896d7282e258a8a0170c5eec69 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 18:08:23 +0100 Subject: [PATCH 0175/1786] fixed key path --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e2ceb6c3f..120c71795 100755 --- a/.travis.yml +++ b/.travis.yml @@ -44,7 +44,7 @@ jobs: - stage: "Release" name: "Releasing artifacts on Maven central" before_deploy: - - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in private-key.gpg.enc -out private-key.gpg -d + - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d deploy: - provider: script script: config/travis/deploy.sh @@ -54,5 +54,5 @@ jobs: - provider: script script: config/travis/deploy.sh skip_cleanup: true - on: - tags: true +# on: +# tags: true From 310c99cbe1d4961d2005e6d48ee0de584f20fc34 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 18:14:18 +0100 Subject: [PATCH 0176/1786] added on tags true --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 120c71795..23d65d33d 100755 --- a/.travis.yml +++ b/.travis.yml @@ -54,5 +54,5 @@ jobs: - provider: script script: config/travis/deploy.sh skip_cleanup: true -# on: -# tags: true + on: + tags: true From 858e007e9159119bdd18b9315da4dbc6d73646ec Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 18:25:24 +0100 Subject: [PATCH 0177/1786] Completed travis configuration --- .travis.yml | 48 +++++++++++++------------- config/travis/deploy.sh | 1 - pom.xml | 75 +---------------------------------------- 3 files changed, 25 insertions(+), 99 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d65d33d..09dfab440 100755 --- a/.travis.yml +++ b/.travis.yml @@ -17,30 +17,30 @@ env: jobs: include: # If the branch is not master it just builds the application -# - stage: "Build" -# name: "Build and Test" -# if: NOT branch = master -# jdk: oraclejdk11 -# install: mvn clean install -Dmaven.javadoc.skip=true -B -# # If the branch is master it sends the quality report to SonarCloud -# - stage: "Build, Test and Quality Check" -# name: "Building, testing and sending a quality report to SonarCloud" -# if: branch = master -# jdk: oraclejdk11 -# install: mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build and Publish" -# name: "Building site and publishing on GitHub pages" -# if: branch = master -# jdk: oraclejdk8 -# install: mvn clean site:site -DskipTests=true -B -# deploy: -# provider: pages -# local-dir: target/site -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true -# on: -# branch: master + - stage: "Build" + name: "Build and Test" + if: NOT branch = master + jdk: oraclejdk11 + install: mvn clean install -Dmaven.javadoc.skip=true -B + # If the branch is master it sends the quality report to SonarCloud + - stage: "Build, Test and Quality Check" + name: "Building, testing and sending a quality report to SonarCloud" + if: branch = master + jdk: oraclejdk11 + install: mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build and Publish" + name: "Building site and publishing on GitHub pages" + if: branch = master + jdk: oraclejdk8 + install: mvn clean site:site -DskipTests=true -B + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + branch: master - stage: "Release" name: "Releasing artifacts on Maven central" before_deploy: diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index c09fa613e..279ff6ae7 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -10,7 +10,6 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true else echo "Deploying snapshot" - echo ${TRAVIS_TAG} gpg --import config/travis/private-key.gpg mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true fi diff --git a/pom.xml b/pom.xml index e8f004623..eb12e1a7c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.6-SNAPSHOT + 1.0.17-SNAPSHOT jar 2019 @@ -125,16 +125,6 @@ release - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - @@ -387,69 +377,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 40e71a88cea486dca0c6d9fb1125c562698d1d6e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 18:30:45 +0100 Subject: [PATCH 0178/1786] minor: changed stage name --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 638266834..cb3e96d05 100755 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,7 @@ jobs: on: branch: master - stage: "Release" - name: "Releasing artifacts on Maven central" + name: "Releasing artifacts" before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d deploy: From e127607eacd6b1aa89eadc137141982c63ddc931 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 21:33:50 +0100 Subject: [PATCH 0179/1786] Fix travis config --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index cb3e96d05..b00937b64 100755 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ os: - linux cache: directories: -<<<<<<< HEAD - "~/.m2/repository" env: global: @@ -15,10 +14,8 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -======= - ~/.m2/repository install: skip ->>>>>>> ccbc37b6c016f16fa91ec20432fe9781edadda8d jobs: include: # If the branch is not master it just builds the application From 194181ad7b311e591b053496784bb99c144a34c2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 21:37:56 +0100 Subject: [PATCH 0180/1786] removed not needed sentence into contributing instructions --- CONTRIBUTING.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index decec42c0..2f405e0e3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,8 +5,6 @@ technologies and and their ecosystems and how to make constructive, helpful bug ### How to make a clean pull request -Look for a project's contribution instructions. If there are any, follow them. - - Create a personal fork of the project on Github. - Clone the fork on your local machine. Your remote repo on Github is called `origin`. - Add the original repository as a remote called `upstream`. From 01932244b1b6a080de623806ac94b79cb6e3a4aa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Feb 2019 21:39:22 +0100 Subject: [PATCH 0181/1786] removed variable definition in the wrong place --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b00937b64..bc6c00f79 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,6 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= - - ~/.m2/repository install: skip jobs: include: From 0fc45fa08b7d2b0700e6edf58e8ccfe8c5d61a48 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 06:26:16 +0100 Subject: [PATCH 0182/1786] testing deploy from branch --- .travis.yml | 50 ++++++++++++++++++++--------------------- config/travis/deploy.sh | 15 +++++++------ pom.xml | 2 +- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/.travis.yml b/.travis.yml index bc6c00f79..fad8368e5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -17,31 +17,31 @@ env: install: skip jobs: include: - # If the branch is not master it just builds the application - - stage: "Build" - name: "Build and Test" - if: NOT branch = master - jdk: oraclejdk11 - install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B - # If the branch is master it sends the quality report to SonarCloud - - stage: "Build, Test and Quality Check" - name: "Building, testing and sending a quality report to SonarCloud" - if: branch = master AND type NOT IN (pull_request) - jdk: oraclejdk11 - install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build and Publish" - name: "Building site and publishing on GitHub pages" - if: branch = master AND type NOT IN (pull_request) - jdk: oraclejdk8 - before_deploy: mvn install site:site -DskipTests=true -B - deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true - on: - branch: master +# # If the branch is not master it just builds the application +# - stage: "Build" +# name: "Build and Test" +# if: NOT branch = master +# jdk: oraclejdk11 +# install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B +# # If the branch is master it sends the quality report to SonarCloud +# - stage: "Build, Test and Quality Check" +# name: "Building, testing and sending a quality report to SonarCloud" +# if: branch = master AND type NOT IN (pull_request) +# jdk: oraclejdk11 +# install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build and Publish" +# name: "Building site and publishing on GitHub pages" +# if: branch = master AND type NOT IN (pull_request) +# jdk: oraclejdk8 +# before_deploy: mvn install site:site -DskipTests=true -B +# deploy: +# provider: pages +# local-dir: target/site +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# branch: master - stage: "Release" name: "Releasing artifacts" before_deploy: diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 279ff6ae7..109edbb4b 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -2,15 +2,16 @@ set -e -if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then - if [ ! -z "$TRAVIS_TAG" ]; then +if [ "$TRAVIS_PULL_REQUEST" == 'true' ]; then +# if [ ! -z "$TRAVIS_TAG" ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg + echo ${TRAVIS_TAG} mvn versions:set -D newVersion=${TRAVIS_TAG} mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true - else - echo "Deploying snapshot" - gpg --import config/travis/private-key.gpg - mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true - fi +# else +# echo "Deploying snapshot" +# gpg --import config/travis/private-key.gpg +# mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true +# fi fi \ No newline at end of file diff --git a/pom.xml b/pom.xml index eb12e1a7c..e8c3a39f8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.17-SNAPSHOT + 1.0.4-SNAPSHOT jar 2019 From ed859ef825f1252e99d2c8d10d6f970eb6c4f273 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 06:33:43 +0100 Subject: [PATCH 0183/1786] removing condition preventing the release --- .travis.yml | 14 +++++++------- CHANGELOG.md | 8 +++++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index fad8368e5..bd3f49710 100755 --- a/.travis.yml +++ b/.travis.yml @@ -50,10 +50,10 @@ jobs: - provider: script script: config/travis/deploy.sh skip_cleanup: true - on: - branch: master - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true +# on: +# branch: master +# - provider: script +# script: config/travis/deploy.sh +# skip_cleanup: true +# on: +# tags: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 3beb4facc..6c225bca7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,18 @@ All notable changes to this project will be documented in this file. +### [1.0.17] 2019.02.03 +#### Changed +* Improved package-info comments +#### Added +* Configured Travis in order to automatically release artifacts + ### [1.0.16] 2019.01.26 #### Changed * Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). * Updated `hotels-oss-parent` version to `4.0.0` (was `2.3.5`). #### Added -* Configured Travis in order to automatically build the application, perform a quality check and publish site and artifact. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) +* Configured Travis in order to automatically build the application, perform a quality check and publish site. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) * Added build, test coverage and security badge to readme file. ### [1.0.15] 2019.01.23 From acd744397a1bdc76067f694a2613049158a676c7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 06:36:37 +0100 Subject: [PATCH 0184/1786] restored travis configuration --- .travis.yml | 64 ++++++++++++++++++++--------------------- config/travis/deploy.sh | 14 ++++----- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/.travis.yml b/.travis.yml index bd3f49710..bc6c00f79 100755 --- a/.travis.yml +++ b/.travis.yml @@ -17,31 +17,31 @@ env: install: skip jobs: include: -# # If the branch is not master it just builds the application -# - stage: "Build" -# name: "Build and Test" -# if: NOT branch = master -# jdk: oraclejdk11 -# install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B -# # If the branch is master it sends the quality report to SonarCloud -# - stage: "Build, Test and Quality Check" -# name: "Building, testing and sending a quality report to SonarCloud" -# if: branch = master AND type NOT IN (pull_request) -# jdk: oraclejdk11 -# install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build and Publish" -# name: "Building site and publishing on GitHub pages" -# if: branch = master AND type NOT IN (pull_request) -# jdk: oraclejdk8 -# before_deploy: mvn install site:site -DskipTests=true -B -# deploy: -# provider: pages -# local-dir: target/site -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true -# on: -# branch: master + # If the branch is not master it just builds the application + - stage: "Build" + name: "Build and Test" + if: NOT branch = master + jdk: oraclejdk11 + install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B + # If the branch is master it sends the quality report to SonarCloud + - stage: "Build, Test and Quality Check" + name: "Building, testing and sending a quality report to SonarCloud" + if: branch = master AND type NOT IN (pull_request) + jdk: oraclejdk11 + install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build and Publish" + name: "Building site and publishing on GitHub pages" + if: branch = master AND type NOT IN (pull_request) + jdk: oraclejdk8 + before_deploy: mvn install site:site -DskipTests=true -B + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + branch: master - stage: "Release" name: "Releasing artifacts" before_deploy: @@ -50,10 +50,10 @@ jobs: - provider: script script: config/travis/deploy.sh skip_cleanup: true -# on: -# branch: master -# - provider: script -# script: config/travis/deploy.sh -# skip_cleanup: true -# on: -# tags: true + on: + branch: master + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 109edbb4b..a398cad1a 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -2,16 +2,16 @@ set -e -if [ "$TRAVIS_PULL_REQUEST" == 'true' ]; then -# if [ ! -z "$TRAVIS_TAG" ]; then +if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then + if [ ! -z "$TRAVIS_TAG" ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg echo ${TRAVIS_TAG} mvn versions:set -D newVersion=${TRAVIS_TAG} mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true -# else -# echo "Deploying snapshot" -# gpg --import config/travis/private-key.gpg -# mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true -# fi + else + echo "Deploying snapshot" + gpg --import config/travis/private-key.gpg + mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true + fi fi \ No newline at end of file From 3683f2b618c0b586373887a0435ee7282d14b58a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 06:42:33 +0100 Subject: [PATCH 0185/1786] As the deploy script will not start if a branch is different from master and if it's a pull request, the skip condition has been moved before its call --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index bc6c00f79..fb0dfccef 100755 --- a/.travis.yml +++ b/.travis.yml @@ -44,6 +44,7 @@ jobs: branch: master - stage: "Release" name: "Releasing artifacts" + if: branch = master AND type NOT IN (pull_request) before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d deploy: From 2fb758e447688733fda33fe153d2c8bf20eb27e9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 06:56:24 +0100 Subject: [PATCH 0186/1786] fixed travis config --- config/travis/deploy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index a398cad1a..3cc571201 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -8,10 +8,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then gpg --import config/travis/private-key.gpg echo ${TRAVIS_TAG} mvn versions:set -D newVersion=${TRAVIS_TAG} - mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true + mvn clean deploy --settings config/travis/mvn-settings.xml -Prelease -DskipTests=true else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true + mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true fi fi \ No newline at end of file From d21268a20b2c7ad7125f93c4e23957ca54390977 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 07:07:55 +0100 Subject: [PATCH 0187/1786] temp travis release disable --- .travis.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index fb0dfccef..988f2d10b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -42,19 +42,19 @@ jobs: keep-history: true on: branch: master - - stage: "Release" - name: "Releasing artifacts" - if: branch = master AND type NOT IN (pull_request) - before_deploy: - - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - branch: master - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true +# - stage: "Release" +# name: "Releasing artifacts" +# if: branch = master AND type NOT IN (pull_request) +# before_deploy: +# - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d +# deploy: +# - provider: script +# script: config/travis/deploy.sh +# skip_cleanup: true +# on: +# branch: master +# - provider: script +# script: config/travis/deploy.sh +# skip_cleanup: true +# on: +# tags: true From bdda7d28ed169d432d2bd681fc427d90264dfdb2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 07:08:30 +0100 Subject: [PATCH 0188/1786] fixed project version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e8c3a39f8..eb12e1a7c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.4-SNAPSHOT + 1.0.17-SNAPSHOT jar 2019 From 0db4a0a2f96a6abe5fac13c35e817980c71b4f58 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 07:09:24 +0100 Subject: [PATCH 0189/1786] [maven-release-plugin] prepare release bean-utils-library-1.0.17 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index eb12e1a7c..dbabfa87c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.17-SNAPSHOT + 1.0.17 jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-${project.version} + bean-utils-library-1.0.17 From b176becbeb894ddfd52855119f97a095b4faafcf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 07:21:46 +0100 Subject: [PATCH 0190/1786] preparing release --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index dbabfa87c..eb12e1a7c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.17 + 1.0.17-SNAPSHOT jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.17 + bean-utils-library-${project.version} From 253a1470b23591377930aff42116b89b4a468648 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 07:22:24 +0100 Subject: [PATCH 0191/1786] [maven-release-plugin] prepare release bean-utils-library-1.0.17 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index eb12e1a7c..dbabfa87c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.17-SNAPSHOT + 1.0.17 jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-${project.version} + bean-utils-library-1.0.17 From f118fa4f95b85c51005e100167be4f3114949f54 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 07:22:31 +0100 Subject: [PATCH 0192/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index dbabfa87c..11467d039 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.17 + 1.0.18-SNAPSHOT jar 2019 @@ -51,7 +51,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.0.17 + bean-utils-library-${project.version} From 54781afcdcbdf5ed0c0a1b610dfb47fe209b8c01 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 07:27:20 +0100 Subject: [PATCH 0193/1786] test auto release --- .travis.yml | 64 ++++++++++++++++++++--------------------- config/travis/deploy.sh | 20 ++++++------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.travis.yml b/.travis.yml index fb0dfccef..137f2d3c9 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,43 +18,43 @@ install: skip jobs: include: # If the branch is not master it just builds the application - - stage: "Build" - name: "Build and Test" - if: NOT branch = master - jdk: oraclejdk11 - install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B - # If the branch is master it sends the quality report to SonarCloud - - stage: "Build, Test and Quality Check" - name: "Building, testing and sending a quality report to SonarCloud" - if: branch = master AND type NOT IN (pull_request) - jdk: oraclejdk11 - install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build and Publish" - name: "Building site and publishing on GitHub pages" - if: branch = master AND type NOT IN (pull_request) - jdk: oraclejdk8 - before_deploy: mvn install site:site -DskipTests=true -B - deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true - on: - branch: master +# - stage: "Build" +# name: "Build and Test" +# if: NOT branch = master +# jdk: oraclejdk11 +# install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B +# # If the branch is master it sends the quality report to SonarCloud +# - stage: "Build, Test and Quality Check" +# name: "Building, testing and sending a quality report to SonarCloud" +# if: branch = master AND type NOT IN (pull_request) +# jdk: oraclejdk11 +# install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} +# - stage: "Site Build and Publish" +# name: "Building site and publishing on GitHub pages" +# if: branch = master AND type NOT IN (pull_request) +# jdk: oraclejdk8 +# before_deploy: mvn install site:site -DskipTests=true -B +# deploy: +# provider: pages +# local-dir: target/site +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# branch: master - stage: "Release" name: "Releasing artifacts" - if: branch = master AND type NOT IN (pull_request) +# if: branch = master AND type NOT IN (pull_request) before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d deploy: - provider: script script: config/travis/deploy.sh skip_cleanup: true - on: - branch: master - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true +# on: +# branch: master +# - provider: script +# script: config/travis/deploy.sh +# skip_cleanup: true +# on: +# tags: true diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index a398cad1a..69714c943 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -2,16 +2,16 @@ set -e -if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then - if [ ! -z "$TRAVIS_TAG" ]; then +#if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then +# if [ ! -z "$TRAVIS_TAG" ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - echo ${TRAVIS_TAG} - mvn versions:set -D newVersion=${TRAVIS_TAG} +# echo ${TRAVIS_TAG} +# mvn versions:set -D newVersion=${TRAVIS_TAG} mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true - else - echo "Deploying snapshot" - gpg --import config/travis/private-key.gpg - mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true - fi -fi \ No newline at end of file +# else +# echo "Deploying snapshot" +# gpg --import config/travis/private-key.gpg +# mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true +# fi +#fi \ No newline at end of file From 478c39089b999514ec3ad5092d5333721bbbe324 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 07:35:01 +0100 Subject: [PATCH 0194/1786] trying execute deploy from branch --- .travis.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 137f2d3c9..6effb2f94 100755 --- a/.travis.yml +++ b/.travis.yml @@ -45,12 +45,15 @@ jobs: - stage: "Release" name: "Releasing artifacts" # if: branch = master AND type NOT IN (pull_request) - before_deploy: + before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true + script: + - gpg --import config/travis/private-key.gpg + - mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true +# deploy: +# - provider: script +# script: config/travis/deploy.sh +# skip_cleanup: true # on: # branch: master # - provider: script From e3402517d12ce37fdf0690b06a80ca71efb2e864 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 07:51:39 +0100 Subject: [PATCH 0195/1786] added repos in release build --- .travis.yml | 2 +- pom.xml | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6effb2f94..8b1e03384 100755 --- a/.travis.yml +++ b/.travis.yml @@ -49,7 +49,7 @@ jobs: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d script: - gpg --import config/travis/private-key.gpg - - mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true + - mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true # deploy: # - provider: script # script: config/travis/deploy.sh diff --git a/pom.xml b/pom.xml index e8c3a39f8..1fc7173db 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.4-SNAPSHOT + 1.0.6-SNAPSHOT jar 2019 @@ -125,6 +125,16 @@ release + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + From a5326daf483a250ad8eb0a80939c59703de6f0e3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 08:01:24 +0100 Subject: [PATCH 0196/1786] completed deploy config --- .travis.yml | 75 ++++++++++++++++++++--------------------- config/travis/deploy.sh | 22 ++++++------ pom.xml | 2 +- 3 files changed, 48 insertions(+), 51 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8b1e03384..6ac7781af 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,46 +18,43 @@ install: skip jobs: include: # If the branch is not master it just builds the application -# - stage: "Build" -# name: "Build and Test" -# if: NOT branch = master -# jdk: oraclejdk11 -# install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B -# # If the branch is master it sends the quality report to SonarCloud -# - stage: "Build, Test and Quality Check" -# name: "Building, testing and sending a quality report to SonarCloud" -# if: branch = master AND type NOT IN (pull_request) -# jdk: oraclejdk11 -# install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -# - stage: "Site Build and Publish" -# name: "Building site and publishing on GitHub pages" -# if: branch = master AND type NOT IN (pull_request) -# jdk: oraclejdk8 -# before_deploy: mvn install site:site -DskipTests=true -B -# deploy: -# provider: pages -# local-dir: target/site -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true -# on: -# branch: master + - stage: "Build" + name: "Build and Test" + if: NOT branch = master + jdk: oraclejdk11 + install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B + # If the branch is master it sends the quality report to SonarCloud + - stage: "Build, Test and Quality Check" + name: "Building, testing and sending a quality report to SonarCloud" + if: branch = master AND type NOT IN (pull_request) + jdk: oraclejdk11 + install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build and Publish" + name: "Building site and publishing on GitHub pages" + if: branch = master AND type NOT IN (pull_request) + jdk: oraclejdk8 + before_deploy: mvn install site:site -DskipTests=true -B + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + branch: master - stage: "Release" name: "Releasing artifacts" -# if: branch = master AND type NOT IN (pull_request) + if: branch = master AND type NOT IN (pull_request) before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - script: - - gpg --import config/travis/private-key.gpg - - mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true -# deploy: -# - provider: script -# script: config/travis/deploy.sh -# skip_cleanup: true -# on: -# branch: master -# - provider: script -# script: config/travis/deploy.sh -# skip_cleanup: true -# on: -# tags: true + deploy: + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + branch: master + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 69714c943..7ed2c5142 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -2,16 +2,16 @@ set -e -#if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then -# if [ ! -z "$TRAVIS_TAG" ]; then +if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then + if [ ! -z "$TRAVIS_TAG" ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg -# echo ${TRAVIS_TAG} -# mvn versions:set -D newVersion=${TRAVIS_TAG} - mvn clean deploy --settings config/travis/mvn-settings.xml -P release -DskipTests=true -# else -# echo "Deploying snapshot" -# gpg --import config/travis/private-key.gpg -# mvn clean deploy --settings config/travis/mvn-settings.xml -B -U -P -DskipTests=true -# fi -#fi \ No newline at end of file + echo ${TRAVIS_TAG} + mvn versions:set -D newVersion=${TRAVIS_TAG} + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + else + echo "Deploying snapshot" + gpg --import config/travis/private-key.gpg + mvn deploy --settings config/travis/mvn-settings.xml -B -U -DskipTests=true + fi +fi \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1fc7173db..b187ae371 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.6-SNAPSHOT + 1.0.17-SNAPSHOT jar 2019 From de76a9bbf78ea67a9fb3405305f4ca6a10bbc7b2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Feb 2019 08:15:54 +0100 Subject: [PATCH 0197/1786] added profile --- config/travis/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 7ed2c5142..ef9e1c9d1 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -12,6 +12,6 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true fi fi \ No newline at end of file From dd8a59ad6336b2817c5300c6d6557f38e045e0be Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 06:31:28 +0100 Subject: [PATCH 0198/1786] - Removed spring cache dependency as not needed - Added automatic snapshot release on tagged branches --- .travis.yml | 13 +++++----- config/travis/deploy.sh | 10 ++++---- pom.xml | 57 +++++++++++++++++++---------------------- 3 files changed, 38 insertions(+), 42 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6ac7781af..61f4afc3b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -42,6 +42,12 @@ jobs: keep-history: true on: branch: master + - stage: "Release" + name: "Releasing SNAPSHOT artifact on Maven central" + if: NOT branch = master AND tag IS present + jdk: oraclejdk8 + before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" + install: mvn deploy -B -DskipTests=true - stage: "Release" name: "Releasing artifacts" if: branch = master AND type NOT IN (pull_request) @@ -52,9 +58,4 @@ jobs: script: config/travis/deploy.sh skip_cleanup: true on: - branch: master - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true + tags: true \ No newline at end of file diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index ef9e1c9d1..96eb41a8b 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -9,9 +9,9 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then echo ${TRAVIS_TAG} mvn versions:set -D newVersion=${TRAVIS_TAG} mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true - else - echo "Deploying snapshot" - gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true - fi +# else +# echo "Deploying snapshot" +# gpg --import config/travis/private-key.gpg +# mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true +# fi fi \ No newline at end of file diff --git a/pom.xml b/pom.xml index 32f5dbf2a..110de1df5 100644 --- a/pom.xml +++ b/pom.xml @@ -55,11 +55,6 @@ - - org.springframework.boot - spring-boot-starter-cache - ${spring-boot.version} - org.springframework.boot spring-boot-starter-validation @@ -137,32 +132,6 @@ - - org.apache.maven.plugins - maven-source-plugin - ${maven.source.plugin.version} - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven.javadoc.plugin.version} - - - attach-javadocs - - jar - - - - org.apache.maven.plugins maven-gpg-plugin @@ -211,6 +180,32 @@ + + org.apache.maven.plugins + maven-source-plugin + ${maven.source.plugin.version} + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + + attach-javadocs + + jar + + + + org.apache.maven.plugins maven-checkstyle-plugin From 3331d2bec4b6f28ffdfd8d862be56552e207c69a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 06:39:14 +0100 Subject: [PATCH 0199/1786] added tag version into stage name --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 61f4afc3b..423f73629 100755 --- a/.travis.yml +++ b/.travis.yml @@ -43,14 +43,14 @@ jobs: on: branch: master - stage: "Release" - name: "Releasing SNAPSHOT artifact on Maven central" + name: "Releasing ${TRAVIS_TAG} artifact on Maven central" if: NOT branch = master AND tag IS present jdk: oraclejdk8 before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" install: mvn deploy -B -DskipTests=true - stage: "Release" name: "Releasing artifacts" - if: branch = master AND type NOT IN (pull_request) + if: branch = master AND type NOT IN (pull_request) AND tag IS present before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d deploy: From 1686713de01b53f129ea5d90eec504a1a730fdb1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 06:41:24 +0100 Subject: [PATCH 0200/1786] added snapshot version set --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 423f73629..03cd0a2b5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -43,10 +43,12 @@ jobs: on: branch: master - stage: "Release" - name: "Releasing ${TRAVIS_TAG} artifact on Maven central" + name: "Releasing SNAPSHOT artifact on Maven central" if: NOT branch = master AND tag IS present jdk: oraclejdk8 - before_install: "cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml" + before_install: + - cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml + - mvn versions:set -D newVersion=${TRAVIS_TAG} install: mvn deploy -B -DskipTests=true - stage: "Release" name: "Releasing artifacts" From b128829d82d05e70220875cfc1714232452554dc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 06:49:54 +0100 Subject: [PATCH 0201/1786] fixed 401 unauthorized issue --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 03cd0a2b5..4d64ff2b0 100755 --- a/.travis.yml +++ b/.travis.yml @@ -47,9 +47,9 @@ jobs: if: NOT branch = master AND tag IS present jdk: oraclejdk8 before_install: - - cp config/travis/mvn-settings.xml $HOME/.m2/settings.xml - mvn versions:set -D newVersion=${TRAVIS_TAG} - install: mvn deploy -B -DskipTests=true + - gpg --import config/travis/private-key.gpg + install: mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease - stage: "Release" name: "Releasing artifacts" if: branch = master AND type NOT IN (pull_request) AND tag IS present From 0821515e4e294d49d8cc9bf01c14dff352874a98 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 06:55:59 +0100 Subject: [PATCH 0202/1786] added private key --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4d64ff2b0..70b381af3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -47,6 +47,7 @@ jobs: if: NOT branch = master AND tag IS present jdk: oraclejdk8 before_install: + - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} - gpg --import config/travis/private-key.gpg install: mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease From 2955b431f6f0687ce3966c8f13cdd6a10e532cea Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 10:39:30 +0100 Subject: [PATCH 0203/1786] simplified release step --- .travis.yml | 12 ++---------- config/travis/deploy.sh | 14 ++++++-------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 70b381af3..d816e15b2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -42,20 +42,12 @@ jobs: keep-history: true on: branch: master - - stage: "Release" - name: "Releasing SNAPSHOT artifact on Maven central" - if: NOT branch = master AND tag IS present - jdk: oraclejdk8 - before_install: - - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} - - gpg --import config/travis/private-key.gpg - install: mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease - stage: "Release" name: "Releasing artifacts" - if: branch = master AND type NOT IN (pull_request) AND tag IS present + if: type NOT IN (pull_request) AND tag IS present before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d + - mvn versions:set -D newVersion=${TRAVIS_TAG} deploy: - provider: script script: config/travis/deploy.sh diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 96eb41a8b..d73d5bc16 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -3,15 +3,13 @@ set -e if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then - if [ ! -z "$TRAVIS_TAG" ]; then + if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - echo ${TRAVIS_TAG} - mvn versions:set -D newVersion=${TRAVIS_TAG} mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true -# else -# echo "Deploying snapshot" -# gpg --import config/travis/private-key.gpg -# mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true -# fi + else + echo "Deploying snapshot" + gpg --import config/travis/private-key.gpg + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + fi fi \ No newline at end of file From b4eecbbb2fff34e73d0bc78b9600bb341812aa17 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 10:56:41 +0100 Subject: [PATCH 0204/1786] Improved contributing page --- CONTRIBUTING.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2f405e0e3..eac85d769 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,6 +10,15 @@ technologies and and their ecosystems and how to make constructive, helpful bug - Add the original repository as a remote called `upstream`. - If you created your fork a while ago be sure to pull upstream changes into your local repository. - Create a new branch to work on! Branch from `develop` if it exists, else from `master`. +- The branch name should follow the best practices naming convention: + 1. Use grouping tokens (words) at the beginning of your branch names. + * `feature`: Feature I'm adding or expanding + * `bug`: Bug fix or experiment + * `wip`: Work in progress; stuff I know won't be finished soon + 2. Define and use short lead tokens to differentiate branches in a way that is meaningful to your workflow. + 3. Use slashes to separate parts of your branch names. + 4. Do not use bare numbers as leading parts. + 5. Avoid long descriptive names for long-lived branches. - Implement/fix your feature, comment your code. - Follow the code style of the project, including indentation. - If the project has tests run them! From 7abbc75851bf79da93b9676661223ba66593faa4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 17:34:39 +0100 Subject: [PATCH 0205/1786] - Improved travis configuration - Added dependency to: `slf4j-api` as no longer available from spring. - Removed dependency: `spring-boot-starter-validation` and imported one by one the required validation dependencies - Removed dependency: `spring-boot-starter-cache` and imported one by one the required validation dependencies - Added ValidationUtils class for raising an `IllegalArgumentException` in case any parameter is null --- CHANGELOG.md | 12 ++- pom.xml | 40 ++++++-- .../application/BeanUtilsApplication.java | 37 ------- .../beans/application/package-info.java | 20 ---- .../java/com/hotels/beans/base/Defaults.java | 2 +- .../com/hotels/beans/cache/CacheManager.java | 2 +- .../beans/cache/CacheManagerFactory.java | 2 +- .../beans/transformer/TransformerImpl.java | 2 +- .../com/hotels/beans/utils/ClassUtils.java | 2 +- .../hotels/beans/utils/ReflectionUtils.java | 2 +- .../hotels/beans/utils/ValidationUtils.java | 56 +++++++++++ .../BeanUtilsApplicationTests.java | 39 -------- .../beans/application/package-info.java | 20 ---- .../beans/utils/ValidationUtilsTest.java | 96 +++++++++++++++++++ 14 files changed, 203 insertions(+), 129 deletions(-) delete mode 100644 src/main/java/com/hotels/beans/application/BeanUtilsApplication.java delete mode 100644 src/main/java/com/hotels/beans/application/package-info.java create mode 100644 src/main/java/com/hotels/beans/utils/ValidationUtils.java delete mode 100644 src/test/java/com/hotels/beans/application/BeanUtilsApplicationTests.java delete mode 100644 src/test/java/com/hotels/beans/application/package-info.java create mode 100644 src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c225bca7..3093dc8ed 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,21 @@ All notable changes to this project will be documented in this file. +### [1.0.18] 2019.02.04 +#### Changed +* Improved travis configuration +#### Added +* Added dependency to: `slf4j-api` as no longer available from Spring. +- Added ValidationUtils class for raising an `IllegalArgumentException` in case any parameter is null. +#### Removed +* Removed dependency: `spring-boot-starter-validation` and imported one by one the required validation dependencies +* Removed dependency: `spring-boot-starter-cache` and imported one by one the required validation dependencies + ### [1.0.17] 2019.02.03 #### Changed * Improved package-info comments #### Added -* Configured Travis in order to automatically release artifacts +* Configured Travis in order to automatically release artifacts ### [1.0.16] 2019.01.26 #### Changed diff --git a/pom.xml b/pom.xml index 110de1df5..e04c08eb5 100644 --- a/pom.xml +++ b/pom.xml @@ -25,13 +25,19 @@ 1.8 ${jdk.version} ${jdk.version} + 3.11.0 2.1.2.RELEASE 1.18.4 1.3 3.8.1 0.11 2.8.5 - 3.11.0 + + 2.0.1.Final + 6.0.14.Final + 1.7.25 + 3.0.0 + 2.2.6 0.8.2 0.80 @@ -55,11 +61,6 @@ - - org.springframework.boot - spring-boot-starter-validation - ${spring-boot.version} - org.springframework.boot spring-boot-starter-test @@ -82,6 +83,33 @@ commons-text ${apache.common.version} + + org.slf4j + slf4j-api + ${slf4j-api.version} + + + + javax.validation + validation-api + ${validation-api.version} + + + javax.el + javax.el-api + ${javax.el-api.version} + + + org.hibernate + hibernate-validator + ${hibernate-validator.version} + + + org.glassfish.web + javax.el + ${glassfish.javax.el.version} + + com.shazam shazamcrest diff --git a/src/main/java/com/hotels/beans/application/BeanUtilsApplication.java b/src/main/java/com/hotels/beans/application/BeanUtilsApplication.java deleted file mode 100644 index 1a36880ce..000000000 --- a/src/main/java/com/hotels/beans/application/BeanUtilsApplication.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (C) 2019 Expedia Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.application; - -import static org.springframework.boot.SpringApplication.run; - -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * Spring boot application. - */ -@SpringBootApplication -class BeanUtilsApplication { - - /** - * The main method. - * @param args input arguments - */ - public static void main(final String[] args) { - run(BeanUtilsApplication.class, args); - } - -} diff --git a/src/main/java/com/hotels/beans/application/package-info.java b/src/main/java/com/hotels/beans/application/package-info.java deleted file mode 100644 index 2d2e1befb..000000000 --- a/src/main/java/com/hotels/beans/application/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Spring boot starter package. - */ - -package com.hotels.beans.application; diff --git a/src/main/java/com/hotels/beans/base/Defaults.java b/src/main/java/com/hotels/beans/base/Defaults.java index 34812d51f..fbfc5511e 100644 --- a/src/main/java/com/hotels/beans/base/Defaults.java +++ b/src/main/java/com/hotels/beans/base/Defaults.java @@ -18,7 +18,7 @@ import static java.lang.Boolean.FALSE; -import static org.springframework.util.Assert.notNull; +import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.utils.ClassUtils.isBoolean; import static com.hotels.beans.utils.ClassUtils.isByte; diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/src/main/java/com/hotels/beans/cache/CacheManager.java index 2269041a4..90e0af73b 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -19,7 +19,7 @@ import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; -import static org.springframework.util.Assert.notNull; +import static com.hotels.beans.utils.ValidationUtils.notNull; import static lombok.AccessLevel.PRIVATE; import static lombok.AccessLevel.PROTECTED; diff --git a/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java b/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java index 13bb00243..b12f9d25d 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java +++ b/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java @@ -18,7 +18,7 @@ import static java.util.Objects.isNull; -import static org.springframework.util.Assert.notNull; +import static com.hotels.beans.utils.ValidationUtils.notNull; import static lombok.AccessLevel.PRIVATE; diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index a73e1841b..2ea3aba6c 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -27,8 +27,8 @@ import static org.apache.commons.lang3.StringUtils.SPACE; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static org.springframework.util.Assert.notNull; +import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.constant.ClassType.MIXED; diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index ac0e5a8bb..bafafb390 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -29,8 +29,8 @@ import static java.util.stream.Collectors.toList; import static org.apache.commons.lang3.ArrayUtils.isEmpty; -import static org.springframework.util.Assert.notNull; +import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.constant.ClassType.IMMUTABLE; diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index a421be3ab..cbd2311c0 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -22,8 +22,8 @@ import static java.util.Optional.ofNullable; import static org.apache.commons.text.WordUtils.capitalize; -import static org.springframework.util.Assert.notNull; +import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.constant.MethodPrefix.GET; import static com.hotels.beans.constant.MethodPrefix.IS; import static com.hotels.beans.constant.MethodPrefix.SET; diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java new file mode 100644 index 000000000..dda3e92a2 --- /dev/null +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.utils; + +import static java.util.Objects.isNull; + +import static lombok.AccessLevel.PRIVATE; + +import lombok.NoArgsConstructor; + +/** + * Validation utils for Class objects. + */ +@NoArgsConstructor(access = PRIVATE) +public class ValidationUtils { + /** + * Validate that the specified argument is not {@code null}; + * otherwise throws an {@link IllegalArgumentException} with the specified message. + * @param object the object to check + * @param the object type + * @throws IllegalArgumentException if the object is {@code null} + */ + public static void notNull(final T object) { + if (isNull(object)) { + throw new IllegalArgumentException(); + } + } + + /** + * Validate that the specified argument is not {@code null}; + * otherwise throws an {@link IllegalArgumentException} with the specified message. + * @param object the object to check + * @param message the {@link String#format(String, Object...)} exception message if invalid, not null + * @param the object type + * @throws IllegalArgumentException if the object is {@code null} + */ + public static void notNull(final T object, final String message) { + if (isNull(object)) { + throw new IllegalArgumentException(message); + } + } +} diff --git a/src/test/java/com/hotels/beans/application/BeanUtilsApplicationTests.java b/src/test/java/com/hotels/beans/application/BeanUtilsApplicationTests.java deleted file mode 100644 index 495250f97..000000000 --- a/src/test/java/com/hotels/beans/application/BeanUtilsApplicationTests.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (C) 2019 Expedia Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.application; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -/** - * Integration tests for {@link BeanUtilsApplication}. - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = BeanUtilsApplication.class) -public class BeanUtilsApplicationTests { - - /** - * Checks that the application starts successfully. - */ - @Test - public void contextLoads() { - // checks context load - } - -} diff --git a/src/test/java/com/hotels/beans/application/package-info.java b/src/test/java/com/hotels/beans/application/package-info.java deleted file mode 100644 index 2d2e1befb..000000000 --- a/src/test/java/com/hotels/beans/application/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Spring boot starter package. - */ - -package com.hotels.beans.application; diff --git a/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java new file mode 100644 index 000000000..ad0e90f68 --- /dev/null +++ b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java @@ -0,0 +1,96 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.utils; + +import static org.mockito.MockitoAnnotations.initMocks; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +/** + * Unit test for {@link ValidationUtils}. + */ +public class ValidationUtilsTest { + /** + * Exception message. + */ + private static final String EXCEPTION_MESSAGE = "exception message"; + + /** + * A sample value. + */ + private static final String VALUE = "val"; + + /** + * The class to be tested. + */ + @InjectMocks + private static ValidationUtils underTest; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + } + + /** + * Test that an exception is thrown when the given parameter is null. + */ + @Test(expected = IllegalArgumentException.class) + public void testNotNullRaisesAnExceptionWhenTheGivenObjectIsNull() { + //GIVEN + + //WHEN + underTest.notNull(null, EXCEPTION_MESSAGE); + } + + /** + * Test that no exception are throw when the given parameter is not null. + */ + @Test + public void testThatNoExceptionAreThrownWhenTheGivenObjectIsNotNull() { + //GIVEN + + //WHEN + underTest.notNull(VALUE, EXCEPTION_MESSAGE); + } + + /** + * Test that an exception is thrown when the given parameter is null. + */ + @Test(expected = IllegalArgumentException.class) + public void testNotNullRaisesAnExceptionWhenTheGivenObjectIsNullEvenWithoutACustomMessage() { + //GIVEN + + //WHEN + underTest.notNull(null); + } + + /** + * Test that no exception are throw when the given parameter is not null. + */ + @Test + public void testThatNoExceptionAreThrownWhenTheGivenObjectIsNotNullEvenWithoutACustomMessage() { + //GIVEN + + //WHEN + underTest.notNull(VALUE); + } +} From 2676fa245f838da9ce400efc89e07b4dc0c81bac Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 17:39:42 +0100 Subject: [PATCH 0206/1786] changed version as this change requires a major version increase --- CHANGELOG.md | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3093dc8ed..229a7c1f5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.0.18] 2019.02.04 +### [1.1.0] 2019.02.04 #### Changed * Improved travis configuration #### Added diff --git a/pom.xml b/pom.xml index e04c08eb5..dc7ed28d2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.0.18-SNAPSHOT + 1.1.0-SNAPSHOT jar 2019 From 069c43979760477354bae99d4eba55e400741ebc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 17:44:42 +0100 Subject: [PATCH 0207/1786] [maven-release-plugin] prepare release bean-utils-library-1.1.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index dc7ed28d2..341c22cb9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.0-SNAPSHOT + 1.1.0 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-${project.version} + bean-utils-library-1.1.0 From 0fccdef75ea4675d5c02d48e6c70923e92392649 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 17:44:50 +0100 Subject: [PATCH 0208/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 341c22cb9..10c51d3c4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.0 + 1.1.1-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.1.0 + bean-utils-library-${project.version} From eba5a74f4a04d3abea8985406ff6982ff00590c5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 4 Feb 2019 17:59:35 +0100 Subject: [PATCH 0209/1786] Added travis retry for site build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6ac7781af..566ca2386 100755 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ jobs: name: "Building site and publishing on GitHub pages" if: branch = master AND type NOT IN (pull_request) jdk: oraclejdk8 - before_deploy: mvn install site:site -DskipTests=true -B + before_deploy: travis_retry mvn install site:site -DskipTests=true -B deploy: provider: pages local-dir: target/site From 15a882aa1251a8f37d41350a57013c3eec9813d0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Feb 2019 22:59:45 +0100 Subject: [PATCH 0210/1786] Modified the raised exception message in case the destination constructor arguments is invoked with wrong arguments. This would help the troubleshooting into the hosting project --- .../hotels/beans/constant/Punctuation.java | 14 ++++++- .../beans/transformer/TransformerImpl.java | 26 +++++++++--- .../ImmutableToFooSimpleWrongTypes.java | 32 ++++++++++++++ .../beans/transformer/TransformerTest.java | 42 +++++++++++++++++-- 4 files changed, 105 insertions(+), 9 deletions(-) create mode 100755 src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java diff --git a/src/main/java/com/hotels/beans/constant/Punctuation.java b/src/main/java/com/hotels/beans/constant/Punctuation.java index 07f07f203..998547a7e 100644 --- a/src/main/java/com/hotels/beans/constant/Punctuation.java +++ b/src/main/java/com/hotels/beans/constant/Punctuation.java @@ -34,7 +34,19 @@ public enum Punctuation { /** * Semicolon symbol. ";". */ - SEMICOLON(";"); + SEMICOLON(";"), + /** + * Left parenthesis symbol. "(". + */ + LPAREN("("), + /** + * Right parenthesis symbol. ")". + */ + RPAREN(")"), + /** + * Comma symbol. ",". + */ + COMMA(","); /** * Punctuation character. diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 2ea3aba6c..65f530792 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -28,13 +28,16 @@ import static org.apache.commons.lang3.StringUtils.SPACE; import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.constant.Punctuation.SEMICOLON; +import static com.hotels.beans.constant.Punctuation.COMMA; +import static com.hotels.beans.constant.Punctuation.LPAREN; +import static com.hotels.beans.constant.Punctuation.RPAREN; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.Punctuation.DOT; -import static com.hotels.beans.constant.Punctuation.SEMICOLON; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; @@ -208,10 +211,23 @@ private K injectValues(final T sourceObj, final Class targetClass, fin try { return (K) constructor.newInstance(constructorArgs); } catch (final Exception e) { - throw new InvalidBeanException("Source object: " + sourceObj.getClass().getName() + "; Target class: " + targetClass.getName(), e); + throw new InvalidBeanException("Wrong constructor arguments. Expected: " + constructor + "; Found: " + getFormattedConstructorArgs(targetClass, constructorArgs), e); } } + /** + * Creates a string containing the arguments used to invoke the given class constructor. + * @param targetClass the class containing the constructor + * @param constructorArgs the passed arguments + * @param he target object type + * @return the formatted constructor arguments + */ + private String getFormattedConstructorArgs(final Class targetClass, final Object[] constructorArgs) { + return stream(constructorArgs) + .map(obj -> obj.getClass().getCanonicalName()) + .collect(joining(COMMA.getSymbol(), targetClass.getCanonicalName() + LPAREN.getSymbol(), RPAREN.getSymbol())); + } + /** * Checks if the source class field names can be retrieved from the constructor parameters. * @param constructor the all args constructor diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java new file mode 100755 index 000000000..a9585c0a1 --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object with different field than the source object. + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableToFooSimpleWrongTypes { + private final Integer id; + private final String name; +} diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index fb78d266c..410536ed9 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -16,6 +16,7 @@ package com.hotels.beans.transformer; +import static java.lang.String.format; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; @@ -74,6 +75,7 @@ import com.hotels.beans.sample.immutable.ImmutableToFooNoConstructors; import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; +import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mixed.MixedToFooDiffFields; import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; @@ -115,6 +117,7 @@ public class TransformerTest { private static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); private static FromFoo fromFoo; + private static FromFooSimple fromFooSimple; private static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; private static List fromSubFooList; private static List sourceFooSimpleList; @@ -351,7 +354,7 @@ public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { assertThat(actual, sameBeanAs(fromFoo)); } - /** + /** * Test mutable beans are correctly copied. */ @Test @@ -442,7 +445,7 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTra * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. */ @Test - public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopyedThroughTransformerFunctions() { + public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { //GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); @@ -645,6 +648,30 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro getSourceFieldValueMethod.invoke(underTest, null, null, null, false); } + /** + * Test that a meaningful exception is returned when a constructor is invoked with wrong arguments. + */ + @Test + public void testTransformationReturnsAMeaningfulException() { + //GIVEN + final String expectedExceptionMessageFormat = + "Wrong constructor arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String)"; + String targetClassName = ImmutableToFooSimpleWrongTypes.class.getCanonicalName(); + + //WHEN + Exception raisedException = null; + try { + underTest.transform(fromFooSimple, ImmutableToFooSimpleWrongTypes.class); + } catch (final Exception e) { + raisedException = e; + } + + //THEN + assertNotNull(raisedException); + assertEquals(InvalidBeanException.class, raisedException.getClass()); + assertEquals(format(expectedExceptionMessageFormat, targetClassName, targetClassName), raisedException.getMessage()); + } + /** * Initializes the mocks required for testing method: {@code getDestFieldName}. * @param declaringClassName the declaring class name @@ -682,6 +709,7 @@ private static void initObjects() { fromSubFooList = singletonList(fromSubFoo); sourceFooSimpleList = asList(ITEM_1, ITEM_2); fromFoo = createFromFoo(); + fromFooSimple = createFromFooSimple(); fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); fromFooSubClass = createFromFooSubClass(); fromFooAdvFields = createFromFooAdvFields(); @@ -695,6 +723,15 @@ private static FromFoo createFromFoo() { return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); } + /** + * Creates a {@link FromFooSimple} instance. + * @return the {@link FromFooSimple} instance. + */ + private static FromFooSimple createFromFooSimple() { + return new FromFooSimple(NAME, ID); + } + + /** * Creates a {@link FromFooWithPrimitiveFields} instance. * @return the {@link FromFooWithPrimitiveFields} instance. @@ -718,5 +755,4 @@ private static FromFooSubClass createFromFooSubClass() { private static FromFooAdvFields createFromFooAdvFields() { return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage()); } - } From ea939a4f21a146777027c43d577f638378650416 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 6 Feb 2019 18:02:28 +0100 Subject: [PATCH 0211/1786] roved constructor args exception message --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 3 ++- .../java/com/hotels/beans/transformer/TransformerTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 65f530792..d94c72964 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -211,7 +211,8 @@ private K injectValues(final T sourceObj, final Class targetClass, fin try { return (K) constructor.newInstance(constructorArgs); } catch (final Exception e) { - throw new InvalidBeanException("Wrong constructor arguments. Expected: " + constructor + "; Found: " + getFormattedConstructorArgs(targetClass, constructorArgs), e); + throw new InvalidBeanException("Constructor invoked with arguments. Expected: " + constructor + "; Found: " + + getFormattedConstructorArgs(targetClass, constructorArgs), e); } } diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 410536ed9..a4154883f 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -655,7 +655,7 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro public void testTransformationReturnsAMeaningfulException() { //GIVEN final String expectedExceptionMessageFormat = - "Wrong constructor arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String)"; + "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String)"; String targetClassName = ImmutableToFooSimpleWrongTypes.class.getCanonicalName(); //WHEN From 28fa1cfefe7ccfe1da5ee00485ea702ca35dc60f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 6 Feb 2019 22:41:07 +0100 Subject: [PATCH 0212/1786] - Removed slf4j as not used - added maven shade plugin - Added more details into the exception message raised when a constructor invokation fails --- .travis.yml | 5 +- pom.xml | 49 +++++++++++++------ src/main/java/com/hotels/beans/BeanUtils.java | 3 -- .../beans/transformer/TransformerImpl.java | 7 ++- .../beans/transformer/TransformerTest.java | 12 +++-- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/.travis.yml b/.travis.yml index 81e418b53..5380909c6 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,8 @@ cache: - "~/.m2/repository" env: global: - # sonatype jira username: OSSRH_USERNAME + # sonatype jira info - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= - # sonatype jira password: OSSRH_PASSWORD - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= # GPG_KEYNAME - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= @@ -33,6 +32,7 @@ jobs: name: "Building site and publishing on GitHub pages" if: branch = master AND type NOT IN (pull_request) jdk: oraclejdk8 + install: skip before_deploy: travis_retry mvn install site:site -DskipTests=true -B deploy: provider: pages @@ -45,6 +45,7 @@ jobs: - stage: "Release" name: "Releasing artifacts" if: type NOT IN (pull_request) AND tag IS present + install: skip before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} diff --git a/pom.xml b/pom.xml index 10c51d3c4..8549ad443 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,7 @@ ${jdk.version} ${jdk.version} 3.11.0 + 3.2.1 2.1.2.RELEASE 1.18.4 1.3 @@ -61,12 +62,6 @@ - - org.springframework.boot - spring-boot-starter-test - ${spring-boot.version} - test - org.projectlombok lombok @@ -83,11 +78,6 @@ commons-text ${apache.common.version} - - org.slf4j - slf4j-api - ${slf4j-api.version} - javax.validation @@ -99,17 +89,29 @@ javax.el-api ${javax.el-api.version} + + org.glassfish.web + javax.el + ${glassfish.javax.el.version} + org.hibernate hibernate-validator ${hibernate-validator.version} + - org.glassfish.web - javax.el - ${glassfish.javax.el.version} + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + + + org.slf4j + slf4j-api + ${slf4j-api.version} + test - com.shazam shazamcrest @@ -234,6 +236,23 @@ + + org.apache.maven.plugins + maven-shade-plugin + ${maven.shade.plugin.version} + + true + true + + + + package + + shade + + + + org.apache.maven.plugins maven-checkstyle-plugin diff --git a/src/main/java/com/hotels/beans/BeanUtils.java b/src/main/java/com/hotels/beans/BeanUtils.java index d673d9d50..ef012cec4 100644 --- a/src/main/java/com/hotels/beans/BeanUtils.java +++ b/src/main/java/com/hotels/beans/BeanUtils.java @@ -19,12 +19,9 @@ import com.hotels.beans.transformer.TransformerImpl; import com.hotels.beans.transformer.Transformer; -import lombok.extern.slf4j.Slf4j; - /** * Set of Bean utilities. */ -@Slf4j public class BeanUtils { /** diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index d94c72964..ae72f45cc 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -60,13 +60,10 @@ import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; -import lombok.extern.slf4j.Slf4j; - /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * The implementations are provided by BeanUtils. */ -@Slf4j public class TransformerImpl implements Transformer { /** * Reflection utils class {@link ReflectionUtils}. @@ -212,7 +209,9 @@ private K injectValues(final T sourceObj, final Class targetClass, fin return (K) constructor.newInstance(constructorArgs); } catch (final Exception e) { throw new InvalidBeanException("Constructor invoked with arguments. Expected: " + constructor + "; Found: " - + getFormattedConstructorArgs(targetClass, constructorArgs), e); + + getFormattedConstructorArgs(targetClass, constructorArgs) + + ". Double check that each " + targetClass.getSimpleName() + "'s field have the same type and name than the source object: " + + sourceObj.getClass().getCanonicalName() + " otherwise specify a transformer configuration.", e); } } diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index a4154883f..9fdfa5e7c 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -654,14 +654,18 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro @Test public void testTransformationReturnsAMeaningfulException() { //GIVEN + Class targetClass = ImmutableToFooSimpleWrongTypes.class; final String expectedExceptionMessageFormat = - "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String)"; - String targetClassName = ImmutableToFooSimpleWrongTypes.class.getCanonicalName(); + "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " + + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration."; + String targetClassName = targetClass.getCanonicalName(); + String expectedExceptionMessage = + format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getCanonicalName()); //WHEN Exception raisedException = null; try { - underTest.transform(fromFooSimple, ImmutableToFooSimpleWrongTypes.class); + underTest.transform(fromFooSimple, targetClass); } catch (final Exception e) { raisedException = e; } @@ -669,7 +673,7 @@ public void testTransformationReturnsAMeaningfulException() { //THEN assertNotNull(raisedException); assertEquals(InvalidBeanException.class, raisedException.getClass()); - assertEquals(format(expectedExceptionMessageFormat, targetClassName, targetClassName), raisedException.getMessage()); + assertEquals(expectedExceptionMessage, raisedException.getMessage()); } /** From 8423a7875d9373ae3784d9d8d3df4bb19459f1ee Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 7 Feb 2019 23:01:47 +0100 Subject: [PATCH 0213/1786] Fixed repo url on github site --- docs/site/site.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/site/site.xml b/docs/site/site.xml index e7201a4ae..f39f8228a 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -12,9 +12,9 @@ false true - BULL + HotelsDotCom/bull right - gray + #cf2d35 From 0283c9cb38a9f90a312902b7077bd31d439693f6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 7 Feb 2019 23:09:59 +0100 Subject: [PATCH 0214/1786] changed tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8549ad443..4d97bb144 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-${project.version} + HEAD From fb1563ac3662fd371c831228dec5065a4c774674 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 8 Feb 2019 07:30:23 +0100 Subject: [PATCH 0215/1786] Modified travis configuration in order to create site and scan with sonar cloud only if a tag is available --- .travis.yml | 10 +++++++--- pom.xml | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5380909c6..ea489f75b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -25,15 +25,19 @@ jobs: # If the branch is master it sends the quality report to SonarCloud - stage: "Build, Test and Quality Check" name: "Building, testing and sending a quality report to SonarCloud" - if: branch = master AND type NOT IN (pull_request) + if: branch = master AND type NOT IN (pull_request) AND tag IS present jdk: oraclejdk11 + before_install: + - mvn versions:set -D newVersion=${TRAVIS_TAG} install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" - if: branch = master AND type NOT IN (pull_request) + if: branch = master AND type NOT IN (pull_request) AND tag IS present jdk: oraclejdk8 install: skip - before_deploy: travis_retry mvn install site:site -DskipTests=true -B + before_deploy: + - mvn versions:set -D newVersion=${TRAVIS_TAG} + - travis_retry mvn install site:site -DskipTests=true -B deploy: provider: pages local-dir: target/site diff --git a/pom.xml b/pom.xml index 4d97bb144..a168fae09 100644 --- a/pom.xml +++ b/pom.xml @@ -243,6 +243,35 @@ true true + true + shadow + + + org.hibernate.validator:hibernate:validator:jar: + javax.el:javax.el-api:jar: + javax.validation:validation-api:jar: + org.jboss.logging:jboss-logging:jar: + com.fasterxml:classmate:jar: + + + + + org.hibernate + shaded.org.hibernate + + + javax.validation + shaded.javax.validation + + + org.jboss.logging + shaded.org.jboss.logging + + + com.fasterxml + shaded.com.fasterxml + + From aed547cab1a2235b0658e9a028ac30cf511d7d1f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 8 Feb 2019 15:31:20 +0100 Subject: [PATCH 0216/1786] Improved exception message in case the field has different types --- .../com/hotels/beans/utils/ReflectionUtils.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index cbd2311c0..ea9395790 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -16,19 +16,17 @@ package com.hotels.beans.utils; +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.constant.MethodPrefix.GET; +import static com.hotels.beans.constant.MethodPrefix.IS; +import static com.hotels.beans.constant.MethodPrefix.SET; +import static com.hotels.beans.utils.ValidationUtils.notNull; import static java.lang.reflect.Modifier.isPublic; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; - import static org.apache.commons.text.WordUtils.capitalize; -import static com.hotels.beans.utils.ValidationUtils.notNull; -import static com.hotels.beans.constant.MethodPrefix.GET; -import static com.hotels.beans.constant.MethodPrefix.IS; -import static com.hotels.beans.constant.MethodPrefix.SET; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; - import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -42,6 +40,7 @@ import java.util.concurrent.atomic.AtomicReference; import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.error.MissingFieldException; import com.hotels.beans.error.MissingMethodException; import com.hotels.beans.model.EmptyValue; @@ -241,6 +240,8 @@ private Object getFieldValue(final Object target, final String fieldName) { public void setFieldValue(final Object target, final Field field, final Object fieldValue) { try { setFieldValueWithoutSetterMethod(target, field, fieldValue); + } catch (final IllegalArgumentException e) { + throw e; } catch (final Exception e) { invokeMethod(getSetterMethodForField(target.getClass(), field.getName(), field.getType()), target, fieldValue); } From 783b9d106c161e70f9b47e0a82e2b5d10fead60a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 8 Feb 2019 18:13:21 +0100 Subject: [PATCH 0217/1786] - Improved readme file - Updated changelog - Added maven shade plugin --- CHANGELOG.md | 7 +++ README.md | 131 ++++++++++++++++++++++++++------------------------- pom.xml | 29 ------------ 3 files changed, 73 insertions(+), 94 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 229a7c1f5..4506b9abd 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +### [1.1.1] 2019.02.08 +#### Changed +* Improved exception messaging in order to simplify the troubleshooting process +* Improved readme file +#### Added +* Added `maven-shade-plugin` in order to package dependencies + ### [1.1.0] 2019.02.04 #### Changed * Improved travis configuration diff --git a/README.md b/README.md index 42ba83401..a597ab204 100644 --- a/README.md +++ b/README.md @@ -60,9 +60,6 @@ mvn clean install -P relaxed ### Simple case: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter -@Setter @Setter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -70,8 +67,12 @@ public class FromBean { public class ToBean private List list; private final List list; private final FromSubBean subObject; private final List nestedObjectList; private ImmutableToSubFoo nestedObject; -} - } + + // constructors... // constructors... + + // getters and setters... // getters and setters... + +} } ~~~ And one line code as: ~~~Java @@ -89,23 +90,12 @@ public class FromBean { public class ToBean private final List subBeanList; private final List subBeanList; private final List list; private final List list; private final FromSubBean subObject; private final ToSubBean subObject; - - // getters and setters... - public ToBean(final String differentName, - final int id, -} final List subBeanList, - final List list, - final ToSubBean subObject) { - this.differentName = differentName; - this.id = id; - this.subBeanList = subBeanList; - this.list = list; - this.subObject = subObject; - } - - // getters and setters... - - } + + // all args constructor // all args constructor + + // getters... // getters... + +} } ~~~ And one line code as: @@ -123,11 +113,12 @@ public class FromBean { public class ToBean private final List subBeanList; private final List subBeanList; private final List list; private final List list; private final FromSubBean subObject; private final ToSubBean subObject; - - // getters and setters... + + // all args constructor + // getters... public ToBean(@ConstructorArg("name") final String differentName, - @ConstructorArg("id") final int id, -} @ConstructorArg("subBeanList") final List subBeanList, +} @ConstructorArg("id") final int id, + @ConstructorArg("subBeanList") final List subBeanList, @ConstructorArg(fieldName ="list") final List list, @ConstructorArg("subObject") final ToSubBean subObject) { this.differentName = differentName; @@ -137,7 +128,7 @@ public class FromBean { public class ToBean this.subObject = subObject; } - // getters and setters... + // getters... } ~~~ @@ -149,9 +140,6 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); ### Different field names and types applying transformation through lambda function: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter -@Setter @Setter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger identifier; @@ -160,8 +148,12 @@ public class FromBean { public class ToBean private final FromSubBean subObject; private final List nestedObjectList; private final String locale; private final Locale locale; private ImmutableToSubFoo nestedObject; -} - } + + // constructors... // constructors... + + // getters and setters... // getters and setters... + +} } ~~~ ~~~Java @@ -185,7 +177,12 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final String name; private String notExistingField; // this will be null and no exceptions will be raised -} } + + // constructors... // constructors... + + // getters... // getters and setters... + +} } ~~~ And one line code as: ~~~Java @@ -205,7 +202,11 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final String name; private String notExistingField; // this will have value: sampleVal -} } + + // all args constructor // constructors... + + // getters... // getters and setters... +} } ~~~ And one line code as: ~~~Java @@ -217,6 +218,37 @@ ToBean toBean = beanUtils.getTransformer() More sample beans can be found in the test package: `com.hotels.beans.sample` +## Third party library comparison + +Following a comparison between the BULL functionalities and the following Third-Party libraries: + +* [Apache BeanUtils](http://commons.apache.org/proper/commons-beanutils/) +* [Jackson Data Bind](https://github.com/FasterXML/jackson-databind) +* [Dozer](http://dozer.sourceforge.net/) + +| | **BULL** | **Apache Bean Utils** | **Jackson** | **Dozer** | +| :----------- | :-----------: | :-----------: | :-----------: | :-----------: | +| Mutable bean copy | X | X | X | X+ | +| Mutable bean with nested objects | X | - | X | X+ | +| Mutable bean extending classes | X | - | X | X+ | +| Immutable bean copy | X | - | - | X* | +| Mixed bean copy | X | - | - | X+ | +| Copy of beans without getter and setter methods defined | X | - | - | - | +| Mutable Bean with different field's name | X | - | - | X+ | +| Mixed with different field's type | X | - | - | X+ | +| Immutable with different field's type | X | - | - | X+ | +| Mutable Bean containing collection type fields containing complex objects | X | - | X | X | +| Mixed Bean containing collection type fields containing complex objects | X | - | - | X+ | +| Immutable Bean containing collection type fields containing complex objects | X | - | - | X+ | +| Mutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | X | X | +| Mixed Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | +| Immutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | +| Annotation field validation | X | - | X | - | + +_[*] Immutable types are not supported by Dozer. When a type doesn't have a no-arg constructor and all fields are final, Dozer can't perform the mapping. + Workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ +_[+] Requires a custom configuration_ + ## Performance Let's have a look to the performance library performance. The test has been executed on the following objects: @@ -256,37 +288,6 @@ Following the obtained results: * the class's fields that have to be copied must not be static * the class must not contain builders -## Third party library comparison - -Following a comparison between the BULL functionalities and the following Third-Party libraries: - -* [Apache BeanUtils](http://commons.apache.org/proper/commons-beanutils/) -* [Jackson Data Bind](https://github.com/FasterXML/jackson-databind) -* [Dozer](http://dozer.sourceforge.net/) - -| | **BULL** | **Apache Bean Utils** | **Jackson** | **Dozer** | -| :----------- | :-----------: | :-----------: | :-----------: | :-----------: | -| Mutable bean copy | X | X | X | X+ | -| Mutable bean with nested objects | X | - | X | X+ | -| Mutable bean extending classes | X | - | X | X+ | -| Immutable bean copy | X | - | - | X* | -| Mixed bean copy | X | - | - | X+ | -| Copy of beans without getter and setter methods defined | X | - | - | - | -| Mutable Bean with different field's name | X | - | - | X+ | -| Mixed with different field's type | X | - | - | X+ | -| Immutable with different field's type | X | - | - | X+ | -| Mutable Bean containing collection type fields containing complex objects | X | - | X | X | -| Mixed Bean containing collection type fields containing complex objects | X | - | - | X+ | -| Immutable Bean containing collection type fields containing complex objects | X | - | - | X+ | -| Mutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | X | X | -| Mixed Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | -| Immutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | -| Annotation field validation | X | - | X | - | - -_[*] Immutable types are not supported by Dozer. When a type doesn't have a no-arg constructor and all fields are final, Dozer can't perform the mapping. - Workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ -_[+] Requires a custom configuration_ - ## Documentation A detailed project documentation is available [here](https://hotelsdotcom.github.io/bull). diff --git a/pom.xml b/pom.xml index a168fae09..4d97bb144 100644 --- a/pom.xml +++ b/pom.xml @@ -243,35 +243,6 @@ true true - true - shadow - - - org.hibernate.validator:hibernate:validator:jar: - javax.el:javax.el-api:jar: - javax.validation:validation-api:jar: - org.jboss.logging:jboss-logging:jar: - com.fasterxml:classmate:jar: - - - - - org.hibernate - shaded.org.hibernate - - - javax.validation - shaded.javax.validation - - - org.jboss.logging - shaded.org.jboss.logging - - - com.fasterxml - shaded.com.fasterxml - - From 4e14d0d9b3a5eb39d0769a8c61f7d20453b366f3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 8 Feb 2019 18:17:07 +0100 Subject: [PATCH 0218/1786] fixed checkstyle issues --- CHANGELOG.md | 2 +- .../com/hotels/beans/utils/ReflectionUtils.java | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4506b9abd..1502a786e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.1.1] 2019.02.08 +### [1.1.1] TBD #### Changed * Improved exception messaging in order to simplify the troubleshooting process * Improved readme file diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index ea9395790..290ee9c5c 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -16,17 +16,19 @@ package com.hotels.beans.utils; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.constant.MethodPrefix.GET; -import static com.hotels.beans.constant.MethodPrefix.IS; -import static com.hotels.beans.constant.MethodPrefix.SET; -import static com.hotels.beans.utils.ValidationUtils.notNull; import static java.lang.reflect.Modifier.isPublic; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; + import static org.apache.commons.text.WordUtils.capitalize; +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.constant.MethodPrefix.GET; +import static com.hotels.beans.constant.MethodPrefix.IS; +import static com.hotels.beans.constant.MethodPrefix.SET; +import static com.hotels.beans.utils.ValidationUtils.notNull; + import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -40,7 +42,6 @@ import java.util.concurrent.atomic.AtomicReference; import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.error.MissingFieldException; import com.hotels.beans.error.MissingMethodException; import com.hotels.beans.model.EmptyValue; From 97bd11f22ef5124145db2b8da20fd1a0b1ec4afa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 9 Feb 2019 15:25:19 +0100 Subject: [PATCH 0219/1786] Removed maven-shade plugin --- pom.xml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/pom.xml b/pom.xml index 4d97bb144..89a0e2c5d 100644 --- a/pom.xml +++ b/pom.xml @@ -236,23 +236,6 @@ - - org.apache.maven.plugins - maven-shade-plugin - ${maven.shade.plugin.version} - - true - true - - - - package - - shade - - - - org.apache.maven.plugins maven-checkstyle-plugin From 98c0bcb7febc9a0abb17849b5e8fd097699c878d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 9 Feb 2019 15:29:55 +0100 Subject: [PATCH 0220/1786] Updated changelog --- .travis.yml | 2 +- CHANGELOG.md | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ea489f75b..1112a4de9 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ cache: - "~/.m2/repository" env: global: - # sonatype jira info + # Sonatype jira info - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= # GPG_KEYNAME diff --git a/CHANGELOG.md b/CHANGELOG.md index 1502a786e..b0fe62a54 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,10 @@ All notable changes to this project will be documented in this file. -### [1.1.1] TBD +### [1.1.1] 2019.02.09 #### Changed * Improved exception messaging in order to simplify the troubleshooting process * Improved readme file -#### Added -* Added `maven-shade-plugin` in order to package dependencies ### [1.1.0] 2019.02.04 #### Changed From 99f1af720c85c350acc43c810fef38a97d9b01d2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 9 Feb 2019 15:30:51 +0100 Subject: [PATCH 0221/1786] removed not needed lib version --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 89a0e2c5d..383a06aad 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,6 @@ ${jdk.version} ${jdk.version} 3.11.0 - 3.2.1 2.1.2.RELEASE 1.18.4 1.3 From 06fc1a0628eef39642233e987abb8abdfa093ba4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 9 Feb 2019 15:51:06 +0100 Subject: [PATCH 0222/1786] Fixed travis configuration --- .travis.yml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1112a4de9..c3692659a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -23,20 +23,16 @@ jobs: jdk: oraclejdk11 install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B # If the branch is master it sends the quality report to SonarCloud - - stage: "Build, Test and Quality Check" - name: "Building, testing and sending a quality report to SonarCloud" - if: branch = master AND type NOT IN (pull_request) AND tag IS present + - stage: "Quality Check" + name: "Performing quality check and sending a quality report to SonarCloud" + if: branch = master AND type NOT IN (pull_request) jdk: oraclejdk11 - before_install: - - mvn versions:set -D newVersion=${TRAVIS_TAG} install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" - if: branch = master AND type NOT IN (pull_request) AND tag IS present + if: branch = master AND type NOT IN (pull_request) jdk: oraclejdk8 - install: skip before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} - travis_retry mvn install site:site -DskipTests=true -B deploy: provider: pages From d1e87b6f6e212846ccab4584c7a5d5a034a7edf7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 9 Feb 2019 15:53:02 +0100 Subject: [PATCH 0223/1786] removed wrong condition --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c3692659a..151835158 100755 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - if: NOT branch = master + if: branch = master jdk: oraclejdk11 install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B # If the branch is master it sends the quality report to SonarCloud From 659bb6a75d5a8076f86e5a0f1b68015f3dd455bd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 9 Feb 2019 16:03:39 +0100 Subject: [PATCH 0224/1786] [maven-release-plugin] prepare release 1.1.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 383a06aad..09dbee3df 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.1-SNAPSHOT + 1.1.1 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.1 From a9d6f2bad285f9ded138682f3a03387ea37713df Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 9 Feb 2019 16:03:46 +0100 Subject: [PATCH 0225/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 09dbee3df..f8a094a3b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.1 + 1.1.2-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.1 + HEAD From 24152e94ab2b1f87ee90a5ca2b0ca95740dfbe1f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 9 Feb 2019 16:18:45 +0100 Subject: [PATCH 0226/1786] removed no longer existing link from menu --- docs/site/site.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/site/site.xml b/docs/site/site.xml index f39f8228a..73278ae57 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -27,7 +27,6 @@

  • - From 50366927a1a053aa65daf36175cab933d76c01f6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 9 Feb 2019 18:55:38 +0100 Subject: [PATCH 0227/1786] Moved distribution management outside from profile --- pom.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index f8a094a3b..5e6b45a80 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,16 @@ https://github.com/HotelsDotCom/bull HEAD + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + @@ -149,16 +159,6 @@ release - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - From 977d4f7f3f29617049a32ddfff5492d9dbfb0385 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Feb 2019 12:08:10 +0100 Subject: [PATCH 0228/1786] - Added possibility to specify composite field name mapping - Implemented new test for the above feature - Modified hibernate validator dependencies as it has been moved --- CHANGELOG.md | 4 ++ pom.xml | 2 +- .../beans/transformer/TransformerImpl.java | 8 +++- .../hotels/beans/utils/ReflectionUtils.java | 18 ++++++--- .../sample/immutable/ImmutableFlatToFoo.java | 39 +++++++++++++++++++ .../beans/transformer/TransformerTest.java | 22 ++++++++++- 6 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java diff --git a/CHANGELOG.md b/CHANGELOG.md index b0fe62a54..f4945e0a2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.1.2] TBD +#### Added +* Added possiblity to define fields name mappings ... + ### [1.1.1] 2019.02.09 #### Changed * Improved exception messaging in order to simplify the troubleshooting process diff --git a/pom.xml b/pom.xml index f8a094a3b..dff49b2e5 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ ${glassfish.javax.el.version} - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index ae72f45cc..d2d669b68 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -44,8 +44,10 @@ import java.lang.reflect.Field; import java.lang.reflect.Parameter; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import javax.validation.ConstraintViolation; import javax.validation.Validator; @@ -100,8 +102,9 @@ public TransformerImpl() { */ @Override public final Transformer withFieldMapping(final FieldMapping... fieldMapping) { + final Map fieldsNameMapping = transformerSettings.getFieldsNameMapping(); stream(fieldMapping) - .forEach(mapping -> transformerSettings.getFieldsNameMapping().put(mapping.getDestFieldName(), mapping.getSourceFieldName())); + .forEach(mapping -> fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName())); return this; } @@ -128,8 +131,9 @@ public final void resetFieldsMapping() { @Override @SuppressWarnings("unchecked") public final Transformer withFieldTransformer(final FieldTransformer... fieldTransformer) { + Map> fieldsTransformers = transformerSettings.getFieldsTransformers(); stream(fieldTransformer) - .forEach(transformer -> transformerSettings.getFieldsTransformers().put(transformer.getDestFieldName(), transformer.getTransformerFunction())); + .forEach(transformer -> fieldsTransformers.put(transformer.getDestFieldName(), transformer.getTransformerFunction())); return this; } diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 290ee9c5c..c4bef7275 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -63,6 +63,11 @@ public final class ReflectionUtils { */ private static final String SETTER_METHOD_NAME_REGEX = "^set[A-Z].*"; + /** + * Regex for identify dots into a string. + */ + private static final String DOT_SPLIT_REGEX = "\\."; + /** * CacheManager class {@link CacheManager}. */ @@ -130,12 +135,13 @@ public Object getFieldValue(final Object target, final Field field) { * @return the field value */ public Object getFieldValue(final Object target, final String fieldName, final Class fieldType) { - Object fieldValue; - Object realTarget = getRealTarget(target); - try { - fieldValue = getFieldValue(realTarget, fieldName); - } catch (final Exception e) { - fieldValue = invokeMethod(getGetterMethod(realTarget.getClass(), fieldName, fieldType), realTarget); + Object fieldValue = getRealTarget(target); + for (String currFieldName : fieldName.split(DOT_SPLIT_REGEX)) { + try { + fieldValue = getFieldValue(fieldValue, currFieldName); + } catch (final Exception e) { + fieldValue = invokeMethod(getGetterMethod(fieldValue.getClass(), currFieldName, fieldType), fieldValue); + } } return fieldValue; } diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java new file mode 100644 index 000000000..3e0e87a8d --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object containing properties available in the source object inside other objects. + *

    + * e.g. phoneNumbers field is available inside FromFoo.nestedObject.phoneNumbers + *

    + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableFlatToFoo { + private final String name; + private final BigInteger id; + private final int[] phoneNumbers; + +} diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 9fdfa5e7c..aa895566a 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -66,6 +66,7 @@ import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.FromFooWithPrimitiveFields; import com.hotels.beans.sample.FromSubFoo; +import com.hotels.beans.sample.immutable.ImmutableFlatToFoo; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; @@ -74,8 +75,8 @@ import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooNoConstructors; import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; -import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; +import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mixed.MixedToFooDiffFields; import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; @@ -252,6 +253,25 @@ public void testBeanWithoutCustomAnnotationIsCorrectlyCopied() { assertThat(actual, sameBeanAs(fromFoo)); } + /** + * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly + * valorized. + */ + @Test + public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected() { + //GIVEN + FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); + + //WHEN + ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFoo, ImmutableFlatToFoo.class); + + //THEN + assertEquals(fromFoo.getName(), actual.getName()); + assertEquals(fromFoo.getId(), actual.getId()); + assertEquals(fromFoo.getNestedObject().getPhoneNumbers(), actual.getPhoneNumbers()); + underTest.resetFieldsMapping(); + } + /** * Test that immutable beans without custom field mapping. */ From 0ec79ac9a11b4b7be2df6de234b045d55618d26f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Feb 2019 12:16:02 +0100 Subject: [PATCH 0229/1786] Fixed travis configuration as the build was not starting on branches --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 151835158..d894aba4a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -19,12 +19,12 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - if: branch = master + if: NOT branch = master jdk: oraclejdk11 install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B # If the branch is master it sends the quality report to SonarCloud - - stage: "Quality Check" - name: "Performing quality check and sending a quality report to SonarCloud" + - stage: "Build and Quality Check" + name: "Building, testing and performing quality check" if: branch = master AND type NOT IN (pull_request) jdk: oraclejdk11 install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} From 13ee2a15531b5b970fcba5323d01a4dcb85faeb1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Feb 2019 12:22:05 +0100 Subject: [PATCH 0230/1786] Added skip tests as travis executes mvn test automatically --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d894aba4a..cb6c90ae7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ jobs: name: "Build and Test" if: NOT branch = master jdk: oraclejdk11 - install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B + install: travis_retry mvn clean install -DskipTests -Dmaven.javadoc.skip=true -B # If the branch is master it sends the quality report to SonarCloud - stage: "Build and Quality Check" name: "Building, testing and performing quality check" From 45555e68bb30f7d3995a80ce55ae1e913b7fc59d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Feb 2019 17:53:58 +0100 Subject: [PATCH 0231/1786] - Added null check to the new feature implemented - Implemented samples and documentation --- CHANGELOG.md | 3 +- README.md | 42 ++++++++++++++++++- config/checkstyle/suppression.xml | 13 +++--- docs/site/markdown/transformer/samples.md | 38 +++++++++++++++++ .../beans/transformer/TransformerImpl.java | 10 +++-- .../hotels/beans/utils/ReflectionUtils.java | 1 + .../beans/transformer/TransformerTest.java | 28 +++++++++++-- 7 files changed, 120 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4945e0a2..95259e4b9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ All notable changes to this project will be documented in this file. ### [1.1.2] TBD #### Added -* Added possiblity to define fields name mappings ... +* Made the field name mapping more flexible adding the possibility to map destination object field with field contained into nested objects +* Added samples for the above functionality ### [1.1.1] 2019.02.09 #### Changed diff --git a/README.md b/README.md index a597ab204..748fcd8f0 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,44 @@ And one line code as: beanUtils.getTransformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); ~~~ +### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: + +Assuming that the object `FromSubBean` is declared as follow: +~~~Java +public class FromSubBean { + + private String serialNumber; + private Date creationDate; + + // getters and setters... + +} +~~~ +and our source object and destination object are described as follow: +~~~Java +public class FromBean { public class ToBean { + + private final int id; private final int id; + private final String name; private final String name; + private final FromSubBean subObject; private final String serialNumber; + private final Date creationDate; + + // all args constructor // all args constructor + + // getters... // getters... + +} } +~~~ +the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: +~~~Java +FieldMapping serialNumberMapping = new FieldMapping("subObject.serialNumber", "serialNumber"); +FieldMapping creationDateMapping = new FieldMapping("subObject.creationDate", "creationDate"); + +beanUtils.getTransformer() + .withFieldMapping(serialNumberMapping, creationDateMapping) + .transform(fromBean, ToBean.class); +~~~ + ### Different field names defining constructor args: ~~~Java @@ -117,8 +155,8 @@ public class FromBean { public class ToBean // all args constructor // getters... public ToBean(@ConstructorArg("name") final String differentName, -} @ConstructorArg("id") final int id, - @ConstructorArg("subBeanList") final List subBeanList, +} @ConstructorArg("id") final int id, + @ConstructorArg("subBeanList") final List subBeanList, @ConstructorArg(fieldName ="list") final List list, @ConstructorArg("subObject") final ToSubBean subObject) { this.differentName = differentName; diff --git a/config/checkstyle/suppression.xml b/config/checkstyle/suppression.xml index 3799852df..9ff874c91 100644 --- a/config/checkstyle/suppression.xml +++ b/config/checkstyle/suppression.xml @@ -5,20 +5,23 @@ "https://checkstyle.org/dtds/suppressions_1_2.dtd"> - + - + - + + + + - + - + diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index c8b088a46..cbe5e0b7d 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -60,6 +60,44 @@ And one line code as: beanUtils.getTransformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); ~~~ +### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: + +Assuming that the object `FromSubBean` is declared as follow: +~~~Java +public class FromSubBean { + + private String serialNumber; + private Date creationDate; + + // getters and setters... + +} +~~~ +and our source object and destination object are described as follow: +~~~Java +public class FromBean { public class ToBean { + + private final int id; private final int id; + private final String name; private final String name; + private final FromSubBean subObject; private final String serialNumber; + private final Date creationDate; + + // all args constructor // all args constructor + + // getters... // getters... + +} } +~~~ +the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: +~~~Java +FieldMapping serialNumberMapping = new FieldMapping("subObject.serialNumber", "serialNumber"); +FieldMapping creationDateMapping = new FieldMapping("subObject.creationDate", "creationDate"); + +beanUtils.getTransformer() + .withFieldMapping(serialNumberMapping, creationDateMapping) + .transform(fromBean, ToBean.class); +~~~ + ### Different field names defining constructor args: ~~~Java diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index d2d669b68..5ca6833fd 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -103,8 +103,9 @@ public TransformerImpl() { @Override public final Transformer withFieldMapping(final FieldMapping... fieldMapping) { final Map fieldsNameMapping = transformerSettings.getFieldsNameMapping(); - stream(fieldMapping) - .forEach(mapping -> fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName())); + for (FieldMapping mapping : fieldMapping) { + fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); + } return this; } @@ -132,8 +133,9 @@ public final void resetFieldsMapping() { @SuppressWarnings("unchecked") public final Transformer withFieldTransformer(final FieldTransformer... fieldTransformer) { Map> fieldsTransformers = transformerSettings.getFieldsTransformers(); - stream(fieldTransformer) - .forEach(transformer -> fieldsTransformers.put(transformer.getDestFieldName(), transformer.getTransformerFunction())); + for (FieldTransformer transformer : fieldTransformer) { + fieldsTransformers.put(transformer.getDestFieldName(), transformer.getTransformerFunction()); + } return this; } diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index c4bef7275..108fbbd66 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -137,6 +137,7 @@ public Object getFieldValue(final Object target, final Field field) { public Object getFieldValue(final Object target, final String fieldName, final Class fieldType) { Object fieldValue = getRealTarget(target); for (String currFieldName : fieldName.split(DOT_SPLIT_REGEX)) { + if (fieldValue == null) break; try { fieldValue = getFieldValue(fieldValue, currFieldName); } catch (final Exception e) { diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index aa895566a..7d80ffa6a 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -118,6 +118,7 @@ public class TransformerTest { private static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); private static FromFoo fromFoo; + private static FromFoo fromFooWithNullProperties; private static FromFooSimple fromFooSimple; private static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; private static List fromSubFooList; @@ -272,6 +273,25 @@ public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected() underTest.resetFieldsMapping(); } + /** + * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly + * valorized even if some of them are null. + */ + @Test + public void testTransformationWithCompositeFieldNameWorksEvenWithNullObjects() { + //GIVEN + FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); + + //WHEN + ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFooWithNullProperties, ImmutableFlatToFoo.class); + + //THEN + assertEquals(fromFooWithNullProperties.getName(), actual.getName()); + assertEquals(fromFooWithNullProperties.getId(), actual.getId()); + assertEquals(fromFooWithNullProperties.getNestedObject(), actual.getPhoneNumbers()); + underTest.resetFieldsMapping(); + } + /** * Test that immutable beans without custom field mapping. */ @@ -715,7 +735,7 @@ private void initGetDestFieldNameTestMock(final String declaringClassName, final } /** - * Restored the initail object status before testing method: {@code getDestFieldName}. + * Restored the initial object status before testing method: {@code getDestFieldName}. */ private void restoreObjects(final Method getDestFieldNameMethod) { getDestFieldNameMethod.setAccessible(false); @@ -732,7 +752,8 @@ private static void initObjects() { fromSubFoo = new FromSubFoo(SUB_FOO_NAME, SUB_FOO_PHONE_NUMBERS, SUB_FOO_SAMPLE_MAP, SUB_FOO_COMPLEX_MAP, SUB_FOO_VERY_COMPLEX_MAP); fromSubFooList = singletonList(fromSubFoo); sourceFooSimpleList = asList(ITEM_1, ITEM_2); - fromFoo = createFromFoo(); + fromFoo = createFromFoo(fromSubFoo); + fromFooWithNullProperties = createFromFoo(null); fromFooSimple = createFromFooSimple(); fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); fromFooSubClass = createFromFooSubClass(); @@ -741,9 +762,10 @@ private static void initObjects() { /** * Creates a {@link FromFoo} instance. + * @param fromSubFoo the {@link FromSubFoo} instance * @return the {@link FromFoo} instance. */ - private static FromFoo createFromFoo() { + private static FromFoo createFromFoo(final FromSubFoo fromSubFoo) { return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); } From a85ded0305c5a6e1852d9c3bc57d776827c2e7bf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Feb 2019 09:51:13 +0100 Subject: [PATCH 0232/1786] Removed parallel execution in order to improve performances --- .travis.yml | 1 + .../java/com/hotels/beans/populator/ArrayPopulator.java | 2 +- .../com/hotels/beans/populator/CollectionPopulator.java | 3 ++- src/main/java/com/hotels/beans/populator/MapPopulator.java | 4 +++- src/main/java/com/hotels/beans/utils/ClassUtils.java | 7 ++++--- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index cb6c90ae7..1750020c6 100755 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ jobs: if: branch = master AND type NOT IN (pull_request) jdk: oraclejdk8 before_deploy: + - mvn versions:set -D newVersion=${TRAVIS_TAG} AND tag IS present - travis_retry mvn install site:site -DskipTests=true -B deploy: provider: pages diff --git a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index abc6aa4f9..80bdfe212 100644 --- a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -55,7 +55,7 @@ public Object getPopulatedObject(final Class genericFieldType, final Object f res = fieldValue; } else { res = stream((Object[]) fieldValue) - .parallel() + //.parallel() .map(o -> classUtils.isPrimitiveOrSpecialType(genericFieldType) ? o : transform(o, genericFieldType)).toArray(); } return res; diff --git a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index 220b103c9..5f18f5c83 100644 --- a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -58,7 +58,8 @@ public Collection getPopulatedObject(final Class genericFieldType, final O res = (Collection) fieldValue; } else { res = ((Collection) fieldValue) - .parallelStream() + .stream() +// .parallelStream() .map(elem -> transform(elem, (Class) genericFieldType)) .collect(toList()); } diff --git a/src/main/java/com/hotels/beans/populator/MapPopulator.java b/src/main/java/com/hotels/beans/populator/MapPopulator.java index 908de07a0..f019b56d7 100644 --- a/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -63,7 +63,9 @@ class MapPopulator extends Populator> { if (keyIsPrimitive && elemIsPrimitive) { populatedObject = fieldValue; } else { - populatedObject = fieldValue.keySet().parallelStream() + populatedObject = fieldValue.keySet() + .stream() +// .parallelStream() .collect(toMap( key -> getElemValue(keyType, keyIsPrimitive, key), key -> getElemValue(elemType, elemIsPrimitive, fieldValue.get(key)))); diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index bafafb390..4e8e9008a 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -234,7 +234,7 @@ public List getPrivateFinalFields(final Class clazz) { res.addAll(getPrivateFinalFields(clazz.getSuperclass())); } res.addAll(stream(getDeclaredFields(clazz)) - .parallel() + //.parallel() .filter(IS_FINAL_AND_NOT_STATIC_FIELD) .collect(toList())); cacheManager.cacheObject(cacheKey, res); @@ -286,7 +286,7 @@ public List getPrivateFields(final Class clazz, final boolean skipFina res.addAll(getPrivateFields(clazz.getSuperclass(), skipFinal)); } res.addAll(stream(getDeclaredFields(clazz)) - .parallel() + //.parallel() .filter(field -> isPrivate(field.getModifiers()) && (!skipFinal || !isFinal(field.getModifiers())) && !isStatic(field.getModifiers())) @@ -313,7 +313,8 @@ public List getDeclaredFields(final Class clazz, final boolean skipSta } Stream fieldStream = stream(getDeclaredFields(clazz)); if (skipStatic) { - fieldStream = fieldStream.parallel().filter(field -> !isStatic(field.getModifiers())); +// fieldStream = fieldStream.parallel().filter(field -> !isStatic(field.getModifiers())); + fieldStream = fieldStream.filter(field -> !isStatic(field.getModifiers())); } res.addAll(fieldStream.collect(toList())); cacheManager.cacheObject(cacheKey, res); From e42f29b9434f15bd3feb9120863095dbdd60b31a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Feb 2019 09:56:40 +0100 Subject: [PATCH 0233/1786] Moved distribution management outside release profile --- pom.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index dff49b2e5..677aed4ad 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,16 @@ https://github.com/HotelsDotCom/bull HEAD + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + @@ -149,16 +159,6 @@ release - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - From 0a5e842a031d1c413d32d05109b7fcb66e380ee2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Feb 2019 14:28:03 +0100 Subject: [PATCH 0234/1786] Modified change log release date for version 1.1.2 --- CHANGELOG.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95259e4b9..29c1cacba 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,13 @@ All notable changes to this project will be documented in this file. -### [1.1.2] TBD +### [1.1.2] 2019.02 #### Added -* Made the field name mapping more flexible adding the possibility to map destination object field with field contained into nested objects -* Added samples for the above functionality +* Made the field name mapping more flexible adding the possibility to map destination object field with field contained into nested objects. +* Added samples and tests for the above functionality. +#### Changed +* Updated hibernate dependency: `org.hibernate.validator` (was `org.hibernate.validator`). +* Removed `parallel` execution where not needed because this could cause performance degradation. ### [1.1.1] 2019.02.09 #### Changed From 855b142d80036423db438882e587d81b7773b911 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Feb 2019 14:33:11 +0100 Subject: [PATCH 0235/1786] moved site build condition --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1750020c6..538efdd08 100755 --- a/.travis.yml +++ b/.travis.yml @@ -30,10 +30,10 @@ jobs: install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" - if: branch = master AND type NOT IN (pull_request) + if: branch = master AND type NOT IN (pull_request) AND tag IS present jdk: oraclejdk8 before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} AND tag IS present + - mvn versions:set -D newVersion=${TRAVIS_TAG} - travis_retry mvn install site:site -DskipTests=true -B deploy: provider: pages From d103627e613d54c2abc50bbeb45ba044d2520326 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Feb 2019 15:12:14 +0100 Subject: [PATCH 0236/1786] modified travis tag condition --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 538efdd08..b26af0bbd 100755 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ jobs: install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" - if: branch = master AND type NOT IN (pull_request) AND tag IS present + if: branch = master AND type NOT IN (pull_request) AND tag = true jdk: oraclejdk8 before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} @@ -45,7 +45,7 @@ jobs: branch: master - stage: "Release" name: "Releasing artifacts" - if: type NOT IN (pull_request) AND tag IS present + if: type NOT IN (pull_request) AND tag = true install: skip before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d From 392bc455534acf486b10642117c76b54a84371a9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Feb 2019 15:18:15 +0100 Subject: [PATCH 0237/1786] restored old travis condition as not working as expected --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b26af0bbd..488f16d1f 100755 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ jobs: install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" - if: branch = master AND type NOT IN (pull_request) AND tag = true + if: type NOT IN (pull_request) AND tag IS present jdk: oraclejdk8 before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} @@ -45,7 +45,7 @@ jobs: branch: master - stage: "Release" name: "Releasing artifacts" - if: type NOT IN (pull_request) AND tag = true + if: type NOT IN (pull_request) AND tag IS present install: skip before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d From 94441733dab338452d02eece510fc4312fef72d7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Feb 2019 15:26:52 +0100 Subject: [PATCH 0238/1786] [maven-release-plugin] prepare release bean-utils-library-1.1.2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 677aed4ad..e19f77e6c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.2-SNAPSHOT + 1.1.2 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + bean-utils-library-1.1.2 From 10a52acbfe5f07619e71df347dea45e6a33f703d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Feb 2019 15:26:59 +0100 Subject: [PATCH 0239/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e19f77e6c..2521adf1d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.2 + 1.1.3-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - bean-utils-library-1.1.2 + HEAD From 09e1e596828b959dfc65462a7c016276724c4bdc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Feb 2019 20:48:43 +0100 Subject: [PATCH 0240/1786] added sonar server settings --- config/travis/mvn-settings.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index f83952c5c..c7dd98343 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -5,6 +5,16 @@ ${env.OSSRH_USERNAME} ${env.OSSRH_PASSWORD} + + sonatype-nexus-staging + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + + + sonatype-nexus-snapshots + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + ${github_server_id} From 3e845a11e0091dc33abf6cc9d3ce6b31bfb97626 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 13 Feb 2019 14:13:29 +0100 Subject: [PATCH 0241/1786] Added Javadoc page link plus github site --- README.md | 7 +++++-- pom.xml | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 748fcd8f0..b18d8f53b 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,16 @@ ## Bean Utils Light Library -This BeanUtils library is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. +BULL is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. ## Start using -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=com.hotels.beans:bean-utils-library)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) +[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bean-utils-library.svg)](http://www.javadoc.io/doc/com.hotels.beans/bean-utils-library) +[![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) + [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) diff --git a/pom.xml b/pom.xml index 2521adf1d..dc46cbff2 100644 --- a/pom.xml +++ b/pom.xml @@ -204,7 +204,6 @@ **/logback*.xml **/banner.txt **/*.yml - **/application/** **/stats/** From 7fb64e802552d263b6096a0205345e52a78603b1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 14 Feb 2019 22:19:12 +0100 Subject: [PATCH 0242/1786] Added PULL request template --- PULL_REQUEST_TEMPLATE.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 PULL_REQUEST_TEMPLATE.md diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..a199360c1 --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,24 @@ +# Pull Request Template + +## Description + +Please include a summary of the change or which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. + +Fixes # (issue) + +## How Has This Been Tested? + +Please describe the tests that you ran to verify your changes. Please also note any relevant details for your test configuration. + +- [ ] Test A +- [ ] Test B + +## Checklist: + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] Any dependent changes have been merged and published in downstream modules +- [ ] My changes have no bad impacts on performances From 1879b3e0400c9c663e8487753691e3dbe4da75af Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 15 Feb 2019 19:31:13 +0100 Subject: [PATCH 0243/1786] Creating "How to test" page --- docs/site/markdown/transformer/testing.md | 109 ++++++++++++++++++++++ docs/site/site.xml | 1 + 2 files changed, 110 insertions(+) create mode 100644 docs/site/markdown/transformer/testing.md diff --git a/docs/site/markdown/transformer/testing.md b/docs/site/markdown/transformer/testing.md new file mode 100644 index 000000000..c2f31cf08 --- /dev/null +++ b/docs/site/markdown/transformer/testing.md @@ -0,0 +1,109 @@ + + Test your library + + +# Overview + +Software testing plays a fundamental role in the software development because we can evaluate one or more properties of interest. In general, these properties indicate the +extent to which the component or system under test: + +* meets the requirements that guided its design and development, +* responds correctly to all kinds of inputs, +* performs its functions within an acceptable time, +* it is sufficiently usable, +* can be installed and run in its intended environments +* achieves the general result its stakeholders desire. + +This page will show how to test BULL into a simple project. All the examples utilizes [JUnit](https://github.com/junit-team) + +The Java Bean transformation function can be tested in two different ways that depends on the following scenarios: + +1. The destination object does not require a special configuration to get transformed +2. The destination object requires a special configuration, you are confident that the configuration is working fine as it doesn't includes any special action +3. The destination object requires a special and complex configuration that needs to be tested as we are not confident that it would work + +For both scenarios: 1 and 2 we can use a mocked version the `BeanUtils` object. + +### First scenario: + +Assuming that our source object and our destination object have been defined as follow: +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +@Setter @Setter +public class FromFoo { public class ToFoo { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List nestedObjectList; + private ImmutableToSubFoo nestedObject; +} + } +~~~ +And this is the class containing the `BeanUtils` library: +~~~Java +import ... + +public class SampleClass { + + private final BeanUtils beanUtils; + + public SampleClass() { + this.beanUtils = new BeanUtils(); + } + + public SampleResponse doSomething(final SampleRequest request) { + final Transformer beanTransformer = beanUtils.getTransformer(); + return beanTransformer.transform(request, SampleResponse.class); + } +} +~~~ +The test class will be: +~~~Java +import static org.junit.Assert.assertNotNull; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.transformer.Transformer; + +/** + * Unit test for {@link SampleClass}. + */ +public class SampleClassTest { + /** + * The class to be tested. + */ + @InjectMocks + private SampleClass underTest; + + @Mock + private BeanUtils beanUtils; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + ReflectionTestUtils.setField(underTest, "beanUtils", beanUtils); + } + + /** + * Test that a SampleResponse is returned. + */ + @Test + public void testDoSomethingWorksProperly() { + //GIVEN + + //WHEN + final Transformer transformer = underTest.getTransformer(); + + //THEN + assertNotNull(transformer); + } +} +~~~ diff --git a/docs/site/site.xml b/docs/site/site.xml index 73278ae57..9a1f7f9e0 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -28,6 +28,7 @@
    + From 31acefd9857190db45471722121b215256f00884 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 15 Feb 2019 23:46:00 +0100 Subject: [PATCH 0244/1786] Replaced utility method in order to remove a dependency --- pom.xml | 66 +++++++++++++++++-- .../hotels/beans/utils/ReflectionUtils.java | 2 +- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index dc46cbff2..de7059cdf 100644 --- a/pom.xml +++ b/pom.xml @@ -26,9 +26,9 @@ ${jdk.version} ${jdk.version} 3.11.0 + 2.1.2.RELEASE 1.18.4 - 1.3 3.8.1 0.11 2.8.5 @@ -82,12 +82,6 @@ commons-lang3 ${apache.commons-lang3.version}
    - - org.apache.commons - commons-text - ${apache.common.version} - - javax.validation validation-api @@ -234,6 +228,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.apache.maven.plugins maven-checkstyle-plugin diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 108fbbd66..b606c8f5d 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -21,7 +21,7 @@ import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; -import static org.apache.commons.text.WordUtils.capitalize; +import static org.apache.commons.lang3.StringUtils.capitalize; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.constant.MethodPrefix.GET; From c115ac90dbf6203feb5f1629823b773a293eb4b7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 16 Feb 2019 08:05:01 +0100 Subject: [PATCH 0245/1786] Added static method for transforming object --- src/main/java/com/hotels/beans/BeanUtils.java | 14 ++++++ .../java/com/hotels/beans/BeanUtilsTest.java | 48 ++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hotels/beans/BeanUtils.java b/src/main/java/com/hotels/beans/BeanUtils.java index ef012cec4..b7aaadeae 100644 --- a/src/main/java/com/hotels/beans/BeanUtils.java +++ b/src/main/java/com/hotels/beans/BeanUtils.java @@ -16,6 +16,8 @@ package com.hotels.beans; +import java.util.function.Function; + import com.hotels.beans.transformer.TransformerImpl; import com.hotels.beans.transformer.Transformer; @@ -24,6 +26,18 @@ */ public class BeanUtils { + /** + * Returns a function that transforms an object T in an object K. + * @param targetClass the destination object class + * @param the Source object type + * @param the target object type + * @return a function that copies of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + public static Function getTransformer(final Class targetClass) { + return fromBean -> new TransformerImpl().transform(fromBean, targetClass); + } + /** * Returns a Bean Transformer. * @return a Bean Transformer instance. diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/src/test/java/com/hotels/beans/BeanUtilsTest.java index 3e241bf09..887963a17 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -17,19 +17,34 @@ package com.hotels.beans; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.immutable.ImmutableToFooSimple; import com.hotels.beans.transformer.Transformer; /** * Unit test for {@link BeanUtils}. */ public class BeanUtilsTest { - /** + private static final BigInteger ID = new BigInteger("1234"); + private static final String NAME = "Goofy"; + + /** * The class to be tested. */ @InjectMocks @@ -44,7 +59,7 @@ public void beforeMethod() { } /** - * Test that a Tranformer is returned. + * Test that a Transformer is returned. */ @Test public void testGetTransformerWorksProperly() { @@ -56,4 +71,33 @@ public void testGetTransformerWorksProperly() { //THEN assertNotNull(transformer); } + + /** + * Test that the transformer function returned is able to transform the given object. + */ + @Test + public void testGetTransformerFunctionWorksProperly() { + //GIVEN + FromFooSimple fromFooSimple = createFromFooSimple(); + List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimple); + + //WHEN + Function transformerFunction = underTest.getTransformer(ImmutableToFooSimple.class); + List actual = fromFooSimpleList.stream() + .map(transformerFunction) + .collect(Collectors.toList()); + + //THEN + assertNotNull(transformerFunction); + IntStream.range(0, actual.size()) + .forEach(i -> assertThat(actual.get(i), sameBeanAs(fromFooSimpleList.get(i)))); + } + + /** + * Creates a {@link FromFooSimple} instance. + * @return the {@link FromFooSimple} instance. + */ + private FromFooSimple createFromFooSimple() { + return new FromFooSimple(NAME, ID); + } } From e2380868932fd96e0a570452a13b0f02b37699a3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 17 Feb 2019 08:21:04 +0100 Subject: [PATCH 0246/1786] Documented new function and updated backlog --- CHANGELOG.md | 4 ++++ README.md | 15 ++++++++++++++- docs/site/markdown/transformer/samples.md | 15 ++++++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29c1cacba..600719fa1 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.1.3] 2019.17 +#### Added +* Added static transformation functionality (see: [Issue 25](https://github.com/HotelsDotCom/bull/issues/25)). + ### [1.1.2] 2019.02 #### Added * Made the field name mapping more flexible adding the possibility to map destination object field with field contained into nested objects. diff --git a/README.md b/README.md index 748fcd8f0..73d65296c 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final List subBeanList; private final String name; private List list; private final List list; - private final FromSubBean subObject; private final List nestedObjectList; + private final FromSubBean subObject; private final List subBeanList; private ImmutableToSubFoo nestedObject; // constructors... // constructors... @@ -253,6 +253,19 @@ ToBean toBean = beanUtils.getTransformer() .withFieldTransformer(notExistingFieldTransformer) .transform(fromBean, ToBean.class); ~~~ + +### Static transformer function: + +~~~Java +List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimple); +~~~ +can be transformed as follow: +~~~Java +Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); + List actual = fromFooSimpleList.stream() + .map(transformerFunction) + .collect(Collectors.toList()); +~~~ More sample beans can be found in the test package: `com.hotels.beans.sample` diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index cbe5e0b7d..2982197a5 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -199,5 +199,18 @@ ToBean toBean = beanUtils.getTransformer() .withFieldTransformer(notExistingFieldTransformer) .transform(fromBean, ToBean.class); ~~~ - + +### Static transformer function: + +~~~Java +List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimple); +~~~ +can be transformed as follow: +~~~Java +Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); + List actual = fromFooSimpleList.stream() + .map(transformerFunction) + .collect(Collectors.toList()); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` \ No newline at end of file From 37459e6ab595c2b47e72c6a3d5ee1835f58897e1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 17 Feb 2019 08:27:07 +0100 Subject: [PATCH 0247/1786] [maven-release-plugin] prepare release 1.1.3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2521adf1d..b4be0d4f4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.3-SNAPSHOT + 1.1.3 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.3 From ac4f0f52d2f1c61ef1beba70cb013d512d74979a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 17 Feb 2019 08:27:14 +0100 Subject: [PATCH 0248/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index b4be0d4f4..2f6a86866 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.3 + 1.1.4-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.3 + HEAD From 7e34cc8bea5734bb51a6805873aa611a2f3a718c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 Feb 2019 23:05:11 +0100 Subject: [PATCH 0249/1786] Started breadcrumbs implementation --- .../beans/transformer/TransformerImpl.java | 56 +++++++++++-------- .../mutable/MutableToFooBreadcrumb.java | 33 +++++++++++ .../beans/transformer/TransformerTest.java | 15 +++++ 3 files changed, 81 insertions(+), 23 deletions(-) create mode 100644 src/test/java/com/hotels/beans/sample/mutable/MutableToFooBreadcrumb.java diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 5ca6833fd..ef932a419 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -164,12 +164,16 @@ public final Transformer setDefaultValueForMissingField(final boolean useDefault transformerSettings.setSetDefaultValue(useDefaultValue); return this; } + @Override + public final K transform(final T sourceObj, final Class targetClass) { + return transform(sourceObj, targetClass, null); + } /** * {@inheritDoc} */ - @Override - public final K transform(final T sourceObj, final Class targetClass) { + + public final K transform(final T sourceObj, final Class targetClass, String breadCrumb) { notNull(sourceObj, "The object to copy cannot be null!"); notNull(targetClass, "The destination class cannot be null!"); final K k; @@ -177,16 +181,16 @@ public final K transform(final T sourceObj, final Class targ if (classType.is(MUTABLE)) { try { k = targetClass.getDeclaredConstructor().newInstance(); - injectNotFinalFields(sourceObj, k); + injectNotFinalFields(sourceObj, k, breadCrumb); } catch (NoSuchMethodException e) { throw new InvalidBeanException("No default constructor defined for class: " + targetClass.getName(), e); } catch (Exception e) { throw new InvalidBeanException(e.getMessage(), e); } } else { - k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass)); + k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadCrumb); if (classType.is(MIXED)) { - injectNotFinalFields(sourceObj, k); + injectNotFinalFields(sourceObj, k, breadCrumb); } } validate(k); @@ -204,12 +208,12 @@ public final K transform(final T sourceObj, final Class targ * @throws InvalidBeanException {@link InvalidBeanException} if the target object is not compliant with the requirements */ @SuppressWarnings("unchecked") - private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor) { + private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, String breadCrumb) { final Object[] constructorArgs; if (canBeInjectedByConstructorParams(constructor, targetClass)) { - constructorArgs = getConstructorArgsValues(sourceObj, targetClass, constructor); + constructorArgs = getConstructorArgsValues(sourceObj, targetClass, constructor, breadCrumb); } else { - constructorArgs = getConstructorValuesFromFields(sourceObj, targetClass); + constructorArgs = getConstructorValuesFromFields(sourceObj, targetClass, breadCrumb); } try { return (K) constructor.newInstance(constructorArgs); @@ -262,7 +266,7 @@ private boolean canBeInjectedByConstructorParams(final Constructor construct * @return a list containing the values for the destination constructor. * @throws InvalidBeanException {@link InvalidBeanException} if there is an error while retrieving the constructor args parameter */ - private Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor) { + private Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor, String breadCrumb) { final Parameter[] constructorParameters = classUtils.getConstructorParameters(constructor); final Object[] constructorArgsValues = new Object[constructorParameters.length]; range(0, constructorParameters.length) @@ -273,7 +277,7 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); } else { String sourceFieldName = getSourceFieldName(destFieldName); - constructorArgsValues[i] = ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, classUtils.getDeclaredField(targetClass, destFieldName))) + constructorArgsValues[i] = ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, classUtils.getDeclaredField(targetClass, destFieldName), breadCrumb)) .orElse(classUtils.getDefaultTypeValue(constructorParameters[i].getType())); } }); @@ -331,10 +335,10 @@ private String getDestFieldName(final Parameter constructorParameter, final Stri * @return a list containing the values for the destination constructor. * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ - private Object[] getConstructorValuesFromFields(final T sourceObj, final Class targetClass) { + private Object[] getConstructorValuesFromFields(final T sourceObj, final Class targetClass, String breadCrumb) { final List declaredFields = classUtils.getDeclaredFields(targetClass, true); return declaredFields.stream() - .map(field -> getFieldValue(sourceObj, targetClass, field)) + .map(field -> getFieldValue(sourceObj, targetClass, field, breadCrumb)) .toArray(Object[]::new); } @@ -347,11 +351,11 @@ private Object[] getConstructorValuesFromFields(final T sourceObj, final * @param the target object type * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ - private void injectNotFinalFields(final T sourceObj, final K targetObject) { + private void injectNotFinalFields(final T sourceObj, final K targetObject, String breadCrumb) { final Class targetObjectClass = targetObject.getClass(); classUtils.getNotFinalFields(targetObjectClass, true) //.parallelStream() - .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field))); + .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadCrumb))); } /** @@ -364,9 +368,10 @@ private void injectNotFinalFields(final T sourceObj, final K targetObject * @return the field value * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ - private Object getFieldValue(final T sourceObj, final Class targetClass, final Field field) { + private Object getFieldValue(final T sourceObj, final Class targetClass, final Field field, String breadCrumb) { String sourceFieldName = getSourceFieldName(field); - return getFieldValue(sourceObj, sourceFieldName, targetClass, field); + String breadCrumbValorized = ofNullable(breadCrumb).map(bc -> bc + "." + field.getName()).orElse(field.getName()); + return getFieldValue(sourceObj, sourceFieldName, targetClass, field, breadCrumbValorized); } /** @@ -380,7 +385,11 @@ private Object getFieldValue(final T sourceObj, final Class targetClas * @return the field value * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ - private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field) { +// private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field) { +// return getFieldValue(sourceObj, sourceFieldName, targetClass, field, field.getName()); +// } + + private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadCrumb) { Object fieldValue = null; if (isNotEmpty(sourceFieldName)) { boolean primitiveType = classUtils.isPrimitiveType(field.getType()); @@ -392,13 +401,13 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(field.getType()); if ((notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass())) && !isFieldTransformerDefined) { - fieldValue = getFieldValue(targetClass, field, fieldValue); + fieldValue = getFieldValue(targetClass, field, fieldValue, breadCrumb); } } else if (primitiveType) { fieldValue = defaultValue(field.getType()); // assign the default value } } - return getTransformedField(field, fieldValue); + return getTransformedField(field, fieldValue, breadCrumb); } /** @@ -430,10 +439,11 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie * It executes the lambda function defined to the field. * @param field The field on which the transformation should be applied. * @param fieldValue The field value. + * @param breadCrumb * @return the transformed field. */ - private Object getTransformedField(final Field field, final Object fieldValue) { - return ofNullable(transformerSettings.getFieldsTransformers().get(field.getName())) + private Object getTransformedField(final Field field, final Object fieldValue, String breadCrumb) { + return ofNullable(transformerSettings.getFieldsTransformers().get(breadCrumb)) .map(fieldTransformer -> fieldTransformer.apply(fieldValue)) .orElse(fieldValue); } @@ -448,12 +458,12 @@ private Object getTransformedField(final Field field, final Object fieldValue) { * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ @SuppressWarnings("unchecked") - private Object getFieldValue(final Class targetClass, final Field field, final Object fieldValue) { + private Object getFieldValue(final Class targetClass, final Field field, final Object fieldValue, final String breadCrumb) { return getPopulator(field.getType(), fieldValue.getClass(), this) .map(populator -> populator.getPopulatedObject(targetClass, field.getName(), fieldValue)) .orElseGet(() -> // recursively inject object - transform(fieldValue, field.getType()) + transform(fieldValue, field.getType(), breadCrumb) ); } diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooBreadcrumb.java b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooBreadcrumb.java new file mode 100644 index 000000000..c02d747ab --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooBreadcrumb.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import lombok.Getter; +import lombok.Setter; + +import java.math.BigInteger; +import java.util.List; + +/** + * Sample mutable object. + */ +@Getter +@Setter +public class MutableToFooBreadcrumb { + private String name; + private MutableToSubFoo nestedObject; +} diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 7d80ffa6a..bcd505545 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -48,6 +48,7 @@ import java.util.Optional; import java.util.stream.IntStream; +import com.hotels.beans.sample.mutable.MutableToFooBreadcrumb; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -408,6 +409,20 @@ public void testMutableBeanIsCorrectlyCopied() { assertThat(actual, sameBeanAs(fromFoo)); } + /** + * Test mutable beans are correctly copied. + */ + @Test + public void testMutableBeanIsCorrectlyCopied2() { + //GIVEN + + //WHEN + MutableToFooBreadcrumb actual = underTest.transform(fromFoo, MutableToFooBreadcrumb.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + /** * Test that bean that extends another class are correctly copied. */ From dc3b2cadedcdf4449bd0590ecb1cb9aed690c910 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 19 Feb 2019 00:04:47 +0100 Subject: [PATCH 0250/1786] Added "breadcrumb" strategy that allows to apply a lambda function only on a specific field even if there are other with same name elsewhere --- .../beans/transformer/TransformerImpl.java | 90 ++++++++++++------- .../mutable/MutableToFooBreadcrumb.java | 33 ------- .../beans/transformer/TransformerTest.java | 21 +++-- 3 files changed, 70 insertions(+), 74 deletions(-) delete mode 100644 src/test/java/com/hotels/beans/sample/mutable/MutableToFooBreadcrumb.java diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index ef932a419..d7fe33f66 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -164,33 +164,42 @@ public final Transformer setDefaultValueForMissingField(final boolean useDefault transformerSettings.setSetDefaultValue(useDefaultValue); return this; } + + /** + * {@inheritDoc} + */ @Override public final K transform(final T sourceObj, final Class targetClass) { + notNull(sourceObj, "The object to copy cannot be null!"); + notNull(targetClass, "The destination class cannot be null!"); return transform(sourceObj, targetClass, null); } /** - * {@inheritDoc} + * Copies all properties from an object to a new one. + * @param sourceObj the source object + * @param targetClass the destination object class + * @param breadcrumb the full path of the current field starting from his ancestor + * @param the Source object type + * @param the target object type + * @return a copy of the source object into the destination object */ - - public final K transform(final T sourceObj, final Class targetClass, String breadCrumb) { - notNull(sourceObj, "The object to copy cannot be null!"); - notNull(targetClass, "The destination class cannot be null!"); + private K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; final ClassType classType = classUtils.getClassType(targetClass); if (classType.is(MUTABLE)) { try { k = targetClass.getDeclaredConstructor().newInstance(); - injectNotFinalFields(sourceObj, k, breadCrumb); + injectNotFinalFields(sourceObj, k, breadcrumb); } catch (NoSuchMethodException e) { throw new InvalidBeanException("No default constructor defined for class: " + targetClass.getName(), e); } catch (Exception e) { throw new InvalidBeanException(e.getMessage(), e); } } else { - k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadCrumb); + k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); if (classType.is(MIXED)) { - injectNotFinalFields(sourceObj, k, breadCrumb); + injectNotFinalFields(sourceObj, k, breadcrumb); } } validate(k); @@ -202,18 +211,19 @@ public final K transform(final T sourceObj, final Class targ * @param sourceObj sourceObj the source object * @param targetClass the destination object class * @param constructor the all args constructor + * @param breadcrumb the full path of the current field starting from his ancestor * @param the sourceObj object type * @param the target object type * @return a copy of the source object into the destination object * @throws InvalidBeanException {@link InvalidBeanException} if the target object is not compliant with the requirements */ @SuppressWarnings("unchecked") - private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, String breadCrumb) { + private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { final Object[] constructorArgs; if (canBeInjectedByConstructorParams(constructor, targetClass)) { - constructorArgs = getConstructorArgsValues(sourceObj, targetClass, constructor, breadCrumb); + constructorArgs = getConstructorArgsValues(sourceObj, targetClass, constructor, breadcrumb); } else { - constructorArgs = getConstructorValuesFromFields(sourceObj, targetClass, breadCrumb); + constructorArgs = getConstructorValuesFromFields(sourceObj, targetClass, breadcrumb); } try { return (K) constructor.newInstance(constructorArgs); @@ -261,12 +271,13 @@ private boolean canBeInjectedByConstructorParams(final Constructor construct * @param sourceObj sourceObj the source object * @param targetClass the destination object class * @param constructor the all args constructor + * @param breadcrumb the full path of the current field starting from his ancestor * @param the sourceObj object type * @param the target object type * @return a list containing the values for the destination constructor. * @throws InvalidBeanException {@link InvalidBeanException} if there is an error while retrieving the constructor args parameter */ - private Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor, String breadCrumb) { + private Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { final Parameter[] constructorParameters = classUtils.getConstructorParameters(constructor); final Object[] constructorArgsValues = new Object[constructorParameters.length]; range(0, constructorParameters.length) @@ -277,7 +288,8 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); } else { String sourceFieldName = getSourceFieldName(destFieldName); - constructorArgsValues[i] = ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, classUtils.getDeclaredField(targetClass, destFieldName), breadCrumb)) + constructorArgsValues[i] = + ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, classUtils.getDeclaredField(targetClass, destFieldName), breadcrumb)) .orElse(classUtils.getDefaultTypeValue(constructorParameters[i].getType())); } }); @@ -330,15 +342,16 @@ private String getDestFieldName(final Parameter constructorParameter, final Stri * This methods retrieves the values from the declared class field into the target object. * @param sourceObj sourceObj the source object * @param targetClass the destination object class + * @param breadcrumb the full path of the current field starting from his ancestor * @param the sourceObj object type * @param the target object type * @return a list containing the values for the destination constructor. * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ - private Object[] getConstructorValuesFromFields(final T sourceObj, final Class targetClass, String breadCrumb) { + private Object[] getConstructorValuesFromFields(final T sourceObj, final Class targetClass, final String breadcrumb) { final List declaredFields = classUtils.getDeclaredFields(targetClass, true); return declaredFields.stream() - .map(field -> getFieldValue(sourceObj, targetClass, field, breadCrumb)) + .map(field -> getFieldValue(sourceObj, targetClass, field, breadcrumb)) .toArray(Object[]::new); } @@ -347,15 +360,16 @@ private Object[] getConstructorValuesFromFields(final T sourceObj, final * This methods retrieves the values from the declared class field into the target object. * @param sourceObj sourceObj the source object * @param targetObject the destination object instance + * @param breadcrumb the full path of the current field starting from his ancestor * @param the sourceObj object type * @param the target object type * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ - private void injectNotFinalFields(final T sourceObj, final K targetObject, String breadCrumb) { + private void injectNotFinalFields(final T sourceObj, final K targetObject, final String breadcrumb) { final Class targetObjectClass = targetObject.getClass(); classUtils.getNotFinalFields(targetObjectClass, true) //.parallelStream() - .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadCrumb))); + .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); } /** @@ -363,15 +377,15 @@ private void injectNotFinalFields(final T sourceObj, final K targetObject * @param sourceObj sourceObj the source object * @param targetClass the destination object class * @param field The field for which the value has to be retrieved + * @param breadcrumb the full path of the current field starting from his ancestor * @param the sourceObj object type * @param the target object type * @return the field value * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ - private Object getFieldValue(final T sourceObj, final Class targetClass, final Field field, String breadCrumb) { + private Object getFieldValue(final T sourceObj, final Class targetClass, final Field field, final String breadcrumb) { String sourceFieldName = getSourceFieldName(field); - String breadCrumbValorized = ofNullable(breadCrumb).map(bc -> bc + "." + field.getName()).orElse(field.getName()); - return getFieldValue(sourceObj, sourceFieldName, targetClass, field, breadCrumbValorized); + return getFieldValue(sourceObj, sourceFieldName, targetClass, field, breadcrumb); } /** @@ -380,17 +394,15 @@ private Object getFieldValue(final T sourceObj, final Class targetClas * @param sourceFieldName sourceFieldName the field name in the source object (if different from the target one) * @param targetClass the destination object class * @param field The field for which the value has to be retrieved + * @param breadcrumb the full path of the current field starting from his ancestor * @param the sourceObj object type * @param the target object type * @return the field value * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ -// private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field) { -// return getFieldValue(sourceObj, sourceFieldName, targetClass, field, field.getName()); -// } - - private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadCrumb) { + private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { Object fieldValue = null; + String realBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); if (isNotEmpty(sourceFieldName)) { boolean primitiveType = classUtils.isPrimitiveType(field.getType()); boolean isFieldTransformerDefined = transformerSettings.getFieldsTransformers().containsKey(field.getName()); @@ -401,13 +413,23 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(field.getType()); if ((notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass())) && !isFieldTransformerDefined) { - fieldValue = getFieldValue(targetClass, field, fieldValue, breadCrumb); + fieldValue = getFieldValue(targetClass, field, fieldValue, realBreadcrumb); } } else if (primitiveType) { fieldValue = defaultValue(field.getType()); // assign the default value } } - return getTransformedField(field, fieldValue, breadCrumb); + return getTransformedField(realBreadcrumb, fieldValue); + } + + /** + * Build the current field breadcrumb. + * @param fieldName the field name + * @param breadcrumb the existing breadcrumb + * @return the updated breadcrumb + */ + private String evalBreadcrumb(final String fieldName, final String breadcrumb) { + return (nonNull(breadcrumb) ? (breadcrumb + DOT.getSymbol()) : "") + fieldName; } /** @@ -415,7 +437,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN * @param sourceObj sourceObj the source object * @param sourceFieldName sourceFieldName the field name in the source object (if different from the target one) * @param field The field for which the value has to be retrieved - * @param isFieldTransformerDefined indicates if a tranformer function is implemented for this field + * @param isFieldTransformerDefined indicates if a transformer function is implemented for this field * @param the sourceObj object type * @return the source field value */ @@ -437,13 +459,12 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie /** * It executes the lambda function defined to the field. - * @param field The field on which the transformation should be applied. + * @param breadcrumb The full field path on which the transformation should be applied. * @param fieldValue The field value. - * @param breadCrumb * @return the transformed field. */ - private Object getTransformedField(final Field field, final Object fieldValue, String breadCrumb) { - return ofNullable(transformerSettings.getFieldsTransformers().get(breadCrumb)) + private Object getTransformedField(final String breadcrumb, final Object fieldValue) { + return ofNullable(transformerSettings.getFieldsTransformers().get(breadcrumb)) .map(fieldTransformer -> fieldTransformer.apply(fieldValue)) .orElse(fieldValue); } @@ -453,17 +474,18 @@ private Object getTransformedField(final Field field, final Object fieldValue, S * @param targetClass the destination object class * @param field The field for which the value has to be retrieved * @param fieldValue The current object value. + * @param breadcrumb The full field path on which the transformation should be applied * @param the target object type * @return the field value * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ @SuppressWarnings("unchecked") - private Object getFieldValue(final Class targetClass, final Field field, final Object fieldValue, final String breadCrumb) { + private Object getFieldValue(final Class targetClass, final Field field, final Object fieldValue, final String breadcrumb) { return getPopulator(field.getType(), fieldValue.getClass(), this) .map(populator -> populator.getPopulatedObject(targetClass, field.getName(), fieldValue)) .orElseGet(() -> // recursively inject object - transform(fieldValue, field.getType(), breadCrumb) + transform(fieldValue, field.getType(), breadcrumb) ); } diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooBreadcrumb.java b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooBreadcrumb.java deleted file mode 100644 index c02d747ab..000000000 --- a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooBreadcrumb.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (C) 2019 Expedia Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import lombok.Getter; -import lombok.Setter; - -import java.math.BigInteger; -import java.util.List; - -/** - * Sample mutable object. - */ -@Getter -@Setter -public class MutableToFooBreadcrumb { - private String name; - private MutableToSubFoo nestedObject; -} diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index bcd505545..563b7674a 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -48,7 +48,6 @@ import java.util.Optional; import java.util.stream.IntStream; -import com.hotels.beans.sample.mutable.MutableToFooBreadcrumb; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -410,17 +409,24 @@ public void testMutableBeanIsCorrectlyCopied() { } /** - * Test mutable beans are correctly copied. + * Test that a given field transformer function is applied only to a specific field even if there are other ones with same name. */ @Test - public void testMutableBeanIsCorrectlyCopied2() { + public void testFieldTransformationIsAppliedOnlyToASpecificField() { //GIVEN + String namePrefix = "prefix-"; + String expectedTransformedName = namePrefix + fromFoo.getNestedObject().getName(); + FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", val -> namePrefix + val); //WHEN - MutableToFooBreadcrumb actual = underTest.transform(fromFoo, MutableToFooBreadcrumb.class); + MutableToFoo actual = underTest + .withFieldTransformer(nameTransformer) + .transform(fromFoo, MutableToFoo.class); //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertEquals(fromFoo.getName(), actual.getName()); + assertEquals(expectedTransformedName, actual.getNestedObject().getName()); + underTest.resetFieldsTransformer(); } /** @@ -637,9 +643,10 @@ public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { underTest.withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); //WHEN - final Method getConstructorValuesFromFieldsMethod = underTest.getClass().getDeclaredMethod(GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME, Object.class, Class.class); + final Method getConstructorValuesFromFieldsMethod = + underTest.getClass().getDeclaredMethod(GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME, Object.class, Class.class, String.class); getConstructorValuesFromFieldsMethod.setAccessible(true); - Object[] actual = (Object[]) getConstructorValuesFromFieldsMethod.invoke(underTest, fromFooAdvFields, ImmutableToFooAdvFields.class); + Object[] actual = (Object[]) getConstructorValuesFromFieldsMethod.invoke(underTest, fromFooAdvFields, ImmutableToFooAdvFields.class, ""); //THEN assertNotNull(actual); From 9c4a0ad9ec0de7771252200425a1e356d5bd45dc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 19 Feb 2019 00:26:39 +0100 Subject: [PATCH 0251/1786] improved method performance --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index d7fe33f66..fc0142a54 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -429,7 +429,10 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN * @return the updated breadcrumb */ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { - return (nonNull(breadcrumb) ? (breadcrumb + DOT.getSymbol()) : "") + fieldName; + if (breadcrumb != null) { + return breadcrumb + DOT.getSymbol() + fieldName; + } + return fieldName; } /** From da7d708fe09ef2d54e46bf171c9b99d6fe15aa60 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 19 Feb 2019 08:38:12 +0100 Subject: [PATCH 0252/1786] writing testing sample --- docs/site/markdown/transformer/testing.md | 25 +++---- .../beans/transformer/TransformerImpl.java | 52 +++------------ .../hotels/beans/utils/ValidationUtils.java | 65 ++++++++++++++++++- 3 files changed, 84 insertions(+), 58 deletions(-) diff --git a/docs/site/markdown/transformer/testing.md b/docs/site/markdown/transformer/testing.md index c2f31cf08..e28dbfef9 100644 --- a/docs/site/markdown/transformer/testing.md +++ b/docs/site/markdown/transformer/testing.md @@ -14,7 +14,7 @@ extent to which the component or system under test: * can be installed and run in its intended environments * achieves the general result its stakeholders desire. -This page will show how to test BULL into a simple project. All the examples utilizes [JUnit](https://github.com/junit-team) +This page will show how to test BULL into a simple project. All the examples utilizes [JUnit](https://github.com/junit-team) and [Mockito](https://site.mockito.org/). The Java Bean transformation function can be tested in two different ways that depends on the following scenarios: @@ -31,15 +31,14 @@ Assuming that our source object and our destination object have been defined as @AllArgsConstructor @AllArgsConstructor @Getter @Getter @Setter @Setter -public class FromFoo { public class ToFoo { - private final String name; @NotNull - private final BigInteger id; public BigInteger id; - private final List subBeanList; private final String name; +public class SampleRequest { public class DestObject { + private final BigInteger x; @NotNull + private final BigInteger y; private BigInteger x; + private final List subBeanList; private final BigInteger y; private List list; private final List list; private final FromSubBean subObject; private final List nestedObjectList; - private ImmutableToSubFoo nestedObject; -} - } + +} } ~~~ And this is the class containing the `BeanUtils` library: ~~~Java @@ -53,9 +52,14 @@ public class SampleClass { this.beanUtils = new BeanUtils(); } - public SampleResponse doSomething(final SampleRequest request) { + public BigInteger doSomething(final SampleRequest request) { final Transformer beanTransformer = beanUtils.getTransformer(); - return beanTransformer.transform(request, SampleResponse.class); + DestObject destObject = beanTransformer.transform(request, DestObject.class); + return multiplyValues(destObject.getX(), destObject.getY()); + } + + private BigInteger multiplyValues(final BigInteger x, final BigInteger y) { + return x * y; } } ~~~ @@ -89,7 +93,6 @@ public class SampleClassTest { @Before public void beforeMethod() { initMocks(this); - ReflectionTestUtils.setField(underTest, "beanUtils", beanUtils); } /** diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 5ca6833fd..f572e3a4b 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -23,13 +23,8 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; -import static javax.validation.Validation.buildDefaultValidatorFactory; - -import static org.apache.commons.lang3.StringUtils.SPACE; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static com.hotels.beans.constant.Punctuation.DOT; -import static com.hotels.beans.constant.Punctuation.SEMICOLON; import static com.hotels.beans.constant.Punctuation.COMMA; import static com.hotels.beans.constant.Punctuation.LPAREN; import static com.hotels.beans.constant.Punctuation.RPAREN; @@ -46,12 +41,8 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Set; import java.util.function.Function; -import javax.validation.ConstraintViolation; -import javax.validation.Validator; - import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.cache.CacheManager; import com.hotels.beans.constant.ClassType; @@ -61,6 +52,7 @@ import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; +import com.hotels.beans.utils.ValidationUtils; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. @@ -77,6 +69,11 @@ public class TransformerImpl implements Transformer { */ private final ClassUtils classUtils; + /** + * Class reflection utils class {@link ValidationUtils}. + */ + private final ValidationUtils validationUtils; + /** * CacheManager class {@link CacheManager}. */ @@ -93,6 +90,7 @@ public class TransformerImpl implements Transformer { public TransformerImpl() { this.reflectionUtils = new ReflectionUtils(); this.classUtils = new ClassUtils(); + this.validationUtils = new ValidationUtils(); this.transformerSettings = new TransformerSettings(); this.cacheManager = getCacheManager("transformer"); } @@ -189,7 +187,7 @@ public final K transform(final T sourceObj, final Class targ injectNotFinalFields(sourceObj, k); } } - validate(k); + validationUtils.validate(k); return k; } @@ -456,38 +454,4 @@ private Object getFieldValue(final Class targetClass, final Field field, transform(fieldValue, field.getType()) ); } - - /** - * Checks if an object is valid. - * @param k the object to check - * @param the object class - * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails - */ - private void validate(final K k) { - final Set> constraintViolations = getValidator().validate(k); - if (!constraintViolations.isEmpty()) { - final String errors = constraintViolations.stream() - .map(cv -> cv.getRootBeanClass().getCanonicalName() - + DOT.getSymbol() - + cv.getPropertyPath() - + SPACE - + cv.getMessage()) - .collect(joining(SEMICOLON.getSymbol())); - throw new InvalidBeanException(errors); - } - } - - /** - * Creates the validator. - * @return a {@link Validator} instance. - */ - private Validator getValidator() { - String cacheKey = "BeanValidator"; - return ofNullable(cacheManager.getFromCache(cacheKey, Validator.class)) - .orElseGet(() -> { - Validator validator = buildDefaultValidatorFactory().getValidator(); - cacheManager.cacheObject(cacheKey, validator); - return validator; - }); - } } diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java index dda3e92a2..f1a1d4b36 100644 --- a/src/main/java/com/hotels/beans/utils/ValidationUtils.java +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -17,16 +17,41 @@ package com.hotels.beans.utils; import static java.util.Objects.isNull; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.joining; -import static lombok.AccessLevel.PRIVATE; +import static javax.validation.Validation.buildDefaultValidatorFactory; -import lombok.NoArgsConstructor; +import static org.apache.commons.lang3.StringUtils.SPACE; + +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.constant.Punctuation.SEMICOLON; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validator; + +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.error.InvalidBeanException; /** * Validation utils for Class objects. */ -@NoArgsConstructor(access = PRIVATE) public class ValidationUtils { + /** + * CacheManager class {@link CacheManager}. + */ + private final CacheManager cacheManager; + + /** + * Default constructor. + */ + public ValidationUtils() { + this.cacheManager = getCacheManager("validationUtils"); + } + /** * Validate that the specified argument is not {@code null}; * otherwise throws an {@link IllegalArgumentException} with the specified message. @@ -53,4 +78,38 @@ public static void notNull(final T object, final String message) { throw new IllegalArgumentException(message); } } + + /** + * Checks if an object is valid. + * @param k the object to check + * @param the object class + * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails + */ + public final void validate(final K k) { + final Set> constraintViolations = getValidator().validate(k); + if (!constraintViolations.isEmpty()) { + final String errors = constraintViolations.stream() + .map(cv -> cv.getRootBeanClass().getCanonicalName() + + DOT.getSymbol() + + cv.getPropertyPath() + + SPACE + + cv.getMessage()) + .collect(joining(SEMICOLON.getSymbol())); + throw new InvalidBeanException(errors); + } + } + + /** + * Creates the validator. + * @return a {@link Validator} instance. + */ + private Validator getValidator() { + String cacheKey = "BeanValidator"; + return ofNullable(cacheManager.getFromCache(cacheKey, Validator.class)) + .orElseGet(() -> { + Validator validator = buildDefaultValidatorFactory().getValidator(); + cacheManager.cacheObject(cacheKey, validator); + return validator; + }); + } } From 2fc29d281413ab61a77dd144521d7be3c2493c97 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 19 Feb 2019 09:25:56 +0100 Subject: [PATCH 0253/1786] Added samples for transformation function applied only on a nested object field --- README.md | 105 +++++++++++------- docs/site/markdown/transformer/samples.md | 31 +++++- .../beans/transformer/TransformerImpl.java | 5 +- .../hotels/beans/utils/ValidationUtils.java | 2 +- .../beans/transformer/TransformerTest.java | 2 +- .../beans/utils/ReflectionUtilsTest.java | 4 +- 6 files changed, 104 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 73d65296c..66b132755 100644 --- a/README.md +++ b/README.md @@ -55,24 +55,24 @@ mvn clean install -P relaxed * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. -## Transformation samples + +# Transformation samples ### Simple case: ~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +@Setter @Setter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; private final List subBeanList; private final String name; private List list; private final List list; - private final FromSubBean subObject; private final List subBeanList; + private final FromSubBean subObject; private final List nestedObjectList; private ImmutableToSubFoo nestedObject; - - // constructors... // constructors... - - // getters and setters... // getters and setters... - -} } +} + } ~~~ And one line code as: ~~~Java @@ -90,12 +90,23 @@ public class FromBean { public class ToBean private final List subBeanList; private final List subBeanList; private final List list; private final List list; private final FromSubBean subObject; private final ToSubBean subObject; - - // all args constructor // all args constructor - - // getters... // getters... - -} } + + // getters and setters... + public ToBean(final String differentName, + final int id, +} final List subBeanList, + final List list, + final ToSubBean subObject) { + this.differentName = differentName; + this.id = id; + this.subBeanList = subBeanList; + this.list = list; + this.subObject = subObject; + } + + // getters and setters... + + } ~~~ And one line code as: @@ -151,12 +162,11 @@ public class FromBean { public class ToBean private final List subBeanList; private final List subBeanList; private final List list; private final List list; private final FromSubBean subObject; private final ToSubBean subObject; - - // all args constructor - // getters... + + // getters and setters... public ToBean(@ConstructorArg("name") final String differentName, -} @ConstructorArg("id") final int id, - @ConstructorArg("subBeanList") final List subBeanList, + @ConstructorArg("id") final int id, +} @ConstructorArg("subBeanList") final List subBeanList, @ConstructorArg(fieldName ="list") final List list, @ConstructorArg("subObject") final ToSubBean subObject) { this.differentName = differentName; @@ -166,7 +176,7 @@ public class FromBean { public class ToBean this.subObject = subObject; } - // getters... + // getters and setters... } ~~~ @@ -178,6 +188,9 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); ### Different field names and types applying transformation through lambda function: ~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +@Setter @Setter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger identifier; @@ -186,12 +199,8 @@ public class FromBean { public class ToBean private final FromSubBean subObject; private final List nestedObjectList; private final String locale; private final Locale locale; private ImmutableToSubFoo nestedObject; - - // constructors... // constructors... - - // getters and setters... // getters and setters... - -} } +} + } ~~~ ~~~Java @@ -215,12 +224,7 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final String name; private String notExistingField; // this will be null and no exceptions will be raised - - // constructors... // constructors... - - // getters... // getters and setters... - -} } +} } ~~~ And one line code as: ~~~Java @@ -240,11 +244,7 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final String name; private String notExistingField; // this will have value: sampleVal - - // all args constructor // constructors... - - // getters... // getters and setters... -} } +} } ~~~ And one line code as: ~~~Java @@ -254,6 +254,35 @@ ToBean toBean = beanUtils.getTransformer() .transform(fromBean, ToBean.class); ~~~ +### Apply a transformation function on a field contained in a nested object: + +This example shows of a lambda transformation function can be applied on a nested object field. + +Given: + +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromBean { public class ToBean { + private final String name; private final String name; + private final FromSubBean nestedObject; private final ToSubBean nestedObject; +} } +~~~ +and +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromSubBean { public class ToSubBean { + private final String name; private final String name; + private final long index; private final long index; +} } +~~~ +Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +follow: +~~~Java +FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); +~~~ + ### Static transformer function: ~~~Java @@ -266,7 +295,7 @@ Function transformerFunction = BeanUtils.ge .map(transformerFunction) .collect(Collectors.toList()); ~~~ - + More sample beans can be found in the test package: `com.hotels.beans.sample` ## Third party library comparison diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 2982197a5..41cf8781b 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -1,5 +1,5 @@ - Bean Transformer + Samples # Transformation samples @@ -200,6 +200,35 @@ ToBean toBean = beanUtils.getTransformer() .transform(fromBean, ToBean.class); ~~~ +### Apply a transformation function on a field contained in a nested object: + +This example shows of a lambda transformation function can be applied on a nested object field. + +Given: + +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromBean { public class ToBean { + private final String name; private final String name; + private final FromSubBean nestedObject; private final ToSubBean nestedObject; +} } +~~~ +and +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromSubBean { public class ToSubBean { + private final String name; private final String name; + private final long index; private final long index; +} } +~~~ +Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +follow: +~~~Java +FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); +~~~ + ### Static transformer function: ~~~Java diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index fc0142a54..7b2e2b755 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -429,10 +429,11 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN * @return the updated breadcrumb */ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { + String res = ""; if (breadcrumb != null) { - return breadcrumb + DOT.getSymbol() + fieldName; + res = breadcrumb + DOT.getSymbol(); } - return fieldName; + return res + fieldName; } /** diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java index dda3e92a2..50d968956 100644 --- a/src/main/java/com/hotels/beans/utils/ValidationUtils.java +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -26,7 +26,7 @@ * Validation utils for Class objects. */ @NoArgsConstructor(access = PRIVATE) -public class ValidationUtils { +public final class ValidationUtils { /** * Validate that the specified argument is not {@code null}; * otherwise throws an {@link IllegalArgumentException} with the specified message. diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 563b7674a..247e4518e 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -288,7 +288,7 @@ public void testTransformationWithCompositeFieldNameWorksEvenWithNullObjects() { //THEN assertEquals(fromFooWithNullProperties.getName(), actual.getName()); assertEquals(fromFooWithNullProperties.getId(), actual.getId()); - assertEquals(fromFooWithNullProperties.getNestedObject(), actual.getPhoneNumbers()); + assertNull(actual.getPhoneNumbers()); underTest.resetFieldsMapping(); } diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index 9b29fb9d5..a152ac5c7 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -184,12 +184,12 @@ public void testGetGetterMethodPrefixWorksAsExpected() throws Exception { // WHEN String stringGetterMethodPrefix = (String) method.invoke(underTest, String.class); String booleanGetterMethodPrefix = (String) method.invoke(underTest, Boolean.class); - String primitiveBbooleanGetterMethodPrefix = (String) method.invoke(underTest, booleanField.getType()); + String primitiveBooleanGetterMethodPrefix = (String) method.invoke(underTest, booleanField.getType()); // THEN assertEquals(GET.getPrefix(), stringGetterMethodPrefix); assertEquals(IS.getPrefix(), booleanGetterMethodPrefix); - assertEquals(IS.getPrefix(), primitiveBbooleanGetterMethodPrefix); + assertEquals(IS.getPrefix(), primitiveBooleanGetterMethodPrefix); } /** From 1a5dd49e780a35cb5738dc073714fc8fb5266ac7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 19 Feb 2019 09:50:53 +0100 Subject: [PATCH 0254/1786] minor: renamed variable --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 7b2e2b755..2ae97adc2 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -402,7 +402,7 @@ private Object getFieldValue(final T sourceObj, final Class targetClas */ private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { Object fieldValue = null; - String realBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); + String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); if (isNotEmpty(sourceFieldName)) { boolean primitiveType = classUtils.isPrimitiveType(field.getType()); boolean isFieldTransformerDefined = transformerSettings.getFieldsTransformers().containsKey(field.getName()); @@ -413,13 +413,13 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(field.getType()); if ((notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass())) && !isFieldTransformerDefined) { - fieldValue = getFieldValue(targetClass, field, fieldValue, realBreadcrumb); + fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); } } else if (primitiveType) { fieldValue = defaultValue(field.getType()); // assign the default value } } - return getTransformedField(realBreadcrumb, fieldValue); + return getTransformedField(fieldBreadcrumb, fieldValue); } /** From 2090ea4322f969e25a60f25747be4a2320a44b9d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 19 Feb 2019 10:08:12 +0100 Subject: [PATCH 0255/1786] Updated changelog --- CHANGELOG.md | 5 +++++ README.md | 1 - .../java/com/hotels/beans/transformer/TransformerImpl.java | 6 +----- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 600719fa1..5eaded4fb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.1.4] TBD +#### Added +* Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/HotelsDotCom/bull/issues/27)). +* Added samples and tests for the above functionality + ### [1.1.3] 2019.17 #### Added * Added static transformation functionality (see: [Issue 25](https://github.com/HotelsDotCom/bull/issues/25)). diff --git a/README.md b/README.md index 66b132755..4f5ff2393 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,6 @@ mvn clean install -P relaxed * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. - # Transformation samples ### Simple case: diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 2ae97adc2..c6ffa83d5 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -429,11 +429,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN * @return the updated breadcrumb */ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { - String res = ""; - if (breadcrumb != null) { - res = breadcrumb + DOT.getSymbol(); - } - return res + fieldName; + return (breadcrumb != null ? breadcrumb + DOT.getSymbol() : "") + fieldName; } /** From f9df0be575a299fb33220141424a9a30956c0eea Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 07:30:25 +0100 Subject: [PATCH 0256/1786] Integrated possibility to apply the transformation on all fields matching with the given name, without evaluating the full path --- .../com/hotels/beans/transformer/TransformerImpl.java | 8 +++++--- .../hotels/beans/transformer/TransformerSettings.java | 9 ++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index c6ffa83d5..f15fcc08e 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -419,7 +419,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN fieldValue = defaultValue(field.getType()); // assign the default value } } - return getTransformedField(fieldBreadcrumb, fieldValue); + return getTransformedField(field, fieldBreadcrumb, fieldValue); } /** @@ -459,12 +459,14 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie /** * It executes the lambda function defined to the field. + * @param field The field on which the transformation should be applied. * @param breadcrumb The full field path on which the transformation should be applied. * @param fieldValue The field value. * @return the transformed field. */ - private Object getTransformedField(final String breadcrumb, final Object fieldValue) { - return ofNullable(transformerSettings.getFieldsTransformers().get(breadcrumb)) + private Object getTransformedField(final Field field, final String breadcrumb, final Object fieldValue) { + String fieldName = transformerSettings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; + return ofNullable(transformerSettings.getFieldsTransformers().get(fieldName)) .map(fieldTransformer -> fieldTransformer.apply(fieldValue)) .orElse(fieldValue); } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 2dc24365c..3854e395a 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -28,7 +28,7 @@ * It contains: * 1) The field name mapping * 2) The lambda function to apply on a field. - * 2) Other configurations. + * 3) Other configurations. */ @Getter final class TransformerSettings { @@ -53,4 +53,11 @@ final class TransformerSettings { */ @Setter private boolean setDefaultValue; + + /** + * It allows to apply a transformation to all fields matching with the provided name without using their whole path. + * If set to true the transformation function is applied to all fields without evaluating their full path. + */ + @Setter + private boolean flatFieldNameTransformation; } From 35e43673ce7dc55a2b941edb46721bba1d2126c6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 09:59:08 +0100 Subject: [PATCH 0257/1786] - Added an abstract class that centralizes all methods that would be common for any Transformer implementation - Reduced number of external dependencies - Improved documentation --- CHANGELOG.md | 1 + README.md | 71 +++++- docs/site/markdown/transformer/samples.md | 64 ++++- pom.xml | 7 - .../transformer/AbstractTransformer.java | 173 ++++++++++++++ .../hotels/beans/transformer/Transformer.java | 9 + .../beans/transformer/TransformerImpl.java | 218 +++--------------- .../transformer/TransformerSettings.java | 2 +- .../hotels/beans/utils/ReflectionUtils.java | 2 +- .../hotels/beans/utils/ValidationUtils.java | 67 +++++- .../beans/transformer/TransformerTest.java | 24 +- 11 files changed, 416 insertions(+), 222 deletions(-) create mode 100644 src/main/java/com/hotels/beans/transformer/AbstractTransformer.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eaded4fb..c7d98ec1f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.1.4] TBD #### Added * Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/HotelsDotCom/bull/issues/27)). +* Added possibility to apply a transformation function on all fields matching with the given name without evaluating the full field path. * Added samples and tests for the above functionality ### [1.1.3] 2019.17 diff --git a/README.md b/README.md index 4f5ff2393..74b696b0d 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,16 @@ ## Bean Utils Light Library -This BeanUtils library is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. +BULL is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. ## Start using -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=com.hotels.beans:bean-utils-library)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) +[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bean-utils-library.svg)](http://www.javadoc.io/doc/com.hotels.beans/bean-utils-library) +[![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) + [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) @@ -161,8 +164,9 @@ public class FromBean { public class ToBean private final List subBeanList; private final List subBeanList; private final List list; private final List list; private final FromSubBean subObject; private final ToSubBean subObject; - - // getters and setters... + + // all args constructor + // getters... public ToBean(@ConstructorArg("name") final String differentName, @ConstructorArg("id") final int id, } @ConstructorArg("subBeanList") final List subBeanList, @@ -175,7 +179,7 @@ public class FromBean { public class ToBean this.subObject = subObject; } - // getters and setters... + // getters... } ~~~ @@ -198,8 +202,12 @@ public class FromBean { public class ToBean private final FromSubBean subObject; private final List nestedObjectList; private final String locale; private final Locale locale; private ImmutableToSubFoo nestedObject; -} - } + + // constructors... // constructors... + + // getters and setters... // getters and setters... + +} } ~~~ ~~~Java @@ -223,7 +231,12 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final String name; private String notExistingField; // this will be null and no exceptions will be raised -} } + + // constructors... // constructors... + + // getters... // getters and setters... + +} } ~~~ And one line code as: ~~~Java @@ -243,7 +256,11 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final String name; private String notExistingField; // this will have value: sampleVal -} } + + // all args constructor // constructors... + + // getters... // getters and setters... +} } ~~~ And one line code as: ~~~Java @@ -280,6 +297,42 @@ Assuming that the lambda transformation function should be applied only to field follow: ~~~Java FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); +ToBean toBean = beanUtils.getTransformer() + .withFieldTransformer(nameTransformer) + .transform(fromBean, ToBean.class); +~~~ + +### Apply a transformation function on all fields matching with the given one: + +This example shows of a lambda transformation function can be applied on all fields matching with the given one independently from their position. + +Given: + +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromBean { public class ToBean { + private final String name; private final String name; + private final FromSubBean nestedObject; private final ToSubBean nestedObject; +} } +~~~ +and +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromSubBean { public class ToSubBean { + private final String name; private final String name; + private final long index; private final long index; +} } +~~~ +Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +follow: +~~~Java +FieldTransformer nameTransformer = new FieldTransformer<>("name", StringUtils::capitalize); +ToBean toBean = beanUtils.getTransformer() + .setFlatFieldNameTransformation(true) + .withFieldTransformer(nameTransformer) + .transform(fromBean, ToBean.class); ~~~ ### Static transformer function: diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 41cf8781b..2c1d98727 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -108,8 +108,9 @@ public class FromBean { public class ToBean private final List subBeanList; private final List subBeanList; private final List list; private final List list; private final FromSubBean subObject; private final ToSubBean subObject; - - // getters and setters... + + // all args constructor + // getters... public ToBean(@ConstructorArg("name") final String differentName, @ConstructorArg("id") final int id, } @ConstructorArg("subBeanList") final List subBeanList, @@ -122,7 +123,7 @@ public class FromBean { public class ToBean this.subObject = subObject; } - // getters and setters... + // getters... } ~~~ @@ -145,8 +146,12 @@ public class FromBean { public class ToBean private final FromSubBean subObject; private final List nestedObjectList; private final String locale; private final Locale locale; private ImmutableToSubFoo nestedObject; -} - } + + // constructors... // constructors... + + // getters and setters... // getters and setters... + +} } ~~~ ~~~Java @@ -170,7 +175,12 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final String name; private String notExistingField; // this will be null and no exceptions will be raised -} } + + // constructors... // constructors... + + // getters... // getters and setters... + +} } ~~~ And one line code as: ~~~Java @@ -190,7 +200,11 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final String name; private String notExistingField; // this will have value: sampleVal -} } + + // all args constructor // constructors... + + // getters... // getters and setters... +} } ~~~ And one line code as: ~~~Java @@ -227,6 +241,42 @@ Assuming that the lambda transformation function should be applied only to field follow: ~~~Java FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); +ToBean toBean = beanUtils.getTransformer() + .withFieldTransformer(nameTransformer) + .transform(fromBean, ToBean.class); +~~~ + +### Apply a transformation function on all fields matching with the given one: + +This example shows of a lambda transformation function can be applied on all fields matching with the given one independently from their position. + +Given: + +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromBean { public class ToBean { + private final String name; private final String name; + private final FromSubBean nestedObject; private final ToSubBean nestedObject; +} } +~~~ +and +~~~Java +@AllArgsConstructor @AllArgsConstructor +@Getter @Getter +public class FromSubBean { public class ToSubBean { + private final String name; private final String name; + private final long index; private final long index; +} } +~~~ +Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +follow: +~~~Java +FieldTransformer nameTransformer = new FieldTransformer<>("name", StringUtils::capitalize); +ToBean toBean = beanUtils.getTransformer() + .setFlatFieldNameTransformation(true) + .withFieldTransformer(nameTransformer) + .transform(fromBean, ToBean.class); ~~~ ### Static transformer function: diff --git a/pom.xml b/pom.xml index 2f6a86866..6e41c30bd 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,6 @@ 3.11.0 2.1.2.RELEASE 1.18.4 - 1.3 3.8.1 0.11 2.8.5 @@ -82,11 +81,6 @@ commons-lang3 ${apache.commons-lang3.version} - - org.apache.commons - commons-text - ${apache.common.version} - javax.validation @@ -204,7 +198,6 @@ **/logback*.xml **/banner.txt **/*.yml - **/application/** **/stats/** diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java new file mode 100644 index 000000000..6bd2d9c7b --- /dev/null +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -0,0 +1,173 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import static com.hotels.beans.utils.ValidationUtils.notNull; + +import java.util.Map; +import java.util.function.Function; + +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.cache.CacheManagerFactory; +import com.hotels.beans.model.FieldMapping; +import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.utils.ClassUtils; +import com.hotels.beans.utils.ReflectionUtils; +import com.hotels.beans.utils.ValidationUtils; + +import lombok.Getter; + +/** + * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. + * Contains all method implementation that will be common to any {@link Transformer} implementation. + */ +@Getter +abstract class AbstractTransformer implements Transformer { + /** + * Reflection utils class {@link ReflectionUtils}. + */ + private final ReflectionUtils reflectionUtils; + + /** + * Class reflection utils class {@link ClassUtils}. + */ + private final ClassUtils classUtils; + + /** + * Validation utils class {@link ValidationUtils}. + */ + private final ValidationUtils validationUtils; + + /** + * CacheManager class {@link CacheManager}. + */ + private final CacheManager cacheManager; + + /** + * Contains both the field name mapping and the lambda function to be applied on fields. + */ + private final TransformerSettings transformerSettings; + + /** + * Default constructor. + */ + AbstractTransformer() { + this.reflectionUtils = new ReflectionUtils(); + this.classUtils = new ClassUtils(); + this.validationUtils = new ValidationUtils(); + this.transformerSettings = new TransformerSettings(); + this.cacheManager = CacheManagerFactory.getCacheManager("transformer"); + } + + /** + * {@inheritDoc} + */ + @Override + public final Transformer withFieldMapping(final FieldMapping... fieldMapping) { + final Map fieldsNameMapping = transformerSettings.getFieldsNameMapping(); + for (FieldMapping mapping : fieldMapping) { + fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); + } + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public final void removeFieldMapping(final String destFieldName) { + notNull(destFieldName, "The field name for which the mapping has to be removed cannot be null!"); + transformerSettings.getFieldsNameMapping().remove(destFieldName); + } + + /** + * {@inheritDoc} + */ + @Override + public final void resetFieldsMapping() { + transformerSettings.getFieldsNameMapping().clear(); + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public final Transformer withFieldTransformer(final FieldTransformer... fieldTransformer) { + Map> fieldsTransformers = transformerSettings.getFieldsTransformers(); + for (FieldTransformer transformer : fieldTransformer) { + fieldsTransformers.put(transformer.getDestFieldName(), transformer.getTransformerFunction()); + } + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public final void removeFieldTransformer(final String destFieldName) { + notNull(destFieldName, "The field name for which the transformer function has to be removed cannot be null!"); + transformerSettings.getFieldsTransformers().remove(destFieldName); + } + + /** + * {@inheritDoc} + */ + @Override + public final void resetFieldsTransformer() { + transformerSettings.getFieldsTransformers().clear(); + } + + /** + * {@inheritDoc} + */ + @Override + public final Transformer setDefaultValueForMissingField(final boolean useDefaultValue) { + transformerSettings.setSetDefaultValue(useDefaultValue); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public final Transformer setFlatFieldNameTransformation(final boolean useFlatTransformation) { + transformerSettings.setFlatFieldNameTransformation(useFlatTransformation); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public final K transform(final T sourceObj, final Class targetClass) { + notNull(sourceObj, "The object to copy cannot be null!"); + notNull(targetClass, "The destination class cannot be null!"); + return transform(sourceObj, targetClass, null); + } + + /** + * Copies all properties from an object to a new one. + * @param sourceObj the source object + * @param targetClass the destination object class + * @param breadcrumb the full path of the current field starting from his ancestor + * @param the Source object type + * @param the target object type + * @return a copy of the source object into the destination object + */ + protected abstract K transform(T sourceObj, Class targetClass, String breadcrumb); +} diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index 2e47dd4e9..6345cc102 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -79,4 +79,13 @@ public interface Transformer { * @return the {@link Transformer} instance */ Transformer setDefaultValueForMissingField(boolean useDefaultValue); + + /** + * It allows to configure the transformer in order to apply a transformation function on all fields matching the given name without keeping in consideration their full path. + * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. + * @param useFlatTransformation indicates if the transformer function has to be performed on all fields matching the given name without keeping in consideration their full + * path. + * @return the {@link Transformer} instance + */ + Transformer setFlatFieldNameTransformation(boolean useFlatTransformation); } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index f15fcc08e..5abcff366 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -23,170 +23,40 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; -import static javax.validation.Validation.buildDefaultValidatorFactory; - -import static org.apache.commons.lang3.StringUtils.SPACE; import static org.apache.commons.lang3.StringUtils.isNotEmpty; import static com.hotels.beans.constant.Punctuation.DOT; -import static com.hotels.beans.constant.Punctuation.SEMICOLON; import static com.hotels.beans.constant.Punctuation.COMMA; import static com.hotels.beans.constant.Punctuation.LPAREN; import static com.hotels.beans.constant.Punctuation.RPAREN; import static com.hotels.beans.constant.ClassType.MIXED; import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.base.Defaults.defaultValue; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Parameter; import java.util.List; -import java.util.Map; import java.util.Optional; -import java.util.Set; -import java.util.function.Function; - -import javax.validation.ConstraintViolation; -import javax.validation.Validator; import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.cache.CacheManager; import com.hotels.beans.constant.ClassType; import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.error.MissingFieldException; -import com.hotels.beans.model.FieldMapping; -import com.hotels.beans.model.FieldTransformer; -import com.hotels.beans.utils.ClassUtils; -import com.hotels.beans.utils.ReflectionUtils; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * The implementations are provided by BeanUtils. */ -public class TransformerImpl implements Transformer { - /** - * Reflection utils class {@link ReflectionUtils}. - */ - private final ReflectionUtils reflectionUtils; - - /** - * Class reflection utils class {@link ClassUtils}. - */ - private final ClassUtils classUtils; - - /** - * CacheManager class {@link CacheManager}. - */ - private final CacheManager cacheManager; - - /** - * Contains both the field name mapping and the lambda function to be applied on fields. - */ - private final TransformerSettings transformerSettings; - - /** - * Default constructor. - */ - public TransformerImpl() { - this.reflectionUtils = new ReflectionUtils(); - this.classUtils = new ClassUtils(); - this.transformerSettings = new TransformerSettings(); - this.cacheManager = getCacheManager("transformer"); - } - +public class TransformerImpl extends AbstractTransformer { /** * {@inheritDoc} */ @Override - public final Transformer withFieldMapping(final FieldMapping... fieldMapping) { - final Map fieldsNameMapping = transformerSettings.getFieldsNameMapping(); - for (FieldMapping mapping : fieldMapping) { - fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); - } - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public final void removeFieldMapping(final String destFieldName) { - notNull(destFieldName, "The field name for which the mapping has to be removed cannot be null!"); - transformerSettings.getFieldsNameMapping().remove(destFieldName); - } - - /** - * {@inheritDoc} - */ - @Override - public final void resetFieldsMapping() { - transformerSettings.getFieldsNameMapping().clear(); - } - - /** - * {@inheritDoc} - */ - @Override - @SuppressWarnings("unchecked") - public final Transformer withFieldTransformer(final FieldTransformer... fieldTransformer) { - Map> fieldsTransformers = transformerSettings.getFieldsTransformers(); - for (FieldTransformer transformer : fieldTransformer) { - fieldsTransformers.put(transformer.getDestFieldName(), transformer.getTransformerFunction()); - } - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public final void removeFieldTransformer(final String destFieldName) { - notNull(destFieldName, "The field name for which the transformer function has to be removed cannot be null!"); - transformerSettings.getFieldsTransformers().remove(destFieldName); - } - - /** - * {@inheritDoc} - */ - @Override - public final void resetFieldsTransformer() { - transformerSettings.getFieldsTransformers().clear(); - } - - /** - * {@inheritDoc} - */ - @Override - public final Transformer setDefaultValueForMissingField(final boolean useDefaultValue) { - transformerSettings.setSetDefaultValue(useDefaultValue); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public final K transform(final T sourceObj, final Class targetClass) { - notNull(sourceObj, "The object to copy cannot be null!"); - notNull(targetClass, "The destination class cannot be null!"); - return transform(sourceObj, targetClass, null); - } - - /** - * Copies all properties from an object to a new one. - * @param sourceObj the source object - * @param targetClass the destination object class - * @param breadcrumb the full path of the current field starting from his ancestor - * @param the Source object type - * @param the target object type - * @return a copy of the source object into the destination object - */ - private K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { + protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final ClassType classType = classUtils.getClassType(targetClass); + final ClassType classType = getClassUtils().getClassType(targetClass); if (classType.is(MUTABLE)) { try { k = targetClass.getDeclaredConstructor().newInstance(); @@ -197,12 +67,12 @@ private K transform(final T sourceObj, final Class targetCla throw new InvalidBeanException(e.getMessage(), e); } } else { - k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); + k = injectValues(sourceObj, targetClass, getClassUtils().getAllArgsConstructor(targetClass), breadcrumb); if (classType.is(MIXED)) { injectNotFinalFields(sourceObj, k, breadcrumb); } } - validate(k); + getValidationUtils().validate(k); return k; } @@ -257,10 +127,10 @@ private String getFormattedConstructorArgs(final Class targetClass, final */ private boolean canBeInjectedByConstructorParams(final Constructor constructor, final Class targetClass) { final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { - final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() - && (classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class)); - cacheManager.cacheObject(cacheKey, res); + return ofNullable(getCacheManager().getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final boolean res = getClassUtils().getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() + && (getClassUtils().areParameterNamesAvailable(constructor) || getClassUtils().allParameterAnnotatedWith(constructor, ConstructorArg.class)); + getCacheManager().cacheObject(cacheKey, res); return res; }); } @@ -278,19 +148,19 @@ private boolean canBeInjectedByConstructorParams(final Constructor construct * @throws InvalidBeanException {@link InvalidBeanException} if there is an error while retrieving the constructor args parameter */ private Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { - final Parameter[] constructorParameters = classUtils.getConstructorParameters(constructor); + final Parameter[] constructorParameters = getClassUtils().getConstructorParameters(constructor); final Object[] constructorArgsValues = new Object[constructorParameters.length]; range(0, constructorParameters.length) //.parallel() .forEach(i -> { String destFieldName = getDestFieldName(constructorParameters[i], targetClass.getCanonicalName()); if (isNull(destFieldName)) { - constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); + constructorArgsValues[i] = getClassUtils().getDefaultTypeValue(constructorParameters[i].getType()); } else { String sourceFieldName = getSourceFieldName(destFieldName); constructorArgsValues[i] = - ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, classUtils.getDeclaredField(targetClass, destFieldName), breadcrumb)) - .orElse(classUtils.getDefaultTypeValue(constructorParameters[i].getType())); + ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, getClassUtils().getDeclaredField(targetClass, destFieldName), breadcrumb)) + .orElse(getClassUtils().getDefaultTypeValue(constructorParameters[i].getType())); } }); return constructorArgsValues; @@ -311,7 +181,7 @@ private String getSourceFieldName(final Field field) { * @return the source field name. */ private String getSourceFieldName(final String fieldName) { - return ofNullable(transformerSettings.getFieldsNameMapping().get(fieldName)).orElse(fieldName); + return ofNullable(getTransformerSettings().getFieldsNameMapping().get(fieldName)).orElse(fieldName); } /** @@ -322,17 +192,17 @@ private String getSourceFieldName(final String fieldName) { */ private String getDestFieldName(final Parameter constructorParameter, final String declaringClassName) { String cacheKey = "DestFieldName-" + declaringClassName + "-" + constructorParameter.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, String.class)) + return ofNullable(getCacheManager().getFromCache(cacheKey, String.class)) .orElseGet(() -> { String destFieldName; if (constructorParameter.isNamePresent()) { destFieldName = constructorParameter.getName(); } else { - destFieldName = ofNullable(reflectionUtils.getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)) + destFieldName = ofNullable(getReflectionUtils().getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)) .map(ConstructorArg::value) .orElse(null); } - cacheManager.cacheObject(cacheKey, destFieldName); + getCacheManager().cacheObject(cacheKey, destFieldName); return destFieldName; }); } @@ -349,7 +219,7 @@ private String getDestFieldName(final Parameter constructorParameter, final Stri * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ private Object[] getConstructorValuesFromFields(final T sourceObj, final Class targetClass, final String breadcrumb) { - final List declaredFields = classUtils.getDeclaredFields(targetClass, true); + final List declaredFields = getClassUtils().getDeclaredFields(targetClass, true); return declaredFields.stream() .map(field -> getFieldValue(sourceObj, targetClass, field, breadcrumb)) .toArray(Object[]::new); @@ -367,9 +237,9 @@ private Object[] getConstructorValuesFromFields(final T sourceObj, final */ private void injectNotFinalFields(final T sourceObj, final K targetObject, final String breadcrumb) { final Class targetObjectClass = targetObject.getClass(); - classUtils.getNotFinalFields(targetObjectClass, true) + getClassUtils().getNotFinalFields(targetObjectClass, true) //.parallelStream() - .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); + .forEach(field -> getReflectionUtils().setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); } /** @@ -404,13 +274,13 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN Object fieldValue = null; String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); if (isNotEmpty(sourceFieldName)) { - boolean primitiveType = classUtils.isPrimitiveType(field.getType()); - boolean isFieldTransformerDefined = transformerSettings.getFieldsTransformers().containsKey(field.getName()); + boolean primitiveType = getClassUtils().isPrimitiveType(field.getType()); + boolean isFieldTransformerDefined = getTransformerSettings().getFieldsTransformers().containsKey(field.getName()); fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function // defined it recursively evaluate the value - boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(field.getType()); + boolean notPrimitiveAndNotSpecialType = !primitiveType && !getClassUtils().isSpecialType(field.getType()); if ((notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass())) && !isFieldTransformerDefined) { fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); @@ -444,9 +314,9 @@ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { private Object getSourceFieldValue(final T sourceObj, final String sourceFieldName, final Field field, final boolean isFieldTransformerDefined) { Object fieldValue = null; try { - fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); + fieldValue = getReflectionUtils().getFieldValue(sourceObj, sourceFieldName, field.getType()); } catch (MissingFieldException e) { - if (!isFieldTransformerDefined && !transformerSettings.isSetDefaultValue()) { + if (!isFieldTransformerDefined && !getTransformerSettings().isSetDefaultValue()) { throw e; } } catch (Exception e) { @@ -465,8 +335,8 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie * @return the transformed field. */ private Object getTransformedField(final Field field, final String breadcrumb, final Object fieldValue) { - String fieldName = transformerSettings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - return ofNullable(transformerSettings.getFieldsTransformers().get(fieldName)) + String fieldName = getTransformerSettings().isFlatFieldNameTransformation() ? field.getName() : breadcrumb; + return ofNullable(getTransformerSettings().getFieldsTransformers().get(fieldName)) .map(fieldTransformer -> fieldTransformer.apply(fieldValue)) .orElse(fieldValue); } @@ -490,38 +360,4 @@ private Object getFieldValue(final Class targetClass, final Field field, transform(fieldValue, field.getType(), breadcrumb) ); } - - /** - * Checks if an object is valid. - * @param k the object to check - * @param the object class - * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails - */ - private void validate(final K k) { - final Set> constraintViolations = getValidator().validate(k); - if (!constraintViolations.isEmpty()) { - final String errors = constraintViolations.stream() - .map(cv -> cv.getRootBeanClass().getCanonicalName() - + DOT.getSymbol() - + cv.getPropertyPath() - + SPACE - + cv.getMessage()) - .collect(joining(SEMICOLON.getSymbol())); - throw new InvalidBeanException(errors); - } - } - - /** - * Creates the validator. - * @return a {@link Validator} instance. - */ - private Validator getValidator() { - String cacheKey = "BeanValidator"; - return ofNullable(cacheManager.getFromCache(cacheKey, Validator.class)) - .orElseGet(() -> { - Validator validator = buildDefaultValidatorFactory().getValidator(); - cacheManager.cacheObject(cacheKey, validator); - return validator; - }); - } } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 3854e395a..051c718dc 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -56,7 +56,7 @@ final class TransformerSettings { /** * It allows to apply a transformation to all fields matching with the provided name without using their whole path. - * If set to true the transformation function is applied to all fields without evaluating their full path. + * If set to true the transformation function is applied to all fields that have a name matching with the given one without evaluating their full path. */ @Setter private boolean flatFieldNameTransformation; diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 108fbbd66..b606c8f5d 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -21,7 +21,7 @@ import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; -import static org.apache.commons.text.WordUtils.capitalize; +import static org.apache.commons.lang3.StringUtils.capitalize; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.constant.MethodPrefix.GET; diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java index 50d968956..f1a1d4b36 100644 --- a/src/main/java/com/hotels/beans/utils/ValidationUtils.java +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -17,16 +17,41 @@ package com.hotels.beans.utils; import static java.util.Objects.isNull; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.joining; -import static lombok.AccessLevel.PRIVATE; +import static javax.validation.Validation.buildDefaultValidatorFactory; -import lombok.NoArgsConstructor; +import static org.apache.commons.lang3.StringUtils.SPACE; + +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.constant.Punctuation.SEMICOLON; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validator; + +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.error.InvalidBeanException; /** * Validation utils for Class objects. */ -@NoArgsConstructor(access = PRIVATE) -public final class ValidationUtils { +public class ValidationUtils { + /** + * CacheManager class {@link CacheManager}. + */ + private final CacheManager cacheManager; + + /** + * Default constructor. + */ + public ValidationUtils() { + this.cacheManager = getCacheManager("validationUtils"); + } + /** * Validate that the specified argument is not {@code null}; * otherwise throws an {@link IllegalArgumentException} with the specified message. @@ -53,4 +78,38 @@ public static void notNull(final T object, final String message) { throw new IllegalArgumentException(message); } } + + /** + * Checks if an object is valid. + * @param k the object to check + * @param the object class + * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails + */ + public final void validate(final K k) { + final Set> constraintViolations = getValidator().validate(k); + if (!constraintViolations.isEmpty()) { + final String errors = constraintViolations.stream() + .map(cv -> cv.getRootBeanClass().getCanonicalName() + + DOT.getSymbol() + + cv.getPropertyPath() + + SPACE + + cv.getMessage()) + .collect(joining(SEMICOLON.getSymbol())); + throw new InvalidBeanException(errors); + } + } + + /** + * Creates the validator. + * @return a {@link Validator} instance. + */ + private Validator getValidator() { + String cacheKey = "BeanValidator"; + return ofNullable(cacheManager.getFromCache(cacheKey, Validator.class)) + .orElseGet(() -> { + Validator validator = buildDefaultValidatorFactory().getValidator(); + cacheManager.cacheObject(cacheKey, validator); + return validator; + }); + } } diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 247e4518e..3f2f0348b 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -415,7 +415,6 @@ public void testMutableBeanIsCorrectlyCopied() { public void testFieldTransformationIsAppliedOnlyToASpecificField() { //GIVEN String namePrefix = "prefix-"; - String expectedTransformedName = namePrefix + fromFoo.getNestedObject().getName(); FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", val -> namePrefix + val); //WHEN @@ -425,7 +424,28 @@ public void testFieldTransformationIsAppliedOnlyToASpecificField() { //THEN assertEquals(fromFoo.getName(), actual.getName()); - assertEquals(expectedTransformedName, actual.getNestedObject().getName()); + assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); + underTest.resetFieldsTransformer(); + } + + /** + * Test that a given field transformer function is applied to all field matching the given name when {@code flatFieldNameTransformation} is set to true. + */ + @Test + public void testFieldTransformationIsAppliedToAllMatchingFields() { + //GIVEN + String namePrefix = "prefix-"; + FieldTransformer nameTransformer = new FieldTransformer<>("name", val -> namePrefix + val); + + //WHEN + MutableToFoo actual = underTest + .setFlatFieldNameTransformation(true) + .withFieldTransformer(nameTransformer) + .transform(fromFoo, MutableToFoo.class); + + //THEN + assertEquals(namePrefix + fromFoo.getName(), actual.getName()); + assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); underTest.resetFieldsTransformer(); } From 1d2dfbf2dc2301dea4151099dc04e5db3b56aed8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 13:57:39 +0100 Subject: [PATCH 0258/1786] Added mvn setting profile for sonatype --- config/travis/mvn-settings.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index f83952c5c..c7dd98343 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -5,6 +5,16 @@ ${env.OSSRH_USERNAME} ${env.OSSRH_PASSWORD} + + sonatype-nexus-staging + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + + + sonatype-nexus-snapshots + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + ${github_server_id} From e94374c9e497e56c47f5bbf4006777b86fd8d87b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 13:59:15 +0100 Subject: [PATCH 0259/1786] Added sonatype maven profile into settings --- config/travis/mvn-settings.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index f83952c5c..c7dd98343 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -5,6 +5,16 @@ ${env.OSSRH_USERNAME} ${env.OSSRH_PASSWORD} + + sonatype-nexus-staging + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + + + sonatype-nexus-snapshots + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + ${github_server_id} From e1bf4d5e3a07c244e984ad038351a4e147de465d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 17:10:22 +0100 Subject: [PATCH 0260/1786] Added method for checking if an object has accessible constructors --- .../beans/transformer/TransformerImpl.java | 2 +- .../com/hotels/beans/utils/ClassUtils.java | 33 ++++++++++++++++++ .../beans/sample/FromFooWithBuilder.java | 32 +++++++++++++++++ .../hotels/beans/utils/ClassUtilsTest.java | 34 +++++++++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/hotels/beans/sample/FromFooWithBuilder.java diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 5abcff366..1fd05ce2b 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -114,7 +114,7 @@ private K injectValues(final T sourceObj, final Class targetClass, fin */ private String getFormattedConstructorArgs(final Class targetClass, final Object[] constructorArgs) { return stream(constructorArgs) - .map(obj -> obj.getClass().getCanonicalName()) + .map(arg -> isNull(arg) ? "null" : arg.getClass().getCanonicalName()) .collect(joining(COMMA.getSymbol(), targetClass.getCanonicalName() + LPAREN.getSymbol(), RPAREN.getSymbol())); } diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 4e8e9008a..0a4d84e1d 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -18,6 +18,7 @@ import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isPrivate; +import static java.lang.reflect.Modifier.isPublic; import static java.lang.reflect.Modifier.isStatic; import static java.util.Arrays.asList; import static java.util.Arrays.stream; @@ -29,6 +30,7 @@ import static java.util.stream.Collectors.toList; import static org.apache.commons.lang3.ArrayUtils.isEmpty; +import static org.apache.commons.lang3.ArrayUtils.isNotEmpty; import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.base.Defaults.defaultValue; @@ -365,6 +367,37 @@ public Field getDeclaredField(final Class targetClass, final String field }); } + /** + * Checks if the destination class has accessible constructor. + * @param targetClass the destination object class + * @param the target object type + * @return true if the target class uses the builder pattern + */ + public boolean hasAccessibleConstructors(final Class targetClass) { + final String cacheKey = "HasAccessibleConstructors-" + targetClass.getCanonicalName(); + return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final boolean res = stream(targetClass.getDeclaredConstructors()).anyMatch(constructor -> isPublic(constructor.getModifiers())); + cacheManager.cacheObject(cacheKey, res); + return res; + }); + } + + /** + * Checks if the destination class uses the Builder pattern. + * @param constructor the all args constructor + * @param targetClass the destination object class + * @param the target object type + * @return true if the target class uses the builder pattern + */ + public boolean usesBuilderPattern(final Constructor constructor, final Class targetClass) { + final String cacheKey = "UsesBuilderPattern-" + constructor.getDeclaringClass().getCanonicalName(); + return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final boolean res = !isPublic(constructor.getModifiers()) && isNotEmpty(targetClass.getDeclaredClasses()); + cacheManager.cacheObject(cacheKey, res); + return res; + }); + } + /** * Retrieves the all args constructor. * @param clazz the class from which gets the all arg constructor. diff --git a/src/test/java/com/hotels/beans/sample/FromFooWithBuilder.java b/src/test/java/com/hotels/beans/sample/FromFooWithBuilder.java new file mode 100644 index 000000000..448678bf4 --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/FromFooWithBuilder.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.math.BigInteger; + +import lombok.Builder; +import lombok.Getter; + +/** + * Sample object using Builder pattern. + */ +@Builder +@Getter +public class FromFooWithBuilder { + private final String name; + private final BigInteger id; +} diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 3a8415e06..33d36a482 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -43,6 +43,7 @@ import com.hotels.beans.constant.ClassType; import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.sample.FromFoo; +import com.hotels.beans.sample.FromFooWithBuilder; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; @@ -460,4 +461,37 @@ public void testGetDefaultTypeValueWorksAsExpected() { assertEquals(EXPECTED_DEFAULT_VALUE, actual); } + /** + * Tests that the method {@code getDefaultTypeValue} works as expected. + */ + @Test + public void testUsesBuilderPatternWorksAsExpected() { + // GIVEN + final Constructor constructorWithBuilder = underTest.getAllArgsConstructor(FromFooWithBuilder.class); + final Constructor constructorWithoutBuilder = underTest.getAllArgsConstructor(FromFoo.class); + + // WHEN + final boolean usesBuilderPattern = underTest.usesBuilderPattern(constructorWithBuilder, FromFooWithBuilder.class); + final boolean notUseBuilderPattern = underTest.usesBuilderPattern(constructorWithoutBuilder, FromFoo.class); + + // THEN + assertTrue(usesBuilderPattern); + assertFalse(notUseBuilderPattern); + } + + /** + * Tests that the method {@code hasAccessibleConstructors} works as expected. + */ + @Test + public void testHasAccessibleConstructorsWorksAsExpected() { + // GIVEN + + // WHEN + final boolean notAccessibleConstructors = underTest.hasAccessibleConstructors(FromFooWithBuilder.class); + final boolean accessibleConstructors = underTest.hasAccessibleConstructors(FromFoo.class); + + // THEN + assertFalse(notAccessibleConstructors); + assertTrue(accessibleConstructors); + } } From 3c39b05fbbad59e0b2d6faf345e0f05166de9b8e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 19:07:40 +0100 Subject: [PATCH 0261/1786] Added possibility to transform Set objects --- .../com/hotels/beans/populator/ArrayPopulator.java | 4 ++-- .../hotels/beans/populator/CollectionPopulator.java | 10 +++++++--- .../hotels/beans/populator/ICollectionPopulator.java | 3 ++- .../java/com/hotels/beans/populator/Populator.java | 2 +- .../com/hotels/beans/populator/ArrayPopulatorTest.java | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index 80bdfe212..e15db2b5d 100644 --- a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -41,14 +41,14 @@ class ArrayPopulator extends Populator implements ICollectionPopulator genericFieldType, final Object fieldValue, final Class nestedGenericClass) { + public Object getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { final Object res; final ClassUtils classUtils = getClassUtils(); if (classUtils.isPrimitiveTypeArray(fieldValue) || classUtils.isPrimitiveOrSpecialType(genericFieldType)) { diff --git a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index 5f18f5c83..5514eec8f 100644 --- a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -18,9 +18,12 @@ import static java.util.Objects.isNull; import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; import java.lang.reflect.Field; import java.util.Collection; +import java.util.Set; +import java.util.stream.Collector; import com.hotels.beans.transformer.Transformer; @@ -44,7 +47,7 @@ class CollectionPopulator extends Populator implements ICollectio @Override public Collection getPopulatedObject(final Field field, final Collection fieldValue) { final Class genericClass = getReflectionUtils().getArgumentTypeClass(fieldValue, field.getDeclaringClass().getName(), field.getName(), true); - return getPopulatedObject(getReflectionUtils().getGenericFieldType(field), fieldValue, genericClass); + return getPopulatedObject(field.getType(), getReflectionUtils().getGenericFieldType(field), fieldValue, genericClass); } /** @@ -52,16 +55,17 @@ public Collection getPopulatedObject(final Field field, final Collection fiel */ @SuppressWarnings("unchecked") @Override - public Collection getPopulatedObject(final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { + public Collection getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { final Collection res; if (getClassUtils().isPrimitiveOrSpecialType(isNull(nestedGenericClass) ? genericFieldType : nestedGenericClass)) { res = (Collection) fieldValue; } else { + Collector> collector = Set.class.isAssignableFrom(fieldType) ? toSet() : toList(); res = ((Collection) fieldValue) .stream() // .parallelStream() .map(elem -> transform(elem, (Class) genericFieldType)) - .collect(toList()); + .collect(collector); } return res; } diff --git a/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java index e6db3b8e7..8bd1ca44b 100644 --- a/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java @@ -23,10 +23,11 @@ interface ICollectionPopulator { /** * Populates the array of the target object (contained into the object generics) with the values into the source object. + * @param fieldType the field type * @param genericFieldType the field to be populated class * @param fieldValue the source object from which extract the values * @param nestedGenericClass the nested generic object class. i.e. in case of object like this: {@code List>} the value is: String * @return a populated list of elements */ - O getPopulatedObject(Class genericFieldType, Object fieldValue, Class nestedGenericClass); + O getPopulatedObject(Class fieldType, Class genericFieldType, Object fieldValue, Class nestedGenericClass); } diff --git a/src/main/java/com/hotels/beans/populator/Populator.java b/src/main/java/com/hotels/beans/populator/Populator.java index b11bf94ba..95e52ad51 100644 --- a/src/main/java/com/hotels/beans/populator/Populator.java +++ b/src/main/java/com/hotels/beans/populator/Populator.java @@ -111,7 +111,7 @@ final K transform(final T sourceObj, final Class targetClass, final Cl } else { final Optional optPopulator = getPopulator(targetClass, sourceObj.getClass(), transformer); res = (K) optPopulator - .map(populator -> ((ICollectionPopulator) populator).getPopulatedObject(targetClass, sourceObj, nestedGenericClass)) + .map(populator -> ((ICollectionPopulator) populator).getPopulatedObject(targetClass, targetClass, sourceObj, nestedGenericClass)) .orElseGet(() -> transformer.transform(sourceObj, targetClass)); } return res; diff --git a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 61e5a5e2b..6643a99f8 100644 --- a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -95,7 +95,7 @@ public void testGetPopulatedObjectWorksProperly() { when(transformer.transform(any(), eq(MixedToFooStaticField.class))).thenReturn(MIXED_TO_FOO_STATIC_FIELDS_OBJECTS); // WHEN - Object actual = underTest.getPopulatedObject(genericFieldType, array, nestedGenericClass); + Object actual = underTest.getPopulatedObject(null, genericFieldType, array, nestedGenericClass); // THEN if (genericFieldType == Character.class) { From 88623c98cb28c6dbda244b92c8b4b38b80e6eda2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 19:12:08 +0100 Subject: [PATCH 0262/1786] Updated changelog --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7d98ec1f..07125061d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,15 @@ All notable changes to this project will be documented in this file. -### [1.1.4] TBD +### [1.1.4] 2019.02.20 #### Added * Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/HotelsDotCom/bull/issues/27)). * Added possibility to apply a transformation function on all fields matching with the given name without evaluating the full field path. * Added samples and tests for the above functionality +#### Fixed +* Fixed issue that was preventing the `Set` tranformation -### [1.1.3] 2019.17 +### [1.1.3] 2019.02.17 #### Added * Added static transformation functionality (see: [Issue 25](https://github.com/HotelsDotCom/bull/issues/25)). From 3444721259f59169be1e4d0462428f160773a73c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 19:16:19 +0100 Subject: [PATCH 0263/1786] fixed typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07125061d..094069810 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. * Added possibility to apply a transformation function on all fields matching with the given name without evaluating the full field path. * Added samples and tests for the above functionality #### Fixed -* Fixed issue that was preventing the `Set` tranformation +* Fixed issue that was preventing the `Set` transformation ### [1.1.3] 2019.02.17 #### Added From 41117f59b5cd0959393455ee3009a77e674aece5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 19:17:54 +0100 Subject: [PATCH 0264/1786] [maven-release-plugin] prepare release 1.1.4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6e41c30bd..85d9bf642 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.4-SNAPSHOT + 1.1.4 jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.4 From 50f9e5c5354aac17e123ccde8f7dcbe64bf48a9e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Feb 2019 19:18:03 +0100 Subject: [PATCH 0265/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 85d9bf642..70fe36c6b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.4 + 1.1.5-SNAPSHOT jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.4 + HEAD From b7f90faafbfe00f66284e34ac2fd008fb02eaa6c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Feb 2019 08:48:56 +0100 Subject: [PATCH 0266/1786] checkstyle fixes --- .../transformer/AbstractTransformer.java | 20 +++---- .../beans/transformer/TransformerImpl.java | 56 +++++++++---------- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index d4394718c..67a1e093c 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -18,6 +18,7 @@ import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.joining; + import static javax.validation.Validation.buildDefaultValidatorFactory; import static org.apache.commons.lang3.StringUtils.SPACE; @@ -29,6 +30,7 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; + import javax.validation.Validator; import javax.validation.ConstraintViolation; @@ -39,37 +41,34 @@ import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; -import com.hotels.beans.utils.ValidationUtils; + +import lombok.Getter; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * Contains all method implementation that will be common to any {@link Transformer} implementation. */ +@Getter abstract class AbstractTransformer implements Transformer { /** * Reflection utils class {@link ReflectionUtils}. */ - final ReflectionUtils reflectionUtils; + private final ReflectionUtils reflectionUtils; /** * Class reflection utils class {@link ClassUtils}. */ - final ClassUtils classUtils; - - /** - * Validation utils class {@link ValidationUtils}. - */ - final ValidationUtils validationUtils; + private final ClassUtils classUtils; /** * CacheManager class {@link CacheManager}. */ - final CacheManager cacheManager; + private final CacheManager cacheManager; /** * Contains both the field name mapping and the lambda function to be applied on fields. */ - final TransformerSettings transformerSettings; + private final TransformerSettings transformerSettings; /** * Default constructor. @@ -77,7 +76,6 @@ abstract class AbstractTransformer implements Transformer { AbstractTransformer() { this.reflectionUtils = new ReflectionUtils(); this.classUtils = new ClassUtils(); - this.validationUtils = new ValidationUtils(); this.transformerSettings = new TransformerSettings(); this.cacheManager = CacheManagerFactory.getCacheManager("transformer"); } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index cdf35a9d6..719371b65 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -25,13 +25,13 @@ import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.base.Defaults.defaultValue; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; import static com.hotels.beans.constant.Punctuation.COMMA; +import static com.hotels.beans.constant.Punctuation.DOT; import static com.hotels.beans.constant.Punctuation.LPAREN; import static com.hotels.beans.constant.Punctuation.RPAREN; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; @@ -56,7 +56,7 @@ public class TransformerImpl extends AbstractTransformer { @Override protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final ClassType classType = classUtils.getClassType(targetClass); + final ClassType classType = getClassUtils().getClassType(targetClass); if (classType.is(MUTABLE)) { try { k = targetClass.getDeclaredConstructor().newInstance(); @@ -67,7 +67,7 @@ protected final K transform(final T sourceObj, final Class t throw new InvalidBeanException(e.getMessage(), e); } } else { - k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); + k = injectValues(sourceObj, targetClass, getClassUtils().getAllArgsConstructor(targetClass), breadcrumb); if (classType.is(MIXED)) { injectNotFinalFields(sourceObj, k, breadcrumb); } @@ -127,10 +127,10 @@ private String getFormattedConstructorArgs(final Class targetClass, final */ private boolean canBeInjectedByConstructorParams(final Constructor constructor, final Class targetClass) { final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { - final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() - && (classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class)); - cacheManager.cacheObject(cacheKey, res); + return ofNullable(getCacheManager().getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final boolean res = getClassUtils().getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() + && (getClassUtils().areParameterNamesAvailable(constructor) || getClassUtils().allParameterAnnotatedWith(constructor, ConstructorArg.class)); + getCacheManager().cacheObject(cacheKey, res); return res; }); } @@ -148,19 +148,19 @@ private boolean canBeInjectedByConstructorParams(final Constructor construct * @throws InvalidBeanException {@link InvalidBeanException} if there is an error while retrieving the constructor args parameter */ private Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { - final Parameter[] constructorParameters = classUtils.getConstructorParameters(constructor); + final Parameter[] constructorParameters = getClassUtils().getConstructorParameters(constructor); final Object[] constructorArgsValues = new Object[constructorParameters.length]; range(0, constructorParameters.length) //.parallel() .forEach(i -> { String destFieldName = getDestFieldName(constructorParameters[i], targetClass.getCanonicalName()); if (isNull(destFieldName)) { - constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); + constructorArgsValues[i] = getClassUtils().getDefaultTypeValue(constructorParameters[i].getType()); } else { String sourceFieldName = getSourceFieldName(destFieldName); constructorArgsValues[i] = - ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, classUtils.getDeclaredField(targetClass, destFieldName), breadcrumb)) - .orElse(classUtils.getDefaultTypeValue(constructorParameters[i].getType())); + ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, getClassUtils().getDeclaredField(targetClass, destFieldName), breadcrumb)) + .orElse(getClassUtils().getDefaultTypeValue(constructorParameters[i].getType())); } }); return constructorArgsValues; @@ -181,7 +181,7 @@ private String getSourceFieldName(final Field field) { * @return the source field name. */ private String getSourceFieldName(final String fieldName) { - return ofNullable(transformerSettings.getFieldsNameMapping().get(fieldName)).orElse(fieldName); + return ofNullable(getTransformerSettings().getFieldsNameMapping().get(fieldName)).orElse(fieldName); } /** @@ -192,17 +192,17 @@ private String getSourceFieldName(final String fieldName) { */ private String getDestFieldName(final Parameter constructorParameter, final String declaringClassName) { String cacheKey = "DestFieldName-" + declaringClassName + "-" + constructorParameter.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, String.class)) + return ofNullable(getCacheManager().getFromCache(cacheKey, String.class)) .orElseGet(() -> { String destFieldName; if (constructorParameter.isNamePresent()) { destFieldName = constructorParameter.getName(); } else { - destFieldName = ofNullable(reflectionUtils.getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)) + destFieldName = ofNullable(getReflectionUtils().getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)) .map(ConstructorArg::value) .orElse(null); } - cacheManager.cacheObject(cacheKey, destFieldName); + getCacheManager().cacheObject(cacheKey, destFieldName); return destFieldName; }); } @@ -219,7 +219,7 @@ private String getDestFieldName(final Parameter constructorParameter, final Stri * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ private Object[] getConstructorValuesFromFields(final T sourceObj, final Class targetClass, final String breadcrumb) { - final List declaredFields = classUtils.getDeclaredFields(targetClass, true); + final List declaredFields = getClassUtils().getDeclaredFields(targetClass, true); return declaredFields.stream() .map(field -> getFieldValue(sourceObj, targetClass, field, breadcrumb)) .toArray(Object[]::new); @@ -237,9 +237,9 @@ private Object[] getConstructorValuesFromFields(final T sourceObj, final */ private void injectNotFinalFields(final T sourceObj, final K targetObject, final String breadcrumb) { final Class targetObjectClass = targetObject.getClass(); - classUtils.getNotFinalFields(targetObjectClass, true) + getClassUtils().getNotFinalFields(targetObjectClass, true) //.parallelStream() - .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); + .forEach(field -> getReflectionUtils().setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); } /** @@ -274,13 +274,13 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN Object fieldValue = null; String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); if (isNotEmpty(sourceFieldName)) { - boolean primitiveType = classUtils.isPrimitiveType(field.getType()); - boolean isFieldTransformerDefined = transformerSettings.getFieldsTransformers().containsKey(field.getName()); + boolean primitiveType = getClassUtils().isPrimitiveType(field.getType()); + boolean isFieldTransformerDefined = getTransformerSettings().getFieldsTransformers().containsKey(field.getName()); fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function // defined it recursively evaluate the value - boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(field.getType()); + boolean notPrimitiveAndNotSpecialType = !primitiveType && !getClassUtils().isSpecialType(field.getType()); if ((notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass())) && !isFieldTransformerDefined) { fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); @@ -314,9 +314,9 @@ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { private Object getSourceFieldValue(final T sourceObj, final String sourceFieldName, final Field field, final boolean isFieldTransformerDefined) { Object fieldValue = null; try { - fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); + fieldValue = getReflectionUtils().getFieldValue(sourceObj, sourceFieldName, field.getType()); } catch (MissingFieldException e) { - if (!isFieldTransformerDefined && !transformerSettings.isSetDefaultValue()) { + if (!isFieldTransformerDefined && !getTransformerSettings().isSetDefaultValue()) { throw e; } } catch (Exception e) { @@ -335,8 +335,8 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie * @return the transformed field. */ private Object getTransformedField(final Field field, final String breadcrumb, final Object fieldValue) { - String fieldName = transformerSettings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - return ofNullable(transformerSettings.getFieldsTransformers().get(fieldName)) + String fieldName = getTransformerSettings().isFlatFieldNameTransformation() ? field.getName() : breadcrumb; + return ofNullable(getTransformerSettings().getFieldsTransformers().get(fieldName)) .map(fieldTransformer -> fieldTransformer.apply(fieldValue)) .orElse(fieldValue); } From 2abe572b23f6803c956fdc1c0606c10ac2b04d93 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Feb 2019 09:22:03 +0100 Subject: [PATCH 0267/1786] minor: modified site deploy condition --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 488f16d1f..2d4de6998 100755 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,7 @@ jobs: github-token: ${github_oauth_token} keep-history: true on: - branch: master + tags: true - stage: "Release" name: "Releasing artifacts" if: type NOT IN (pull_request) AND tag IS present From 161e72d3da37b6e5d79986ea63921753939e0729 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Feb 2019 12:02:05 +0100 Subject: [PATCH 0268/1786] - Added field populator caching - Added possibility to disable object validation - Removed not needed conditions --- pom.xml | 5 +++ .../beans/populator/ArrayPopulator.java | 7 ++-- .../beans/populator/CollectionPopulator.java | 7 ++-- .../beans/populator/ICollectionPopulator.java | 3 +- .../hotels/beans/populator/MapPopulator.java | 16 +++++---- .../beans/populator/OptionalPopulator.java | 2 +- .../com/hotels/beans/populator/Populator.java | 12 ++++--- .../beans/populator/PopulatorFactory.java | 30 +++++++++++++++++ .../transformer/AbstractTransformer.java | 10 ++++++ .../hotels/beans/transformer/Transformer.java | 7 ++++ .../beans/transformer/TransformerImpl.java | 33 ++++++++----------- .../transformer/TransformerSettings.java | 7 ++++ .../hotels/beans/utils/ReflectionUtils.java | 2 +- .../beans/populator/ArrayPopulatorTest.java | 3 +- 14 files changed, 103 insertions(+), 41 deletions(-) diff --git a/pom.xml b/pom.xml index 80b69cf37..ad625bda5 100644 --- a/pom.xml +++ b/pom.xml @@ -103,6 +103,11 @@ hibernate-validator ${hibernate-validator.version} + + org.hibernate.validator + hibernate-validator-annotation-processor + ${hibernate-validator.version} + org.springframework.boot diff --git a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index e15db2b5d..e6e60f9a9 100644 --- a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -41,14 +41,15 @@ class ArrayPopulator extends Populator implements ICollectionPopulator fieldType, final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { + public Object getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, + final Class nestedGenericClass, final String fieldName) { final Object res; final ClassUtils classUtils = getClassUtils(); if (classUtils.isPrimitiveTypeArray(fieldValue) || classUtils.isPrimitiveOrSpecialType(genericFieldType)) { @@ -56,7 +57,7 @@ public Object getPopulatedObject(final Class fieldType, final Class generi } else { res = stream((Object[]) fieldValue) //.parallel() - .map(o -> classUtils.isPrimitiveOrSpecialType(genericFieldType) ? o : transform(o, genericFieldType)).toArray(); + .map(o -> classUtils.isPrimitiveOrSpecialType(genericFieldType) ? o : transform(o, genericFieldType, fieldName)).toArray(); } return res; } diff --git a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index 5514eec8f..6a3d5a52c 100644 --- a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -47,7 +47,7 @@ class CollectionPopulator extends Populator implements ICollectio @Override public Collection getPopulatedObject(final Field field, final Collection fieldValue) { final Class genericClass = getReflectionUtils().getArgumentTypeClass(fieldValue, field.getDeclaringClass().getName(), field.getName(), true); - return getPopulatedObject(field.getType(), getReflectionUtils().getGenericFieldType(field), fieldValue, genericClass); + return getPopulatedObject(field.getType(), getReflectionUtils().getGenericFieldType(field), fieldValue, genericClass, field.getName()); } /** @@ -55,7 +55,8 @@ public Collection getPopulatedObject(final Field field, final Collection fiel */ @SuppressWarnings("unchecked") @Override - public Collection getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { + public Collection getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, + final Class nestedGenericClass, final String fieldName) { final Collection res; if (getClassUtils().isPrimitiveOrSpecialType(isNull(nestedGenericClass) ? genericFieldType : nestedGenericClass)) { res = (Collection) fieldValue; @@ -64,7 +65,7 @@ public Collection getPopulatedObject(final Class fieldType, final Class res = ((Collection) fieldValue) .stream() // .parallelStream() - .map(elem -> transform(elem, (Class) genericFieldType)) + .map(elem -> transform(elem, (Class) genericFieldType, fieldName)) .collect(collector); } return res; diff --git a/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java index 8bd1ca44b..99a8e5c94 100644 --- a/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java @@ -27,7 +27,8 @@ interface ICollectionPopulator { * @param genericFieldType the field to be populated class * @param fieldValue the source object from which extract the values * @param nestedGenericClass the nested generic object class. i.e. in case of object like this: {@code List>} the value is: String + * @param fieldName the field name under process * @return a populated list of elements */ - O getPopulatedObject(Class fieldType, Class genericFieldType, Object fieldValue, Class nestedGenericClass); + O getPopulatedObject(Class fieldType, Class genericFieldType, Object fieldValue, Class nestedGenericClass, String fieldName); } diff --git a/src/main/java/com/hotels/beans/populator/MapPopulator.java b/src/main/java/com/hotels/beans/populator/MapPopulator.java index f019b56d7..f72d5acd2 100644 --- a/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -45,16 +45,17 @@ class MapPopulator extends Populator> { @Override public Map getPopulatedObject(final Field field, final Map fieldValue) { final MapType mapGenericType = getReflectionUtils().getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); - return getPopulatedObject(fieldValue, mapGenericType); + return getPopulatedObject(fieldValue, mapGenericType, field.getName()); } /** * Populates the Map objects. * @param fieldValue the source Map. * @param mapType the map key, elem types {@link MapType} + * @param fieldName the name of the field under process * @return the populated map */ - private Map getPopulatedObject(final Map fieldValue, final MapType mapType) { + private Map getPopulatedObject(final Map fieldValue, final MapType mapType, final String fieldName) { final MapElemType keyType = mapType.getKeyType(); final MapElemType elemType = mapType.getElemType(); final boolean keyIsPrimitive = keyType.getClass().equals(ItemType.class) && getClassUtils().isPrimitiveOrSpecialType(((ItemType) keyType).getObjectClass()); @@ -67,8 +68,8 @@ class MapPopulator extends Populator> { .stream() // .parallelStream() .collect(toMap( - key -> getElemValue(keyType, keyIsPrimitive, key), - key -> getElemValue(elemType, elemIsPrimitive, fieldValue.get(key)))); + key -> getElemValue(keyType, keyIsPrimitive, key, fieldName), + key -> getElemValue(elemType, elemIsPrimitive, fieldValue.get(key), fieldName))); } return populatedObject; } @@ -79,18 +80,19 @@ class MapPopulator extends Populator> { * @param mapElemType the map key, elem types {@link MapElemType} * @param elemIsPrimitiveType true if the elem map is primitive type, false otherwise. * @param value the elem value + * @param fieldName the name of the field under process * @return the element value */ @SuppressWarnings("unchecked") - private T getElemValue(final MapElemType mapElemType, final boolean elemIsPrimitiveType, final T value) { + private T getElemValue(final MapElemType mapElemType, final boolean elemIsPrimitiveType, final T value, final String fieldName) { final T elemValue; if (elemIsPrimitiveType || getClassUtils().isPrimitiveOrSpecialType(value.getClass())) { elemValue = value; } else { if (mapElemType.getClass().equals(ItemType.class)) { - elemValue = (T) transform(value, ((ItemType) mapElemType).getObjectClass(), ((ItemType) mapElemType).getGenericClass()); + elemValue = (T) transform(value, ((ItemType) mapElemType).getObjectClass(), ((ItemType) mapElemType).getGenericClass(), fieldName); } else { - elemValue = (T) getPopulatedObject((Map) value, (MapType) mapElemType); + elemValue = (T) getPopulatedObject((Map) value, (MapType) mapElemType, fieldName); } } return elemValue; diff --git a/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index cb8636e58..ee597d1d4 100644 --- a/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -44,7 +44,7 @@ public Object getPopulatedObject(final Field field, final Object fieldValue) { Object res = null; Optional optionalFieldValue = (Optional) fieldValue; if (optionalFieldValue.isPresent()) { - res = transform(optionalFieldValue.get(), field.getType()); + res = transform(optionalFieldValue.get(), field.getType(), field.getName()); } // if the field type in the target class is not an optional it puts the value inside an optional if (field.getType() == Optional.class) { diff --git a/src/main/java/com/hotels/beans/populator/Populator.java b/src/main/java/com/hotels/beans/populator/Populator.java index 95e52ad51..75930a04d 100644 --- a/src/main/java/com/hotels/beans/populator/Populator.java +++ b/src/main/java/com/hotels/beans/populator/Populator.java @@ -85,12 +85,13 @@ public final O getPopulatedObject(final Class targetClass, final String f * Wrapper method for BeanUtil transform method. * @param sourceObj the source object * @param targetClass the destination object class + * @param fieldName the name of field under process * @param the Source object type * @param the target object type * @return a copy of the source object into the destination object */ - final K transform(final T sourceObj, final Class targetClass) { - return transform(sourceObj, targetClass, null); + final K transform(final T sourceObj, final Class targetClass, final String fieldName) { + return transform(sourceObj, targetClass, null, fieldName); } /** @@ -99,19 +100,20 @@ final K transform(final T sourceObj, final Class targetClass) { * @param targetClass the destination object class * @param nestedGenericClass the nested generic object class. i.e. in case of object like this: * {@code List>} the value is: String + * @param fieldName the name of field under process * @param the Source object type * @param the target object type * @return a copy of the source object into the destination object */ @SuppressWarnings("unchecked") - final K transform(final T sourceObj, final Class targetClass, final Class nestedGenericClass) { + final K transform(final T sourceObj, final Class targetClass, final Class nestedGenericClass, final String fieldName) { final K res; if (classUtils.isPrimitiveOrSpecialType(sourceObj.getClass())) { res = (K) sourceObj; } else { - final Optional optPopulator = getPopulator(targetClass, sourceObj.getClass(), transformer); + final Optional optPopulator = getPopulator(targetClass, sourceObj.getClass(), transformer, fieldName); res = (K) optPopulator - .map(populator -> ((ICollectionPopulator) populator).getPopulatedObject(targetClass, targetClass, sourceObj, nestedGenericClass)) + .map(populator -> ((ICollectionPopulator) populator).getPopulatedObject(targetClass, targetClass, sourceObj, nestedGenericClass, fieldName)) .orElseGet(() -> transformer.transform(sourceObj, targetClass)); } return res; diff --git a/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/src/main/java/com/hotels/beans/populator/PopulatorFactory.java index 5e53f1a3f..cc1a8d0ca 100644 --- a/src/main/java/com/hotels/beans/populator/PopulatorFactory.java +++ b/src/main/java/com/hotels/beans/populator/PopulatorFactory.java @@ -18,6 +18,9 @@ import static java.util.Optional.empty; import static java.util.Optional.of; +import static java.util.Optional.ofNullable; + +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static lombok.AccessLevel.PRIVATE; @@ -25,6 +28,7 @@ import java.util.Map; import java.util.Optional; +import com.hotels.beans.cache.CacheManager; import com.hotels.beans.transformer.Transformer; import lombok.NoArgsConstructor; @@ -34,6 +38,11 @@ */ @NoArgsConstructor(access = PRIVATE) public final class PopulatorFactory { + /** + * The Cache manager for this class. + */ + private static final CacheManager CACHE_MANAGER = getCacheManager("populatorFactory"); + /** * Creates an instance of the populator object based on the given class. * @param the generic type of the contained object in the destination object @@ -56,4 +65,25 @@ public static Optional getPopulator(final Class destObjectC } return populator; } + + /** + * Creates an instance of the populator object based on the given class for the given field. + * @param the generic type of the contained object in the destination object + * @param the generic type of the contained object in the source object + * @param destObjectClass the destination object class + * @param sourceObjectClass the source object class + * @param transformer the bean transformer containing the field name mapping and transformation functions + * @param fieldName the name of the field to transform + * @return the populator instance + */ + @SuppressWarnings("unchecked") + public static Optional getPopulator(final Class destObjectClass, final Class sourceObjectClass, final Transformer transformer, final String fieldName) { + String cacheKey = "FieldPopulator-" + destObjectClass.getCanonicalName() + "-" + fieldName; + return ofNullable(CACHE_MANAGER.getFromCache(cacheKey, Optional.class)) + .orElseGet(() -> { + Optional populator = PopulatorFactory.getPopulator(destObjectClass, sourceObjectClass, transformer); + CACHE_MANAGER.cacheObject(cacheKey, populator); + return populator; + }); + } } diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 67a1e093c..392f57741 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -157,6 +157,15 @@ public final Transformer setFlatFieldNameTransformation(final boolean useFlatTra return this; } + /** + * {@inheritDoc} + */ + @Override + public Transformer setValidationDisabled(final boolean validationDisabled) { + transformerSettings.setValidationDisabled(validationDisabled); + return this; + } + /** * {@inheritDoc} */ @@ -174,6 +183,7 @@ public final K transform(final T sourceObj, final Class targ * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails */ final void validate(final K k) { + if (transformerSettings.isValidationDisabled()) return; final Set> constraintViolations = getValidator().validate(k); if (!constraintViolations.isEmpty()) { final String errors = constraintViolations.stream() diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index 6345cc102..6982711f3 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -88,4 +88,11 @@ public interface Transformer { * @return the {@link Transformer} instance */ Transformer setFlatFieldNameTransformation(boolean useFlatTransformation); + + /** + * It allows to disable the object validation. + * @param validationDisabled if true the validation is skipped. + * @return the {@link Transformer} instance + */ + Transformer setValidationDisabled(boolean validationDisabled); } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 719371b65..dec129b19 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -23,8 +23,6 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; -import static org.apache.commons.lang3.StringUtils.isNotEmpty; - import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.constant.ClassType.MIXED; import static com.hotels.beans.constant.ClassType.MUTABLE; @@ -271,23 +269,20 @@ private Object getFieldValue(final T sourceObj, final Class targetClas * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { - Object fieldValue = null; String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); - if (isNotEmpty(sourceFieldName)) { - boolean primitiveType = getClassUtils().isPrimitiveType(field.getType()); - boolean isFieldTransformerDefined = getTransformerSettings().getFieldsTransformers().containsKey(field.getName()); - fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); - if (nonNull(fieldValue)) { - // is not a primitive type or an optional && there are no transformer function - // defined it recursively evaluate the value - boolean notPrimitiveAndNotSpecialType = !primitiveType && !getClassUtils().isSpecialType(field.getType()); - if ((notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass())) - && !isFieldTransformerDefined) { - fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); - } - } else if (primitiveType) { - fieldValue = defaultValue(field.getType()); // assign the default value + boolean primitiveType = getClassUtils().isPrimitiveType(field.getType()); + boolean isFieldTransformerDefined = getTransformerSettings().getFieldsTransformers().containsKey(field.getName()); + Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); + if (nonNull(fieldValue)) { + // is not a primitive type or an optional && there are no transformer function + // defined it recursively evaluate the value + boolean notPrimitiveAndNotSpecialType = !primitiveType && !getClassUtils().isSpecialType(field.getType()); + if ((notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass())) + && !isFieldTransformerDefined) { + fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); } + } else if (primitiveType) { + fieldValue = defaultValue(field.getType()); // assign the default value } return getTransformedField(field, fieldBreadcrumb, fieldValue); } @@ -299,7 +294,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN * @return the updated breadcrumb */ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { - return (breadcrumb != null ? breadcrumb + DOT.getSymbol() : "") + fieldName; + return (nonNull(breadcrumb) ? breadcrumb + DOT.getSymbol() : "") + fieldName; } /** @@ -353,7 +348,7 @@ private Object getTransformedField(final Field field, final String breadcrumb, f */ @SuppressWarnings("unchecked") private Object getFieldValue(final Class targetClass, final Field field, final Object fieldValue, final String breadcrumb) { - return getPopulator(field.getType(), fieldValue.getClass(), this) + return getPopulator(field.getType(), fieldValue.getClass(), this, field.getName()) .map(populator -> populator.getPopulatedObject(targetClass, field.getName(), fieldValue)) .orElseGet(() -> // recursively inject object diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 051c718dc..22d4b4433 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -60,4 +60,11 @@ final class TransformerSettings { */ @Setter private boolean flatFieldNameTransformation; + + /** + * It allows to disable the object validation. + * If set to true the validation is skipped. + */ + @Setter + private boolean validationDisabled; } diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index b606c8f5d..195ac40b7 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -233,7 +233,7 @@ private Object getFieldValue(final Object target, final String fieldName) { handleReflectionException(e); throw new IllegalStateException(e); } finally { - if (nonNull(field) && !isAccessible) { + if (!isAccessible) { field.setAccessible(false); } } diff --git a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 6643a99f8..34843b493 100644 --- a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -51,6 +51,7 @@ public class ArrayPopulatorTest { private static final int ZERO = 0; private static final int[] INT_ARRAY = new int[] {ZERO}; private static final MixedToFooStaticField MIXED_TO_FOO_STATIC_FIELDS_OBJECTS = new MixedToFooStaticField(); + private static final String FIELD_NAME = "testField"; private final Class genericFieldType; private final Class nestedGenericClass; @@ -95,7 +96,7 @@ public void testGetPopulatedObjectWorksProperly() { when(transformer.transform(any(), eq(MixedToFooStaticField.class))).thenReturn(MIXED_TO_FOO_STATIC_FIELDS_OBJECTS); // WHEN - Object actual = underTest.getPopulatedObject(null, genericFieldType, array, nestedGenericClass); + Object actual = underTest.getPopulatedObject(null, genericFieldType, array, nestedGenericClass, FIELD_NAME); // THEN if (genericFieldType == Character.class) { From 2dab176eaf0e4978e1c1e69cf03b993983824395 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Feb 2019 17:29:42 +0100 Subject: [PATCH 0269/1786] - Updated changelog with the new functions implemented - Added test case for the new functionalities --- CHANGELOG.md | 5 + pom.xml | 61 +-------- .../transformer/AbstractTransformer.java | 4 +- .../java/com/hotels/beans/sample/FromFoo.java | 4 +- .../transformer/AbstractTransformerTest.java | 125 ++++++++++++++++++ .../beans/transformer/TransformerTest.java | 107 +++++---------- 6 files changed, 170 insertions(+), 136 deletions(-) create mode 100644 src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 094069810..f0eab5e76 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.1.5] TBD +#### Added +* Upgraded to Java 11 +* Added possibility to skip the object validation + ### [1.1.4] 2019.02.20 #### Added * Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/HotelsDotCom/bull/issues/27)). diff --git a/pom.xml b/pom.xml index ad625bda5..6a6c96c88 100644 --- a/pom.xml +++ b/pom.xml @@ -22,11 +22,10 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 - 2.1.2.RELEASE 1.18.4 3.8.1 @@ -234,64 +233,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 392f57741..b9cec542e 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -183,7 +183,9 @@ public final K transform(final T sourceObj, final Class targ * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails */ final void validate(final K k) { - if (transformerSettings.isValidationDisabled()) return; + if (transformerSettings.isValidationDisabled()) { + return; + } final Set> constraintViolations = getValidator().validate(k); if (!constraintViolations.isEmpty()) { final String errors = constraintViolations.stream() diff --git a/src/test/java/com/hotels/beans/sample/FromFoo.java b/src/test/java/com/hotels/beans/sample/FromFoo.java index 77a5e680c..010259073 100644 --- a/src/test/java/com/hotels/beans/sample/FromFoo.java +++ b/src/test/java/com/hotels/beans/sample/FromFoo.java @@ -21,14 +21,16 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.Setter; /** * Sample immutable object. */ @AllArgsConstructor @Getter +@Setter public class FromFoo { - private final String name; + private String name; private final BigInteger id; private final List nestedObjectList; private final List list; diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java new file mode 100644 index 000000000..6f2c112d6 --- /dev/null +++ b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -0,0 +1,125 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.junit.Before; +import org.junit.Test; + +import com.hotels.beans.model.FieldMapping; +import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.utils.ReflectionUtils; + +/** + * Unit test for class: {@link AbstractTransformer}. + */ +public class AbstractTransformerTest { + private static final String SOURCE_FIELD_NAME = "sourceFieldName"; + private static final String DEST_FIELD_NAME = "destFieldName"; + private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "transformerSettings"; + private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); + + /** + * The class to be tested. + */ + private AbstractTransformer underTest; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + underTest = new TransformerImpl(); + initMocks(this); + } + + /** + * Test that is possible to remove a field mapping for a given field. + */ + @Test + public void testRemoveFieldMappingWorksProperly() { + //GIVEN + Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); + + //WHEN + beanTransformer.removeFieldMapping(DEST_FIELD_NAME); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); + + //THEN + assertFalse(transformerSettings.getFieldsNameMapping().containsKey(DEST_FIELD_NAME)); + } + + /** + * Test that the method {@code removeFieldMapping} raises an {@link IllegalArgumentException} if the parameter is null. + */ + @Test(expected = IllegalArgumentException.class) + public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { + //GIVEN + Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("sourceFieldName", DEST_FIELD_NAME)); + + //WHEN + beanTransformer.removeFieldMapping(null); + } + + /** + * Test that is possible to remove all the fields mappings defined. + */ + @Test + public void testResetFieldsMappingWorksProperly() { + //GIVEN + Transformer beanTransformer = underTest + .withFieldMapping(new FieldMapping("sourceFieldName", DEST_FIELD_NAME), new FieldMapping("sourceFieldName2", DEST_FIELD_NAME)); + + //WHEN + beanTransformer.resetFieldsMapping(); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); + + //THEN + assertTrue(transformerSettings.getFieldsNameMapping().isEmpty()); + } + + /** + * Test that is possible to remove a field transformer for a given field. + */ + @Test + public void testRemoveFieldTransformerWorksProperly() { + //GIVEN + Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); + + //WHEN + beanTransformer.removeFieldTransformer(DEST_FIELD_NAME); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); + + //THEN + assertFalse(transformerSettings.getFieldsTransformers().containsKey(DEST_FIELD_NAME)); + } + + /** + * Test that the method {@code removeFieldTransformer} raises an {@link IllegalArgumentException} if the parameter is null. + */ + @Test(expected = IllegalArgumentException.class) + public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() { + //GIVEN + Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); + + //WHEN + beanTransformer.removeFieldTransformer(null); + } +} diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 3f2f0348b..9877bd9f1 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -23,7 +23,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; @@ -150,79 +149,6 @@ public void beforeMethod() { } - /** - * Test that is possible to remove a field mapping for a given field. - */ - @Test - public void testRemoveFieldMappingWorksProperly() { - //GIVEN - Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("sourceFieldName", DEST_FIELD_NAME)); - - //WHEN - beanTransformer.removeFieldMapping(DEST_FIELD_NAME); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - - //THEN - assertFalse(transformerSettings.getFieldsNameMapping().containsKey(DEST_FIELD_NAME)); - } - - /** - * Test that the method {@code removeFieldMapping} raises an {@link IllegalArgumentException} if the parameter is null. - */ - @Test(expected = IllegalArgumentException.class) - public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { - //GIVEN - Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("sourceFieldName", DEST_FIELD_NAME)); - - //WHEN - beanTransformer.removeFieldMapping(null); - } - - /** - * Test that is possible to remove all the fields mappings defined. - */ - @Test - public void testResetFieldsMappingWorksProperly() { - //GIVEN - Transformer beanTransformer = underTest - .withFieldMapping(new FieldMapping("sourceFieldName", DEST_FIELD_NAME), new FieldMapping("sourceFieldName2", DEST_FIELD_NAME)); - - //WHEN - beanTransformer.resetFieldsMapping(); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - - //THEN - assertTrue(transformerSettings.getFieldsNameMapping().isEmpty()); - } - - /** - * Test that is possible to remove a field transformer for a given field. - */ - @Test - public void testRemoveFieldTransformerWorksProperly() { - //GIVEN - Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - - //WHEN - beanTransformer.removeFieldTransformer(DEST_FIELD_NAME); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - - //THEN - assertFalse(transformerSettings.getFieldsTransformers().containsKey(DEST_FIELD_NAME)); - } - - /** - * Test that the method {@code removeFieldTransformer} raises an {@link IllegalArgumentException} if the parameter is null. - */ - @Test(expected = IllegalArgumentException.class) - public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() { - //GIVEN - Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - - //WHEN - beanTransformer.removeFieldTransformer(null); - } - /** * Test that is possible to remove all the fields transformer defined. */ @@ -380,6 +306,39 @@ public void testTransformThrowsExceptionWhenImmutableBeanHasAWrongConstructor() underTest.transform(fromFoo, ImmutableToFooInvalid.class); } + /** + * Test that an exception is thrown if the destination object don't met the constraints. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionIfTheDestinationObjectValuesAreNotValid() { + //GIVEN + fromFoo.setName(null); + + //WHEN + underTest.transform(fromFoo, ImmutableToFoo.class); + + // THEN + fromFoo.setName(NAME); + } + + /** + * Test that no exception is thrown if the destination object don't met the constraints and the validation is disabled. + */ + @Test + public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotValidAndTheValidationIsDisabled() { + //GIVEN + fromFoo.setName(null); + underTest.setValidationDisabled(true); + + //WHEN + ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); + + // THEN + assertThat(actual, sameBeanAs(fromFoo)); + fromFoo.setName(NAME); + underTest.setValidationDisabled(false); + } + /** * Test that a Mixed bean with a constructor containing the final field only is correctly copied. */ From 5ce6825c7e5f9d95421034f621ba15ed764abb64 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Feb 2019 17:54:27 +0100 Subject: [PATCH 0270/1786] Added examples on how to disable the java bean validation --- README.md | 57 ++++++----- docs/site/markdown/transformer/samples.md | 57 ++++++----- docs/site/markdown/transformer/testing.md | 112 ---------------------- docs/site/site.xml | 1 - 4 files changed, 66 insertions(+), 161 deletions(-) delete mode 100644 docs/site/markdown/transformer/testing.md diff --git a/README.md b/README.md index 74b696b0d..543a459b3 100644 --- a/README.md +++ b/README.md @@ -63,9 +63,6 @@ mvn clean install -P relaxed ### Simple case: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter -@Setter @Setter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -73,6 +70,9 @@ public class FromBean { public class ToBean private List list; private final List list; private final FromSubBean subObject; private final List nestedObjectList; private ImmutableToSubFoo nestedObject; + + // all constructors // all args constructor + // getters and setters... // getters... } } ~~~ @@ -139,7 +139,6 @@ public class FromBean { public class ToBean private final Date creationDate; // all args constructor // all args constructor - // getters... // getters... } } @@ -158,7 +157,6 @@ beanUtils.getTransformer() ~~~Java public class FromBean { public class ToBean { - private final String name; private final String differentName; private final int id; private final int id; private final List subBeanList; private final List subBeanList; @@ -191,9 +189,6 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); ### Different field names and types applying transformation through lambda function: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter -@Setter @Setter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger identifier; @@ -204,7 +199,6 @@ public class FromBean { public class ToBean private ImmutableToSubFoo nestedObject; // constructors... // constructors... - // getters and setters... // getters and setters... } } @@ -224,8 +218,6 @@ beanUtils.getTransformer() Assign a default value in case of missing field in the source object: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -233,8 +225,7 @@ public class FromBean { public class ToBean private String notExistingField; // this will be null and no exceptions will be raised // constructors... // constructors... - - // getters... // getters and setters... + // getters... // getters and setters... } } ~~~ @@ -249,8 +240,6 @@ ToBean toBean = beanUtils.getTransformer() Assign a default value in case of missing field in the source object: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -258,7 +247,6 @@ public class FromBean { public class ToBean private String notExistingField; // this will have value: sampleVal // all args constructor // constructors... - // getters... // getters and setters... } } ~~~ @@ -277,17 +265,16 @@ This example shows of a lambda transformation function can be applied on a neste Given: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; + + // all args constructor // all args constructor + // getters... // getters... } } ~~~ and ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromSubBean { public class ToSubBean { private final String name; private final String name; private final long index; private final long index; @@ -309,20 +296,22 @@ This example shows of a lambda transformation function can be applied on all fie Given: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; + + // all args constructor // all args constructor + // getters... // getters... } } ~~~ and ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromSubBean { public class ToSubBean { private final String name; private final String name; private final long index; private final long index; + + // all args constructor // all args constructor + // getters... // getters... } } ~~~ Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as @@ -348,6 +337,26 @@ Function transformerFunction = BeanUtils.ge .collect(Collectors.toList()); ~~~ +### Disable Java Beans validation: + +Assuming that the field: `id` in the fromBean instance is null. +~~~Java +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final String name; + + // all args constructor // all args constructor + // getters... // getters and setters... +} } +~~~ +adding the following configuration no exception will be thrown: +~~~Java +ToBean toBean = beanUtils.getTransformer() + .setValidationDisabled(true) + .transform(fromBean, ToBean.class); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` ## Third party library comparison diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 2c1d98727..23f872d1f 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -7,9 +7,6 @@ ### Simple case: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter -@Setter @Setter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -17,6 +14,9 @@ public class FromBean { public class ToBean private List list; private final List list; private final FromSubBean subObject; private final List nestedObjectList; private ImmutableToSubFoo nestedObject; + + // all constructors // all args constructor + // getters and setters... // getters... } } ~~~ @@ -83,7 +83,6 @@ public class FromBean { public class ToBean private final Date creationDate; // all args constructor // all args constructor - // getters... // getters... } } @@ -102,7 +101,6 @@ beanUtils.getTransformer() ~~~Java public class FromBean { public class ToBean { - private final String name; private final String differentName; private final int id; private final int id; private final List subBeanList; private final List subBeanList; @@ -135,9 +133,6 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); ### Different field names and types applying transformation through lambda function: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter -@Setter @Setter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger identifier; @@ -148,7 +143,6 @@ public class FromBean { public class ToBean private ImmutableToSubFoo nestedObject; // constructors... // constructors... - // getters and setters... // getters and setters... } } @@ -168,8 +162,6 @@ beanUtils.getTransformer() Assign a default value in case of missing field in the source object: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -177,8 +169,7 @@ public class FromBean { public class ToBean private String notExistingField; // this will be null and no exceptions will be raised // constructors... // constructors... - - // getters... // getters and setters... + // getters... // getters and setters... } } ~~~ @@ -193,8 +184,6 @@ ToBean toBean = beanUtils.getTransformer() Assign a default value in case of missing field in the source object: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -202,7 +191,6 @@ public class FromBean { public class ToBean private String notExistingField; // this will have value: sampleVal // all args constructor // constructors... - // getters... // getters and setters... } } ~~~ @@ -221,17 +209,16 @@ This example shows of a lambda transformation function can be applied on a neste Given: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; + + // all args constructor // all args constructor + // getters... // getters... } } ~~~ and ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromSubBean { public class ToSubBean { private final String name; private final String name; private final long index; private final long index; @@ -253,20 +240,22 @@ This example shows of a lambda transformation function can be applied on all fie Given: ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; + + // all args constructor // all args constructor + // getters... // getters... } } ~~~ and ~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter public class FromSubBean { public class ToSubBean { private final String name; private final String name; private final long index; private final long index; + + // all args constructor // all args constructor + // getters... // getters... } } ~~~ Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as @@ -292,4 +281,24 @@ Function transformerFunction = BeanUtils.ge .collect(Collectors.toList()); ~~~ +### Disable Java Beans validation: + +Assuming that the field: `id` in the fromBean instance is null. +~~~Java +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final String name; + + // all args constructor // all args constructor + // getters... // getters and setters... +} } +~~~ +adding the following configuration no exception will be thrown: +~~~Java +ToBean toBean = beanUtils.getTransformer() + .setValidationDisabled(true) + .transform(fromBean, ToBean.class); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` \ No newline at end of file diff --git a/docs/site/markdown/transformer/testing.md b/docs/site/markdown/transformer/testing.md deleted file mode 100644 index e28dbfef9..000000000 --- a/docs/site/markdown/transformer/testing.md +++ /dev/null @@ -1,112 +0,0 @@ - - Test your library - - -# Overview - -Software testing plays a fundamental role in the software development because we can evaluate one or more properties of interest. In general, these properties indicate the -extent to which the component or system under test: - -* meets the requirements that guided its design and development, -* responds correctly to all kinds of inputs, -* performs its functions within an acceptable time, -* it is sufficiently usable, -* can be installed and run in its intended environments -* achieves the general result its stakeholders desire. - -This page will show how to test BULL into a simple project. All the examples utilizes [JUnit](https://github.com/junit-team) and [Mockito](https://site.mockito.org/). - -The Java Bean transformation function can be tested in two different ways that depends on the following scenarios: - -1. The destination object does not require a special configuration to get transformed -2. The destination object requires a special configuration, you are confident that the configuration is working fine as it doesn't includes any special action -3. The destination object requires a special and complex configuration that needs to be tested as we are not confident that it would work - -For both scenarios: 1 and 2 we can use a mocked version the `BeanUtils` object. - -### First scenario: - -Assuming that our source object and our destination object have been defined as follow: -~~~Java -@AllArgsConstructor @AllArgsConstructor -@Getter @Getter -@Setter @Setter -public class SampleRequest { public class DestObject { - private final BigInteger x; @NotNull - private final BigInteger y; private BigInteger x; - private final List subBeanList; private final BigInteger y; - private List list; private final List list; - private final FromSubBean subObject; private final List nestedObjectList; - -} } -~~~ -And this is the class containing the `BeanUtils` library: -~~~Java -import ... - -public class SampleClass { - - private final BeanUtils beanUtils; - - public SampleClass() { - this.beanUtils = new BeanUtils(); - } - - public BigInteger doSomething(final SampleRequest request) { - final Transformer beanTransformer = beanUtils.getTransformer(); - DestObject destObject = beanTransformer.transform(request, DestObject.class); - return multiplyValues(destObject.getX(), destObject.getY()); - } - - private BigInteger multiplyValues(final BigInteger x, final BigInteger y) { - return x * y; - } -} -~~~ -The test class will be: -~~~Java -import static org.junit.Assert.assertNotNull; -import static org.mockito.MockitoAnnotations.initMocks; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.InjectMocks; - -import com.hotels.beans.transformer.Transformer; - -/** - * Unit test for {@link SampleClass}. - */ -public class SampleClassTest { - /** - * The class to be tested. - */ - @InjectMocks - private SampleClass underTest; - - @Mock - private BeanUtils beanUtils; - - /** - * Initialized mocks. - */ - @Before - public void beforeMethod() { - initMocks(this); - } - - /** - * Test that a SampleResponse is returned. - */ - @Test - public void testDoSomethingWorksProperly() { - //GIVEN - - //WHEN - final Transformer transformer = underTest.getTransformer(); - - //THEN - assertNotNull(transformer); - } -} -~~~ diff --git a/docs/site/site.xml b/docs/site/site.xml index 9a1f7f9e0..73278ae57 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -28,7 +28,6 @@ - From 78df454973c97dcd83c7d47ca1d25963682c0900 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Feb 2019 17:57:50 +0100 Subject: [PATCH 0271/1786] minor: removed not needed fields into ValidationUtils class --- .../com/hotels/beans/utils/ReflectionUtils.java | 4 ++-- .../com/hotels/beans/utils/ValidationUtils.java | 16 ---------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 195ac40b7..62d67141d 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -280,13 +280,13 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f /** * Check if a field is accessible or not. - * To make the project compiling with Java version > 8, replace the following line with: {@code field.canAccess(target);} + * To make the project compiling with Java version <= 8, replace the following line with: {@code field.isAccessible();} * @param field the field to check * @param target the field's class * @return true id is accessible, false otherwise */ private boolean isFieldAccessible(final Field field, final Object target) { - return field.isAccessible(); + return field.canAccess(target); } /** diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java index 10fe0f95e..b49554872 100644 --- a/src/main/java/com/hotels/beans/utils/ValidationUtils.java +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -18,26 +18,10 @@ import static java.util.Objects.isNull; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; - -import com.hotels.beans.cache.CacheManager; - /** * Validation utils for Class objects. */ public class ValidationUtils { - /** - * CacheManager class {@link CacheManager}. - */ - private final CacheManager cacheManager; - - /** - * Default constructor. - */ - public ValidationUtils() { - this.cacheManager = getCacheManager("validationUtils"); - } - /** * Validate that the specified argument is not {@code null}; * otherwise throws an {@link IllegalArgumentException} with the specified message. From 58eeb514fdd1198c7f4e1fce07bfbc0fc8b869ee Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 06:50:22 +0100 Subject: [PATCH 0272/1786] Testing travis build with java 11 --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d4de6998..afed9095f 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,4 @@ language: java -os: -- linux cache: directories: - "~/.m2/repository" @@ -20,8 +18,8 @@ jobs: - stage: "Build" name: "Build and Test" if: NOT branch = master - jdk: oraclejdk11 - install: travis_retry mvn clean install -DskipTests -Dmaven.javadoc.skip=true -B +# jdk: oraclejdk11 + install: travis_retry mvn clean install -DskipTests # If the branch is master it sends the quality report to SonarCloud - stage: "Build and Quality Check" name: "Building, testing and performing quality check" From 4819376a73551a6c23f15e0464246ecec98d988e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 06:52:21 +0100 Subject: [PATCH 0273/1786] Restored jdk version to travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index afed9095f..01804750b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ jobs: - stage: "Build" name: "Build and Test" if: NOT branch = master -# jdk: oraclejdk11 + jdk: oraclejdk11 install: travis_retry mvn clean install -DskipTests # If the branch is master it sends the quality report to SonarCloud - stage: "Build and Quality Check" From 026c3fa5141e46e8073e79e950d477e560d1b5d5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 06:57:18 +0100 Subject: [PATCH 0274/1786] Testing maven site build on Travis with java 11 --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 01804750b..819a98fe2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: java cache: directories: - "~/.m2/repository" +jdk: oraclejdk11 env: global: # Sonatype jira info @@ -18,18 +19,16 @@ jobs: - stage: "Build" name: "Build and Test" if: NOT branch = master - jdk: oraclejdk11 - install: travis_retry mvn clean install -DskipTests +# install: travis_retry mvn clean install -DskipTests -Dmaven.javadoc.skip=true -B + install: travis_retry mvn clean install -DskipTests site:site -B # If the branch is master it sends the quality report to SonarCloud - stage: "Build and Quality Check" name: "Building, testing and performing quality check" if: branch = master AND type NOT IN (pull_request) - jdk: oraclejdk11 install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" if: type NOT IN (pull_request) AND tag IS present - jdk: oraclejdk8 before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - travis_retry mvn install site:site -DskipTests=true -B From db0fafd62264ec19c7e4f259bb9f68e80988dedf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 07:04:02 +0100 Subject: [PATCH 0275/1786] Completed travis configuration with java 11 --- .travis.yml | 3 +-- .../transformer/AbstractTransformer.java | 3 --- .../beans/transformer/TransformerImpl.java | 4 +++- .../beans/performance/PerformanceTest.java | 21 ++++++++++++------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 819a98fe2..bc67ca831 100755 --- a/.travis.yml +++ b/.travis.yml @@ -19,8 +19,7 @@ jobs: - stage: "Build" name: "Build and Test" if: NOT branch = master -# install: travis_retry mvn clean install -DskipTests -Dmaven.javadoc.skip=true -B - install: travis_retry mvn clean install -DskipTests site:site -B + install: travis_retry mvn clean install -DskipTests -Dmaven.javadoc.skip=true -B # If the branch is master it sends the quality report to SonarCloud - stage: "Build and Quality Check" name: "Building, testing and performing quality check" diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index b9cec542e..91e67f69b 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -183,9 +183,6 @@ public final K transform(final T sourceObj, final Class targ * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails */ final void validate(final K k) { - if (transformerSettings.isValidationDisabled()) { - return; - } final Set> constraintViolations = getValidator().validate(k); if (!constraintViolations.isEmpty()) { final String errors = constraintViolations.stream() diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index dec129b19..54b4b733b 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -70,7 +70,9 @@ protected final K transform(final T sourceObj, final Class t injectNotFinalFields(sourceObj, k, breadcrumb); } } - validate(k); + if (!getTransformerSettings().isValidationDisabled()) { + validate(k); + } return k; } diff --git a/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/src/test/java/com/hotels/beans/performance/PerformanceTest.java index 3822a4012..61b290c0c 100644 --- a/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -51,6 +51,7 @@ import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.sample.mutable.MutableToFooSubClass; +import com.hotels.beans.transformer.Transformer; import lombok.extern.slf4j.Slf4j; @@ -90,6 +91,7 @@ public class PerformanceTest { private final Object sourceObject; private final Class destObjectClass; private final double maxTransformationTime; + private final boolean disableValidation; /** * The class to be tested. @@ -103,14 +105,16 @@ public class PerformanceTest { * @param waitInterval time between one transformation and the other * @param sourceObject the Source object to copy * @param destObjectClass the total destination object + * @param disableValidation disables the java bean validation * @param maxTransformationTime expected maximum transformation time */ - public PerformanceTest(final double totalTransformation, final int waitInterval, - final Object sourceObject, final Class destObjectClass, final double maxTransformationTime) { + public PerformanceTest(final double totalTransformation, final int waitInterval, final Object sourceObject, + final Class destObjectClass, final boolean disableValidation, final double maxTransformationTime) { this.totalTransformation = totalTransformation; this.waitInterval = waitInterval; this.sourceObject = sourceObject; this.destObjectClass = destObjectClass; + this.disableValidation = disableValidation; this.maxTransformationTime = maxTransformationTime; } @@ -134,11 +138,12 @@ public void testCopyPropertiesGetsCompletedInTheExpectedTime() throws Interrupte //WHEN StopWatch stopWatch = new StopWatch(); stopWatch.start(); + Transformer beanTransformer = underTest.getTransformer().setValidationDisabled(disableValidation); for (int i = 0; i <= totalTransformation; i++) { stopWatch.suspend(); sleep(waitInterval); stopWatch.resume(); - underTest.getTransformer().transform(sourceObject, destObjectClass); + beanTransformer.transform(sourceObject, destObjectClass); } stopWatch.stop(); double avgTransformationTime = stopWatch.getTime(MILLISECONDS) / totalTransformation; @@ -209,11 +214,11 @@ private static FromFooSubClass createFromFooSubClass() { public static Collection dataProvider() { initObjects(); return asList(new Object[][]{ - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, MutableToFooSimple.class, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, MutableToFooSubClass.class, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, ImmutableToFooSimple.class, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, ImmutableToFooSubClass.class, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFoo, MixedToFoo.class, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME} + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, MutableToFooSimple.class, true, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, MutableToFooSubClass.class, true, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, ImmutableToFooSimple.class, true, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, ImmutableToFooSubClass.class, true, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFoo, MixedToFoo.class, false, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME} }); } } From 17c2cad60a5db9e4b53905d33d6eae583c944c98 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 10:02:26 +0100 Subject: [PATCH 0276/1786] Cached populator generation --- .../beans/populator/ArrayPopulator.java | 7 ++-- .../beans/populator/CollectionPopulator.java | 7 ++-- .../beans/populator/ICollectionPopulator.java | 3 +- .../hotels/beans/populator/MapPopulator.java | 16 ++++--- .../beans/populator/OptionalPopulator.java | 2 +- .../com/hotels/beans/populator/Populator.java | 12 +++--- .../beans/populator/PopulatorFactory.java | 42 ++++++------------- .../beans/transformer/TransformerImpl.java | 2 +- .../beans/performance/PerformanceTest.java | 21 ++++------ .../beans/populator/ArrayPopulatorTest.java | 3 +- 10 files changed, 43 insertions(+), 72 deletions(-) diff --git a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index e6e60f9a9..e15db2b5d 100644 --- a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -41,15 +41,14 @@ class ArrayPopulator extends Populator implements ICollectionPopulator fieldType, final Class genericFieldType, final Object fieldValue, - final Class nestedGenericClass, final String fieldName) { + public Object getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { final Object res; final ClassUtils classUtils = getClassUtils(); if (classUtils.isPrimitiveTypeArray(fieldValue) || classUtils.isPrimitiveOrSpecialType(genericFieldType)) { @@ -57,7 +56,7 @@ public Object getPopulatedObject(final Class fieldType, final Class generi } else { res = stream((Object[]) fieldValue) //.parallel() - .map(o -> classUtils.isPrimitiveOrSpecialType(genericFieldType) ? o : transform(o, genericFieldType, fieldName)).toArray(); + .map(o -> classUtils.isPrimitiveOrSpecialType(genericFieldType) ? o : transform(o, genericFieldType)).toArray(); } return res; } diff --git a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index 6a3d5a52c..5514eec8f 100644 --- a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -47,7 +47,7 @@ class CollectionPopulator extends Populator implements ICollectio @Override public Collection getPopulatedObject(final Field field, final Collection fieldValue) { final Class genericClass = getReflectionUtils().getArgumentTypeClass(fieldValue, field.getDeclaringClass().getName(), field.getName(), true); - return getPopulatedObject(field.getType(), getReflectionUtils().getGenericFieldType(field), fieldValue, genericClass, field.getName()); + return getPopulatedObject(field.getType(), getReflectionUtils().getGenericFieldType(field), fieldValue, genericClass); } /** @@ -55,8 +55,7 @@ public Collection getPopulatedObject(final Field field, final Collection fiel */ @SuppressWarnings("unchecked") @Override - public Collection getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, - final Class nestedGenericClass, final String fieldName) { + public Collection getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { final Collection res; if (getClassUtils().isPrimitiveOrSpecialType(isNull(nestedGenericClass) ? genericFieldType : nestedGenericClass)) { res = (Collection) fieldValue; @@ -65,7 +64,7 @@ public Collection getPopulatedObject(final Class fieldType, final Class res = ((Collection) fieldValue) .stream() // .parallelStream() - .map(elem -> transform(elem, (Class) genericFieldType, fieldName)) + .map(elem -> transform(elem, (Class) genericFieldType)) .collect(collector); } return res; diff --git a/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java index 99a8e5c94..8bd1ca44b 100644 --- a/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java @@ -27,8 +27,7 @@ interface ICollectionPopulator { * @param genericFieldType the field to be populated class * @param fieldValue the source object from which extract the values * @param nestedGenericClass the nested generic object class. i.e. in case of object like this: {@code List>} the value is: String - * @param fieldName the field name under process * @return a populated list of elements */ - O getPopulatedObject(Class fieldType, Class genericFieldType, Object fieldValue, Class nestedGenericClass, String fieldName); + O getPopulatedObject(Class fieldType, Class genericFieldType, Object fieldValue, Class nestedGenericClass); } diff --git a/src/main/java/com/hotels/beans/populator/MapPopulator.java b/src/main/java/com/hotels/beans/populator/MapPopulator.java index f72d5acd2..f019b56d7 100644 --- a/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -45,17 +45,16 @@ class MapPopulator extends Populator> { @Override public Map getPopulatedObject(final Field field, final Map fieldValue) { final MapType mapGenericType = getReflectionUtils().getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); - return getPopulatedObject(fieldValue, mapGenericType, field.getName()); + return getPopulatedObject(fieldValue, mapGenericType); } /** * Populates the Map objects. * @param fieldValue the source Map. * @param mapType the map key, elem types {@link MapType} - * @param fieldName the name of the field under process * @return the populated map */ - private Map getPopulatedObject(final Map fieldValue, final MapType mapType, final String fieldName) { + private Map getPopulatedObject(final Map fieldValue, final MapType mapType) { final MapElemType keyType = mapType.getKeyType(); final MapElemType elemType = mapType.getElemType(); final boolean keyIsPrimitive = keyType.getClass().equals(ItemType.class) && getClassUtils().isPrimitiveOrSpecialType(((ItemType) keyType).getObjectClass()); @@ -68,8 +67,8 @@ class MapPopulator extends Populator> { .stream() // .parallelStream() .collect(toMap( - key -> getElemValue(keyType, keyIsPrimitive, key, fieldName), - key -> getElemValue(elemType, elemIsPrimitive, fieldValue.get(key), fieldName))); + key -> getElemValue(keyType, keyIsPrimitive, key), + key -> getElemValue(elemType, elemIsPrimitive, fieldValue.get(key)))); } return populatedObject; } @@ -80,19 +79,18 @@ class MapPopulator extends Populator> { * @param mapElemType the map key, elem types {@link MapElemType} * @param elemIsPrimitiveType true if the elem map is primitive type, false otherwise. * @param value the elem value - * @param fieldName the name of the field under process * @return the element value */ @SuppressWarnings("unchecked") - private T getElemValue(final MapElemType mapElemType, final boolean elemIsPrimitiveType, final T value, final String fieldName) { + private T getElemValue(final MapElemType mapElemType, final boolean elemIsPrimitiveType, final T value) { final T elemValue; if (elemIsPrimitiveType || getClassUtils().isPrimitiveOrSpecialType(value.getClass())) { elemValue = value; } else { if (mapElemType.getClass().equals(ItemType.class)) { - elemValue = (T) transform(value, ((ItemType) mapElemType).getObjectClass(), ((ItemType) mapElemType).getGenericClass(), fieldName); + elemValue = (T) transform(value, ((ItemType) mapElemType).getObjectClass(), ((ItemType) mapElemType).getGenericClass()); } else { - elemValue = (T) getPopulatedObject((Map) value, (MapType) mapElemType, fieldName); + elemValue = (T) getPopulatedObject((Map) value, (MapType) mapElemType); } } return elemValue; diff --git a/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index ee597d1d4..cb8636e58 100644 --- a/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -44,7 +44,7 @@ public Object getPopulatedObject(final Field field, final Object fieldValue) { Object res = null; Optional optionalFieldValue = (Optional) fieldValue; if (optionalFieldValue.isPresent()) { - res = transform(optionalFieldValue.get(), field.getType(), field.getName()); + res = transform(optionalFieldValue.get(), field.getType()); } // if the field type in the target class is not an optional it puts the value inside an optional if (field.getType() == Optional.class) { diff --git a/src/main/java/com/hotels/beans/populator/Populator.java b/src/main/java/com/hotels/beans/populator/Populator.java index 75930a04d..95e52ad51 100644 --- a/src/main/java/com/hotels/beans/populator/Populator.java +++ b/src/main/java/com/hotels/beans/populator/Populator.java @@ -85,13 +85,12 @@ public final O getPopulatedObject(final Class targetClass, final String f * Wrapper method for BeanUtil transform method. * @param sourceObj the source object * @param targetClass the destination object class - * @param fieldName the name of field under process * @param the Source object type * @param the target object type * @return a copy of the source object into the destination object */ - final K transform(final T sourceObj, final Class targetClass, final String fieldName) { - return transform(sourceObj, targetClass, null, fieldName); + final K transform(final T sourceObj, final Class targetClass) { + return transform(sourceObj, targetClass, null); } /** @@ -100,20 +99,19 @@ final K transform(final T sourceObj, final Class targetClass, final St * @param targetClass the destination object class * @param nestedGenericClass the nested generic object class. i.e. in case of object like this: * {@code List>} the value is: String - * @param fieldName the name of field under process * @param the Source object type * @param the target object type * @return a copy of the source object into the destination object */ @SuppressWarnings("unchecked") - final K transform(final T sourceObj, final Class targetClass, final Class nestedGenericClass, final String fieldName) { + final K transform(final T sourceObj, final Class targetClass, final Class nestedGenericClass) { final K res; if (classUtils.isPrimitiveOrSpecialType(sourceObj.getClass())) { res = (K) sourceObj; } else { - final Optional optPopulator = getPopulator(targetClass, sourceObj.getClass(), transformer, fieldName); + final Optional optPopulator = getPopulator(targetClass, sourceObj.getClass(), transformer); res = (K) optPopulator - .map(populator -> ((ICollectionPopulator) populator).getPopulatedObject(targetClass, targetClass, sourceObj, nestedGenericClass, fieldName)) + .map(populator -> ((ICollectionPopulator) populator).getPopulatedObject(targetClass, targetClass, sourceObj, nestedGenericClass)) .orElseGet(() -> transformer.transform(sourceObj, targetClass)); } return res; diff --git a/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/src/main/java/com/hotels/beans/populator/PopulatorFactory.java index cc1a8d0ca..fc68b1b52 100644 --- a/src/main/java/com/hotels/beans/populator/PopulatorFactory.java +++ b/src/main/java/com/hotels/beans/populator/PopulatorFactory.java @@ -52,38 +52,22 @@ public final class PopulatorFactory { * @param transformer the bean transformer containing the field name mapping and transformation functions * @return the populator instance */ - public static Optional getPopulator(final Class destObjectClass, final Class sourceObjectClass, final Transformer transformer) { - Optional populator = empty(); - if (destObjectClass.isArray()) { - populator = of(new ArrayPopulator(transformer)); - } else if (Collection.class.isAssignableFrom(destObjectClass)) { - populator = of(new CollectionPopulator(transformer)); - } else if (Map.class.isAssignableFrom(destObjectClass)) { - populator = of(new MapPopulator(transformer)); - } else if (Optional.class == sourceObjectClass || Optional.class == destObjectClass) { - populator = of(new OptionalPopulator(transformer)); - } - return populator; - } - - /** - * Creates an instance of the populator object based on the given class for the given field. - * @param the generic type of the contained object in the destination object - * @param the generic type of the contained object in the source object - * @param destObjectClass the destination object class - * @param sourceObjectClass the source object class - * @param transformer the bean transformer containing the field name mapping and transformation functions - * @param fieldName the name of the field to transform - * @return the populator instance - */ @SuppressWarnings("unchecked") - public static Optional getPopulator(final Class destObjectClass, final Class sourceObjectClass, final Transformer transformer, final String fieldName) { - String cacheKey = "FieldPopulator-" + destObjectClass.getCanonicalName() + "-" + fieldName; + public static Optional getPopulator(final Class destObjectClass, final Class sourceObjectClass, final Transformer transformer) { + String cacheKey = "FieldPopulator-" + destObjectClass.getCanonicalName(); return ofNullable(CACHE_MANAGER.getFromCache(cacheKey, Optional.class)) .orElseGet(() -> { - Optional populator = PopulatorFactory.getPopulator(destObjectClass, sourceObjectClass, transformer); - CACHE_MANAGER.cacheObject(cacheKey, populator); + Optional populator = empty(); + if (destObjectClass.isArray()) { + populator = of(new ArrayPopulator(transformer)); + } else if (Collection.class.isAssignableFrom(destObjectClass)) { + populator = of(new CollectionPopulator(transformer)); + } else if (Map.class.isAssignableFrom(destObjectClass)) { + populator = of(new MapPopulator(transformer)); + } else if (Optional.class == sourceObjectClass || Optional.class == destObjectClass) { + populator = of(new OptionalPopulator(transformer)); + } return populator; - }); + }); } } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 54b4b733b..44112c460 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -350,7 +350,7 @@ private Object getTransformedField(final Field field, final String breadcrumb, f */ @SuppressWarnings("unchecked") private Object getFieldValue(final Class targetClass, final Field field, final Object fieldValue, final String breadcrumb) { - return getPopulator(field.getType(), fieldValue.getClass(), this, field.getName()) + return getPopulator(field.getType(), fieldValue.getClass(), this) .map(populator -> populator.getPopulatedObject(targetClass, field.getName(), fieldValue)) .orElseGet(() -> // recursively inject object diff --git a/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/src/test/java/com/hotels/beans/performance/PerformanceTest.java index 61b290c0c..3822a4012 100644 --- a/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -51,7 +51,6 @@ import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.sample.mutable.MutableToFooSubClass; -import com.hotels.beans.transformer.Transformer; import lombok.extern.slf4j.Slf4j; @@ -91,7 +90,6 @@ public class PerformanceTest { private final Object sourceObject; private final Class destObjectClass; private final double maxTransformationTime; - private final boolean disableValidation; /** * The class to be tested. @@ -105,16 +103,14 @@ public class PerformanceTest { * @param waitInterval time between one transformation and the other * @param sourceObject the Source object to copy * @param destObjectClass the total destination object - * @param disableValidation disables the java bean validation * @param maxTransformationTime expected maximum transformation time */ - public PerformanceTest(final double totalTransformation, final int waitInterval, final Object sourceObject, - final Class destObjectClass, final boolean disableValidation, final double maxTransformationTime) { + public PerformanceTest(final double totalTransformation, final int waitInterval, + final Object sourceObject, final Class destObjectClass, final double maxTransformationTime) { this.totalTransformation = totalTransformation; this.waitInterval = waitInterval; this.sourceObject = sourceObject; this.destObjectClass = destObjectClass; - this.disableValidation = disableValidation; this.maxTransformationTime = maxTransformationTime; } @@ -138,12 +134,11 @@ public void testCopyPropertiesGetsCompletedInTheExpectedTime() throws Interrupte //WHEN StopWatch stopWatch = new StopWatch(); stopWatch.start(); - Transformer beanTransformer = underTest.getTransformer().setValidationDisabled(disableValidation); for (int i = 0; i <= totalTransformation; i++) { stopWatch.suspend(); sleep(waitInterval); stopWatch.resume(); - beanTransformer.transform(sourceObject, destObjectClass); + underTest.getTransformer().transform(sourceObject, destObjectClass); } stopWatch.stop(); double avgTransformationTime = stopWatch.getTime(MILLISECONDS) / totalTransformation; @@ -214,11 +209,11 @@ private static FromFooSubClass createFromFooSubClass() { public static Collection dataProvider() { initObjects(); return asList(new Object[][]{ - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, MutableToFooSimple.class, true, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, MutableToFooSubClass.class, true, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, ImmutableToFooSimple.class, true, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, ImmutableToFooSubClass.class, true, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, - {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFoo, MixedToFoo.class, false, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME} + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, MutableToFooSimple.class, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, MutableToFooSubClass.class, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, ImmutableToFooSimple.class, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, ImmutableToFooSubClass.class, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, + {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFoo, MixedToFoo.class, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME} }); } } diff --git a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 34843b493..6643a99f8 100644 --- a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -51,7 +51,6 @@ public class ArrayPopulatorTest { private static final int ZERO = 0; private static final int[] INT_ARRAY = new int[] {ZERO}; private static final MixedToFooStaticField MIXED_TO_FOO_STATIC_FIELDS_OBJECTS = new MixedToFooStaticField(); - private static final String FIELD_NAME = "testField"; private final Class genericFieldType; private final Class nestedGenericClass; @@ -96,7 +95,7 @@ public void testGetPopulatedObjectWorksProperly() { when(transformer.transform(any(), eq(MixedToFooStaticField.class))).thenReturn(MIXED_TO_FOO_STATIC_FIELDS_OBJECTS); // WHEN - Object actual = underTest.getPopulatedObject(null, genericFieldType, array, nestedGenericClass, FIELD_NAME); + Object actual = underTest.getPopulatedObject(null, genericFieldType, array, nestedGenericClass); // THEN if (genericFieldType == Character.class) { From 2e4ddd70be16af4350ad1e56f9dffe2b95988fe8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 14:07:29 +0100 Subject: [PATCH 0277/1786] minor improvements --- src/main/java/com/hotels/beans/utils/ReflectionUtils.java | 2 +- .../hotels/beans/transformer/AbstractTransformerTest.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 62d67141d..7f0983617 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -233,7 +233,7 @@ private Object getFieldValue(final Object target, final String fieldName) { handleReflectionException(e); throw new IllegalStateException(e); } finally { - if (!isAccessible) { + if (nonNull(field) && !isAccessible) { field.setAccessible(false); } } diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index 6f2c112d6..244807411 100644 --- a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -32,6 +32,7 @@ */ public class AbstractTransformerTest { private static final String SOURCE_FIELD_NAME = "sourceFieldName"; + private static final String SOURCE_FIELD_NAME_2 = "sourceFieldName2"; private static final String DEST_FIELD_NAME = "destFieldName"; private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "transformerSettings"; private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); @@ -72,7 +73,7 @@ public void testRemoveFieldMappingWorksProperly() { @Test(expected = IllegalArgumentException.class) public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { //GIVEN - Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("sourceFieldName", DEST_FIELD_NAME)); + Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); //WHEN beanTransformer.removeFieldMapping(null); @@ -85,7 +86,7 @@ public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { public void testResetFieldsMappingWorksProperly() { //GIVEN Transformer beanTransformer = underTest - .withFieldMapping(new FieldMapping("sourceFieldName", DEST_FIELD_NAME), new FieldMapping("sourceFieldName2", DEST_FIELD_NAME)); + .withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME), new FieldMapping(SOURCE_FIELD_NAME_2, DEST_FIELD_NAME)); //WHEN beanTransformer.resetFieldsMapping(); From 98d5903ce32607f48d8cc1014ca5e2e76c3e224d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 18:20:36 +0100 Subject: [PATCH 0278/1786] Reverted all changes that were causing a performance degradation --- pom.xml | 3 + .../beans/populator/PopulatorFactory.java | 36 ++++------- .../transformer/AbstractTransformer.java | 55 ++-------------- .../beans/transformer/TransformerImpl.java | 10 +-- .../hotels/beans/utils/ReflectionUtils.java | 4 +- .../hotels/beans/utils/ValidationUtils.java | 64 +++++++++++++++++++ 6 files changed, 92 insertions(+), 80 deletions(-) diff --git a/pom.xml b/pom.xml index 6a6c96c88..2feafba9c 100644 --- a/pom.xml +++ b/pom.xml @@ -224,6 +224,9 @@ org.apache.maven.plugins maven-javadoc-plugin ${maven.javadoc.plugin.version} + + 8 + attach-javadocs diff --git a/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/src/main/java/com/hotels/beans/populator/PopulatorFactory.java index fc68b1b52..5e53f1a3f 100644 --- a/src/main/java/com/hotels/beans/populator/PopulatorFactory.java +++ b/src/main/java/com/hotels/beans/populator/PopulatorFactory.java @@ -18,9 +18,6 @@ import static java.util.Optional.empty; import static java.util.Optional.of; -import static java.util.Optional.ofNullable; - -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static lombok.AccessLevel.PRIVATE; @@ -28,7 +25,6 @@ import java.util.Map; import java.util.Optional; -import com.hotels.beans.cache.CacheManager; import com.hotels.beans.transformer.Transformer; import lombok.NoArgsConstructor; @@ -38,11 +34,6 @@ */ @NoArgsConstructor(access = PRIVATE) public final class PopulatorFactory { - /** - * The Cache manager for this class. - */ - private static final CacheManager CACHE_MANAGER = getCacheManager("populatorFactory"); - /** * Creates an instance of the populator object based on the given class. * @param the generic type of the contained object in the destination object @@ -52,22 +43,17 @@ public final class PopulatorFactory { * @param transformer the bean transformer containing the field name mapping and transformation functions * @return the populator instance */ - @SuppressWarnings("unchecked") public static Optional getPopulator(final Class destObjectClass, final Class sourceObjectClass, final Transformer transformer) { - String cacheKey = "FieldPopulator-" + destObjectClass.getCanonicalName(); - return ofNullable(CACHE_MANAGER.getFromCache(cacheKey, Optional.class)) - .orElseGet(() -> { - Optional populator = empty(); - if (destObjectClass.isArray()) { - populator = of(new ArrayPopulator(transformer)); - } else if (Collection.class.isAssignableFrom(destObjectClass)) { - populator = of(new CollectionPopulator(transformer)); - } else if (Map.class.isAssignableFrom(destObjectClass)) { - populator = of(new MapPopulator(transformer)); - } else if (Optional.class == sourceObjectClass || Optional.class == destObjectClass) { - populator = of(new OptionalPopulator(transformer)); - } - return populator; - }); + Optional populator = empty(); + if (destObjectClass.isArray()) { + populator = of(new ArrayPopulator(transformer)); + } else if (Collection.class.isAssignableFrom(destObjectClass)) { + populator = of(new CollectionPopulator(transformer)); + } else if (Map.class.isAssignableFrom(destObjectClass)) { + populator = of(new MapPopulator(transformer)); + } else if (Optional.class == sourceObjectClass || Optional.class == destObjectClass) { + populator = of(new OptionalPopulator(transformer)); + } + return populator; } } diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 91e67f69b..5d0943594 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -16,31 +16,18 @@ package com.hotels.beans.transformer; -import static java.util.Optional.ofNullable; -import static java.util.stream.Collectors.joining; - -import static javax.validation.Validation.buildDefaultValidatorFactory; - -import static org.apache.commons.lang3.StringUtils.SPACE; - -import static com.hotels.beans.constant.Punctuation.DOT; -import static com.hotels.beans.constant.Punctuation.SEMICOLON; import static com.hotels.beans.utils.ValidationUtils.notNull; import java.util.Map; -import java.util.Set; import java.util.function.Function; -import javax.validation.Validator; -import javax.validation.ConstraintViolation; - import com.hotels.beans.cache.CacheManager; import com.hotels.beans.cache.CacheManagerFactory; -import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; +import com.hotels.beans.utils.ValidationUtils; import lombok.Getter; @@ -60,6 +47,11 @@ abstract class AbstractTransformer implements Transformer { */ private final ClassUtils classUtils; + /** + * Validation utils class {@link ValidationUtils}. + */ + private final ValidationUtils validationUtils; + /** * CacheManager class {@link CacheManager}. */ @@ -76,6 +68,7 @@ abstract class AbstractTransformer implements Transformer { AbstractTransformer() { this.reflectionUtils = new ReflectionUtils(); this.classUtils = new ClassUtils(); + this.validationUtils = new ValidationUtils(); this.transformerSettings = new TransformerSettings(); this.cacheManager = CacheManagerFactory.getCacheManager("transformer"); } @@ -176,40 +169,6 @@ public final K transform(final T sourceObj, final Class targ return transform(sourceObj, targetClass, null); } - /** - * Checks if an object is valid. - * @param k the object to check - * @param the object class - * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails - */ - final void validate(final K k) { - final Set> constraintViolations = getValidator().validate(k); - if (!constraintViolations.isEmpty()) { - final String errors = constraintViolations.stream() - .map(cv -> cv.getRootBeanClass().getCanonicalName() - + DOT.getSymbol() - + cv.getPropertyPath() - + SPACE - + cv.getMessage()) - .collect(joining(SEMICOLON.getSymbol())); - throw new InvalidBeanException(errors); - } - } - - /** - * Creates the validator. - * @return a {@link Validator} instance. - */ - private Validator getValidator() { - String cacheKey = "BeanValidator"; - return ofNullable(cacheManager.getFromCache(cacheKey, Validator.class)) - .orElseGet(() -> { - Validator validator = buildDefaultValidatorFactory().getValidator(); - cacheManager.cacheObject(cacheKey, validator); - return validator; - }); - } - /** * Copies all properties from an object to a new one. * @param sourceObj the source object diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 44112c460..ffd086081 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -23,13 +23,13 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; -import static com.hotels.beans.base.Defaults.defaultValue; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.Punctuation.COMMA; import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.constant.Punctuation.COMMA; import static com.hotels.beans.constant.Punctuation.LPAREN; import static com.hotels.beans.constant.Punctuation.RPAREN; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; +import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; @@ -71,7 +71,7 @@ protected final K transform(final T sourceObj, final Class t } } if (!getTransformerSettings().isValidationDisabled()) { - validate(k); + getValidationUtils().validate(k); } return k; } diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 7f0983617..b606c8f5d 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -280,13 +280,13 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f /** * Check if a field is accessible or not. - * To make the project compiling with Java version <= 8, replace the following line with: {@code field.isAccessible();} + * To make the project compiling with Java version > 8, replace the following line with: {@code field.canAccess(target);} * @param field the field to check * @param target the field's class * @return true id is accessible, false otherwise */ private boolean isFieldAccessible(final Field field, final Object target) { - return field.canAccess(target); + return field.isAccessible(); } /** diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java index b49554872..f1a1d4b36 100644 --- a/src/main/java/com/hotels/beans/utils/ValidationUtils.java +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -17,11 +17,41 @@ package com.hotels.beans.utils; import static java.util.Objects.isNull; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.joining; + +import static javax.validation.Validation.buildDefaultValidatorFactory; + +import static org.apache.commons.lang3.StringUtils.SPACE; + +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.constant.Punctuation.SEMICOLON; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validator; + +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.error.InvalidBeanException; /** * Validation utils for Class objects. */ public class ValidationUtils { + /** + * CacheManager class {@link CacheManager}. + */ + private final CacheManager cacheManager; + + /** + * Default constructor. + */ + public ValidationUtils() { + this.cacheManager = getCacheManager("validationUtils"); + } + /** * Validate that the specified argument is not {@code null}; * otherwise throws an {@link IllegalArgumentException} with the specified message. @@ -48,4 +78,38 @@ public static void notNull(final T object, final String message) { throw new IllegalArgumentException(message); } } + + /** + * Checks if an object is valid. + * @param k the object to check + * @param the object class + * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails + */ + public final void validate(final K k) { + final Set> constraintViolations = getValidator().validate(k); + if (!constraintViolations.isEmpty()) { + final String errors = constraintViolations.stream() + .map(cv -> cv.getRootBeanClass().getCanonicalName() + + DOT.getSymbol() + + cv.getPropertyPath() + + SPACE + + cv.getMessage()) + .collect(joining(SEMICOLON.getSymbol())); + throw new InvalidBeanException(errors); + } + } + + /** + * Creates the validator. + * @return a {@link Validator} instance. + */ + private Validator getValidator() { + String cacheKey = "BeanValidator"; + return ofNullable(cacheManager.getFromCache(cacheKey, Validator.class)) + .orElseGet(() -> { + Validator validator = buildDefaultValidatorFactory().getValidator(); + cacheManager.cacheObject(cacheKey, validator); + return validator; + }); + } } From ef9257d36266d88fee0e06f6d9f205b0f75884aa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 18:37:23 +0100 Subject: [PATCH 0279/1786] - Updated change log with the changes implemented - raised project version as the migration to java 11 is a major change --- CHANGELOG.md | 10 +++++++--- pom.xml | 5 +---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0eab5e76..ec33dc235 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,14 @@ All notable changes to this project will be documented in this file. -### [1.1.5] TBD +### [1.2.0] 2019.02.25 #### Added -* Upgraded to Java 11 -* Added possibility to skip the object validation +* Added possibility to skip the object validation (see: [Issue 31](https://github.com/HotelsDotCom/bull/issues/31)) +* Added documentation and samples for the above functionality +### Changed +- Updated `jdk` version to 11 (was 1.8). +- Updated Travis configuration in order to work with java 11 +- Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created ### [1.1.4] 2019.02.20 #### Added diff --git a/pom.xml b/pom.xml index 2feafba9c..074bc38d3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.5-SNAPSHOT + 1.2.0-SNAPSHOT jar 2019 @@ -224,9 +224,6 @@ org.apache.maven.plugins maven-javadoc-plugin ${maven.javadoc.plugin.version} - - 8 - attach-javadocs From 2427ad6e3dd8c4f674d1fae849f5d975ed155f28 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 18:46:51 +0100 Subject: [PATCH 0280/1786] [maven-release-plugin] prepare release 1.2.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 074bc38d3..d0c38133c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.0-SNAPSHOT + 1.2.0 jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.0 From db8f1c2ee60bae35f9cdd2c73525b3112e267fba Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 25 Feb 2019 18:46:58 +0100 Subject: [PATCH 0281/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d0c38133c..58a3053de 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.0 + 1.2.1-SNAPSHOT jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.0 + HEAD From c97f2ef83dccaba9dd12a4352fda4500ad8579f9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 28 Feb 2019 18:31:08 +0100 Subject: [PATCH 0282/1786] [issue-33] Added samples on how to test the library --- docs/site/markdown/transformer/testing.md | 398 ++++++++++++++++++++++ docs/site/site.xml | 1 + 2 files changed, 399 insertions(+) create mode 100644 docs/site/markdown/transformer/testing.md diff --git a/docs/site/markdown/transformer/testing.md b/docs/site/markdown/transformer/testing.md new file mode 100644 index 000000000..e0358b63f --- /dev/null +++ b/docs/site/markdown/transformer/testing.md @@ -0,0 +1,398 @@ + + Test your library + + +# Overview + +Software testing plays a fundamental role in the software development because we can evaluate one or more properties of interest. In general, these properties indicate the +extent to which the component or system under test: + +* meets the requirements that guided its design and development, +* responds correctly to all kinds of inputs, +* performs its functions within an acceptable time, +* it is sufficiently usable, +* can be installed and run in its intended environments +* achieves the general result its stakeholders desire. + +This page will show how to test BULL into a simple project. All the examples utilizes [JUnit](https://github.com/junit-team) and [Mockito](https://site.mockito.org/). + +The Java Bean transformation function can be tested in two different ways that depends on the following scenarios: + +1. The destination object does not require a special configuration to get transformed +2. The destination object requires a special configuration, but you are confident that the configuration is working fine as it doesn't includes any special action +3. The destination object requires a special configuration that needs to be tested as we are not confident that it would work + +For both scenarios: 1 and 2 we can use a mocked version the `BeanUtils` object. + +### Before start + +As BULL contains final methods that needs to be mocked and, as Mockito requires a special configuration in order to mock final classes/methods, an extension needs +to be added to the test resource folder. This file is available [here](https://github.com/HotelsDotCom/bull/tree/master/src/test/resources/mockito-extensions). + +All the examples will be based on the following source object and destination object: + +~~~Java +public class SampleRequest { public class DestObject { + private final BigInteger x; @NotNull + private final BigInteger y; private BigInteger x; + private final BigInteger y; + // constructors // constructors + // getters and setters // getters and setters +} } +~~~ + +### First scenario + +#####The destination object does not require a special configuration to get transformed + +Given the following service class that contains the `BeanUtils` library: +~~~Java +import ... + +public class SampleClass { + + private final BeanUtils beanUtils; + + public SampleClass() { + this.beanUtils = new BeanUtils(); + } + + public BigInteger doSomething(final SampleRequest request) { + final Transformer beanTransformer = beanUtils.getTransformer(); + DestObject destObject = beanTransformer.transform(request, DestObject.class); + return multiplyValues(destObject.getX(), destObject.getY()); + } + + private BigInteger multiplyValues(final BigInteger x, final BigInteger y) { + return x.multiply(y); + } +} +~~~ +The test class will be: +~~~Java +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.mock; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.transformer.BeanUtils; +import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.error.InvalidBeanException; + +/** + * Unit test for {@link SampleClass}. + */ +public class SampleClassTest { + private static final BigInteger EXPECTED_RESULT = new BigInteger(20); + /** + * The class to be tested. + */ + @InjectMocks + private SampleClass underTest; + + @Mock + private BeanUtils beanUtils; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + } + + /** + * Test that a SampleResponse is returned. + */ + @Test + public void testDoSomethingWorksProperly() { + //GIVEN + SampleRequest sampleRequest = createSampleRequest(BigInteger.TEN, BigInteger.TWO); + DestObject destObject = createDestObject(BigInteger.TEN, BigInteger.TWO); + Transformer beanTransformer = mock(Transformer.class); + when(beanUtils.getTransformer()).thenReturn(beanTransformer); + when(beanTransformer.transform(sampleRequest, DestObject.class)).thenReturn(destObject); + + //WHEN + final BigInteger actual = underTest.doSomething(sampleRequest); + + //THEN + verify(beanUtils).getTransformer(); + verify(beanTransformer).transform(sampleRequest, DestObject.class); + assertEquals(EXPECTED_RESULT, actual); + } + + /** + * Test that an {@link InvalidBeanException} is thrown when the {@code id} field in the {@link SampleRequest} + * doesn't met the constraints defined into {@link DestObject}. + */ + @Test(expected = InvalidBeanException.class) + public void testThatAnExceptionIsThrownWhenConstraintsAreNotMet() { + //GIVEN + SampleRequest sampleRequest = createSampleRequest(null, BigInteger.TWO); + Transformer beanTransformer = mock(Transformer.class); + when(beanUtils.getTransformer()).thenReturn(beanTransformer); + when(beanTransformer.transform(sampleRequest, DestObject.class)).thenThrow(InvalidBeanException.class); + + //WHEN + final BigInteger actual = underTest.doSomething(sampleRequest); + + //THEN + } + + private SampleRequest createSampleRequest(final BigInteger x, final BigInteger y) { + return new SampleRequest(); + } + + private DestObject createDestObject(final BigInteger x, final BigInteger y) { + return new DestObject(x, y); + } +} +~~~ + +### Second scenario: + +#####The destination object requires a special configuration, but you are confident that the configuration is working fine as it doesn't includes any particular instruction. + +Given the following service class: +~~~Java +import ... + +public class SampleClass { + + private final BeanUtils beanUtils; + + public SampleClass() { + this.beanUtils = new BeanUtils(); + } + + public BigInteger doSomething(final SampleRequest request) { + final Transformer beanTransformer = beanUtils.getTransformer(); + FieldTransformer prodTransformer = new FieldTransformer<>("y", val -> val.multiply(BigInteger.TWO)); + DestObject destObject = beanTransformer + .withFieldTransformer(prodTransformer) + .transform(request, DestObject.class); + return multiplyValues(destObject.getX(), destObject.getY()); + } + + private BigInteger multiplyValues(final BigInteger x, final BigInteger y) { + return x.multiply(y); + } +} +~~~ +The test class will be: +~~~Java +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.ArgumentMatchers.any; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.transformer.BeanUtils; +import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.error.InvalidBeanException; + +/** + * Unit test for {@link SampleClass}. + */ +public class SampleClassTest { + private static final BigInteger EXPECTED_RESULT = new BigInteger(40); + /** + * The class to be tested. + */ + @InjectMocks + private SampleClass underTest; + + @Mock + private BeanUtils beanUtils; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + } + + /** + * Test that a SampleResponse is returned. + */ + @Test + public void testDoSomethingWorksProperly() { + //GIVEN + SampleRequest sampleRequest = createSampleRequest(BigInteger.TEN, BigInteger.TWO); + DestObject destObject = createDestObject(BigInteger.TEN, BigInteger.TWO.multiply(BigInteger.TWO)); + Transformer beanTransformer = mock(Transformer.class); + when(beanUtils.getTransformer()).thenReturn(beanTransformer); + when(beanTransformer.withFieldTransformer(any(FieldTransformer.class))).thenReturn(beanTransformer); + when(beanTransformer.transform(sampleRequest, DestObject.class)).thenReturn(destObject); + + //WHEN + final BigInteger actual = underTest.doSomething(sampleRequest); + + //THEN + verify(beanUtils).getTransformer(); + verify(beanTransformer).withFieldTransformer(any(FieldTransformer.class)); + verify(beanTransformer).transform(sampleRequest, DestObject.class); + assertEquals(EXPECTED_RESULT, actual); + } + + /** + * Test that an {@link InvalidBeanException} is thrown when the {@code id} field in the {@link SampleRequest} + * doesn't met the constraints defined into {@link DestObject}. + */ + @Test(expected = InvalidBeanException.class) + public void testThatAnExceptionIsThrownWhenConstraintsAreNotMet() { + //GIVEN + SampleRequest sampleRequest = createSampleRequest(null, BigInteger.TWO); + Transformer beanTransformer = mock(Transformer.class); + when(beanUtils.getTransformer()).thenReturn(beanTransformer); + when(beanTransformer.withFieldTransformer(any(FieldTransformer.class))).thenReturn(beanTransformer); + when(beanTransformer.transform(sampleRequest, DestObject.class)).thenThrow(InvalidBeanException.class); + + //WHEN + final BigInteger actual = underTest.doSomething(sampleRequest); + + //THEN + } + + private SampleRequest createSampleRequest(final BigInteger x, final BigInteger y) { + return new SampleRequest(); + } + + private DestObject createDestObject(final BigInteger x, final BigInteger y) { + return new DestObject(x, y); + } +} +~~~ + +### Third scenario: + +#####The destination object requires a special configuration that needs to be tested as you are not confident that it would work + +Given the following service class: +~~~Java +import ... + +public class SampleClass { + + private final BeanUtils beanUtils; + + public SampleClass() { + this.beanUtils = new BeanUtils(); + } + + public BigInteger doSomething(final SampleRequest request) { + final Transformer beanTransformer = beanUtils.getTransformer(); + FieldTransformer prodTransformer = new FieldTransformer<>("y", val -> val.multiply(BigInteger.TWO)); + DestObject destObject = beanTransformer + .withFieldTransformer(prodTransformer) + .transform(request, DestObject.class); + return multiplyValues(destObject.getX(), destObject.getY()); + } + + private BigInteger multiplyValues(final BigInteger x, final BigInteger y) { + return x.multiply(y); + } +} +~~~ +The test class will be: +~~~Java +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.lang.reflect.Field; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.transformer.BeanUtils; + +/** + * Unit test for {@link SampleClass}. + */ +public class SampleClassTest { + private static final BigInteger EXPECTED_RESULT = new BigInteger(40); + /** + * The class to be tested. + */ + @InjectMocks + private SampleClass underTest; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + // injects a real BeanUtils instance into the test class + setFieldValue(underTest, "beanUtils", new BeanUtils()); + } + + /** + * Test that a SampleResponse is returned. + */ + @Test + public void testDoSomethingWorksProperly() { + //GIVEN + SampleRequest sampleRequest = createSampleRequest(BigInteger.TEN, BigInteger.TWO); + + //WHEN + final BigInteger actual = underTest.doSomething(sampleRequest); + + //THEN + assertEquals(EXPECTED_RESULT, actual); + } + + /** + * Test that an {@link InvalidBeanException} is thrown when the {@code id} field in the {@link SampleRequest} + * doesn't met the constraints defined into {@link DestObject}. + */ + @Test(expected = InvalidBeanException.class) + public void testThatAnExceptionIsThrownWhenConstraintsAreNotMet() { + //GIVEN + SampleRequest sampleRequest = createSampleRequest(null, BigInteger.TWO); + + //WHEN + final BigInteger actual = underTest.doSomething(sampleRequest); + + //THEN + } + + private SampleRequest createSampleRequest(final BigInteger x, final BigInteger y) { + return new SampleRequest(); + } + + /** + * Sets the value of a field through {@link Field#set} method. + * @param target the field's class + * @param fieldName the field's name to set + * @param fieldValue the value to set + */ + private void setFieldValue(final Object target, final String fieldName, final Object fieldValue) throws NoSuchFieldException { + final Field field = target.getClass().getDeclaredField(fieldName); + final boolean isAccessible = field.canAccess(target); + try { + if (!isAccessible) { + field.setAccessible(true); + } + field.set(target, fieldValue); + } catch (final Exception e) { + throw new IllegalStateException(e); + } finally { + if (!isAccessible) { + field.setAccessible(false); + } + } + } +} +~~~ diff --git a/docs/site/site.xml b/docs/site/site.xml index 73278ae57..ecdc6a697 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -30,6 +30,7 @@ + From 15f08a7acf82259825539bb03079475c108f62b3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Mar 2019 14:57:07 +0100 Subject: [PATCH 0283/1786] Added link to the library testing guide into readme file --- README.md | 2 +- pom.xml | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index 543a459b3..8058014df 100644 --- a/README.md +++ b/README.md @@ -431,7 +431,7 @@ Following the obtained results: ## Documentation -A detailed project documentation is available [here](https://hotelsdotcom.github.io/bull). +A detailed project documentation is available [here](https://hotelsdotcom.github.io/bull), including some samples for [testing the library](https://hotelsdotcom.github.io/bull/transformer/testing.html) inside your project. ## Credits diff --git a/pom.xml b/pom.xml index 58a3053de..0b7ff4a61 100644 --- a/pom.xml +++ b/pom.xml @@ -102,11 +102,6 @@ hibernate-validator ${hibernate-validator.version} - - org.hibernate.validator - hibernate-validator-annotation-processor - ${hibernate-validator.version} - org.springframework.boot From 8eb5b1cb432d548d020826e280e36f4dfae6df95 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Mar 2019 15:35:53 +0100 Subject: [PATCH 0284/1786] Added new feature that allows to copy on existing object instances --- CHANGELOG.md | 3 ++ .../transformer/AbstractTransformer.java | 20 ++++++++++++ .../hotels/beans/transformer/Transformer.java | 10 ++++++ .../beans/transformer/TransformerImpl.java | 32 +++++++++++++++++-- .../com/hotels/beans/utils/ClassUtils.java | 16 ++++++++++ .../beans/transformer/TransformerTest.java | 21 +++++++++++- 6 files changed, 98 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec33dc235..8bdf949f3 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +### [1.2.1] TBD +#### Added +* Implemented new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) ### [1.2.0] 2019.02.25 #### Added * Added possibility to skip the object validation (see: [Issue 31](https://github.com/HotelsDotCom/bull/issues/31)) diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 5d0943594..b8437ab70 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -179,4 +179,24 @@ public final K transform(final T sourceObj, final Class targ * @return a copy of the source object into the destination object */ protected abstract K transform(T sourceObj, Class targetClass, String breadcrumb); + + /** + * {@inheritDoc} + */ + @Override + public final void transform(final T sourceObj, final K targetObject) { + notNull(sourceObj, "The object to copy cannot be null!"); + notNull(targetObject, "The destination object cannot be null!"); + transform(sourceObj, targetObject, null); + } + + /** + * Copies all properties from an object to a new one. + * @param sourceObj the source object + * @param targetObject the destination object + * @param breadcrumb the full path of the current field starting from his ancestor + * @param the Source object type + * @param the target object type + */ + protected abstract void transform(T sourceObj, K targetObject, String breadcrumb); } diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index 6982711f3..986a607e4 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -35,6 +35,16 @@ public interface Transformer { */ K transform(T sourceObj, Class targetClass); + /** + * Copies all properties from an object to a new one. + * @param sourceObj the source object + * @param targetObject the destination object + * @param the Source object type + * @param the target object type + * @throws IllegalArgumentException if any parameter is invalid + */ + void transform(T sourceObj, K targetObject); + /** * Initializes the mapping between fields in the source object and the destination one. * @param fieldMapping the field mapping diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index ffd086081..469f9380f 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -58,7 +58,7 @@ protected final K transform(final T sourceObj, final Class t if (classType.is(MUTABLE)) { try { k = targetClass.getDeclaredConstructor().newInstance(); - injectNotFinalFields(sourceObj, k, breadcrumb); + injectAllFields(sourceObj, k, breadcrumb); } catch (NoSuchMethodException e) { throw new InvalidBeanException("No default constructor defined for class: " + targetClass.getName(), e); } catch (Exception e) { @@ -76,6 +76,17 @@ protected final K transform(final T sourceObj, final Class t return k; } + /** + * {@inheritDoc} + */ + @Override + protected final void transform(final T sourceObj, final K targetObject, final String breadcrumb) { + injectAllFields(sourceObj, targetObject, breadcrumb); + if (!getTransformerSettings().isValidationDisabled()) { + getValidationUtils().validate(targetObject); + } + } + /** * Inject the values through the all args constructor. * @param sourceObj sourceObj the source object @@ -226,8 +237,23 @@ private Object[] getConstructorValuesFromFields(final T sourceObj, final } /** - * Retrieves all the constructor argument values. - * This methods retrieves the values from the declared class field into the target object. + * Injects the values for all class fields. + * @param sourceObj sourceObj the source object + * @param targetObject the destination object instance + * @param breadcrumb the full path of the current field starting from his ancestor + * @param the sourceObj object type + * @param the target object type + * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value + */ + private void injectAllFields(final T sourceObj, final K targetObject, final String breadcrumb) { + final Class targetObjectClass = targetObject.getClass(); + getClassUtils().getFields(targetObjectClass, true) + //.parallelStream() + .forEach(field -> getReflectionUtils().setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); + } + + /** + * Injects the values for all the not final fields. * @param sourceObj sourceObj the source object * @param targetObject the destination object instance * @param breadcrumb the full path of the current field starting from his ancestor diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 0a4d84e1d..fde873215 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -650,6 +650,22 @@ public Object getDefaultTypeValue(final Class objectType) { }); } + /** + * Returns all class fields. + * @param clazz the class containing fields. + * @param skipStatic if true the static fields are skipped. + * @return a list containing all the not final fields. + */ + @SuppressWarnings("unchecked") + public List getFields(final Class clazz, final Boolean skipStatic) { + final String cacheKey = "ClassFields-" + clazz.getCanonicalName() + "-" + skipStatic; + return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + List notFinalFields = new ArrayList<>(getDeclaredFields(clazz, skipStatic)); + cacheManager.cacheObject(cacheKey, notFinalFields); + return notFinalFields; + }); + } + /** * Returns all the not final fields. * @param clazz the class containing fields. diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 9877bd9f1..ce43e81e7 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -76,6 +76,7 @@ import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; +import com.hotels.beans.sample.immutable.ImmutableToFooSimple; import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mixed.MixedToFooDiffFields; import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; @@ -85,6 +86,7 @@ import com.hotels.beans.sample.mutable.MutableToFooInvalid; import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; +import com.hotels.beans.sample.mutable.MutableToFooSubClass; import com.hotels.beans.utils.ReflectionUtils; /** @@ -148,7 +150,6 @@ public void beforeMethod() { initMocks(this); } - /** * Test that is possible to remove all the fields transformer defined. */ @@ -717,6 +718,24 @@ public void testTransformationReturnsAMeaningfulException() { assertEquals(expectedExceptionMessage, raisedException.getMessage()); } + /** + * Test transformation on an existing bean is correctly copied. + */ + @Test + public void testTransformationOnAnExistingDestinationWorksProperly() { + //GIVEN + MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); + ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null); + + //WHEN + underTest.transform(fromFooSubClass, mutableToFoo); + underTest.transform(fromFooSimple, immutableToFoo); + + //THEN + assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); + assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); + } + /** * Initializes the mocks required for testing method: {@code getDestFieldName}. * @param declaringClassName the declaring class name From 0689e23ad0771026f89ad07348e885957b77d1c7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 2 Mar 2019 17:07:04 +0100 Subject: [PATCH 0285/1786] Removed redundant method --- .../beans/transformer/TransformerImpl.java | 2 +- .../java/com/hotels/beans/utils/ClassUtils.java | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 469f9380f..d73243d2b 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -247,7 +247,7 @@ private Object[] getConstructorValuesFromFields(final T sourceObj, final */ private void injectAllFields(final T sourceObj, final K targetObject, final String breadcrumb) { final Class targetObjectClass = targetObject.getClass(); - getClassUtils().getFields(targetObjectClass, true) + getClassUtils().getDeclaredFields(targetObjectClass, true) //.parallelStream() .forEach(field -> getReflectionUtils().setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); } diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index fde873215..0a4d84e1d 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -650,22 +650,6 @@ public Object getDefaultTypeValue(final Class objectType) { }); } - /** - * Returns all class fields. - * @param clazz the class containing fields. - * @param skipStatic if true the static fields are skipped. - * @return a list containing all the not final fields. - */ - @SuppressWarnings("unchecked") - public List getFields(final Class clazz, final Boolean skipStatic) { - final String cacheKey = "ClassFields-" + clazz.getCanonicalName() + "-" + skipStatic; - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { - List notFinalFields = new ArrayList<>(getDeclaredFields(clazz, skipStatic)); - cacheManager.cacheObject(cacheKey, notFinalFields); - return notFinalFields; - }); - } - /** * Returns all the not final fields. * @param clazz the class containing fields. From 8efd7f8250a8f6c401484a914d435d36cf6b294d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Mar 2019 08:45:58 +0100 Subject: [PATCH 0286/1786] Modified access to superclass variables --- config/checkstyle/suppression.xml | 2 +- .../beans/populator/ArrayPopulator.java | 4 +- .../beans/populator/CollectionPopulator.java | 6 +- .../hotels/beans/populator/MapPopulator.java | 8 +-- .../com/hotels/beans/populator/Populator.java | 18 ++---- .../transformer/AbstractTransformer.java | 41 ++++++------- .../beans/transformer/TransformerImpl.java | 60 +++++++++---------- .../com/hotels/beans/utils/ClassUtils.java | 2 +- .../hotels/beans/utils/ReflectionUtils.java | 36 +++++++++-- .../transformer/AbstractTransformerTest.java | 2 +- .../beans/transformer/TransformerTest.java | 2 +- 11 files changed, 99 insertions(+), 82 deletions(-) diff --git a/config/checkstyle/suppression.xml b/config/checkstyle/suppression.xml index 9ff874c91..cc863da25 100644 --- a/config/checkstyle/suppression.xml +++ b/config/checkstyle/suppression.xml @@ -13,7 +13,7 @@ - + diff --git a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index e15db2b5d..cd9180f7c 100644 --- a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -21,7 +21,6 @@ import java.lang.reflect.Field; import com.hotels.beans.transformer.Transformer; -import com.hotels.beans.utils.ClassUtils; /** * Populator for primitive types array. @@ -41,7 +40,7 @@ class ArrayPopulator extends Populator implements ICollectionPopulator fieldType, final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { final Object res; - final ClassUtils classUtils = getClassUtils(); if (classUtils.isPrimitiveTypeArray(fieldValue) || classUtils.isPrimitiveOrSpecialType(genericFieldType)) { res = fieldValue; } else { diff --git a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index 5514eec8f..ea8e50b11 100644 --- a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -46,8 +46,8 @@ class CollectionPopulator extends Populator implements ICollectio */ @Override public Collection getPopulatedObject(final Field field, final Collection fieldValue) { - final Class genericClass = getReflectionUtils().getArgumentTypeClass(fieldValue, field.getDeclaringClass().getName(), field.getName(), true); - return getPopulatedObject(field.getType(), getReflectionUtils().getGenericFieldType(field), fieldValue, genericClass); + final Class genericClass = reflectionUtils.getArgumentTypeClass(fieldValue, field.getDeclaringClass().getName(), field.getName(), true); + return getPopulatedObject(field.getType(), reflectionUtils.getGenericFieldType(field), fieldValue, genericClass); } /** @@ -57,7 +57,7 @@ public Collection getPopulatedObject(final Field field, final Collection fiel @Override public Collection getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { final Collection res; - if (getClassUtils().isPrimitiveOrSpecialType(isNull(nestedGenericClass) ? genericFieldType : nestedGenericClass)) { + if (classUtils.isPrimitiveOrSpecialType(isNull(nestedGenericClass) ? genericFieldType : nestedGenericClass)) { res = (Collection) fieldValue; } else { Collector> collector = Set.class.isAssignableFrom(fieldType) ? toSet() : toList(); diff --git a/src/main/java/com/hotels/beans/populator/MapPopulator.java b/src/main/java/com/hotels/beans/populator/MapPopulator.java index f019b56d7..ea45ea26a 100644 --- a/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -44,7 +44,7 @@ class MapPopulator extends Populator> { */ @Override public Map getPopulatedObject(final Field field, final Map fieldValue) { - final MapType mapGenericType = getReflectionUtils().getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); + final MapType mapGenericType = reflectionUtils.getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); return getPopulatedObject(fieldValue, mapGenericType); } @@ -57,8 +57,8 @@ class MapPopulator extends Populator> { private Map getPopulatedObject(final Map fieldValue, final MapType mapType) { final MapElemType keyType = mapType.getKeyType(); final MapElemType elemType = mapType.getElemType(); - final boolean keyIsPrimitive = keyType.getClass().equals(ItemType.class) && getClassUtils().isPrimitiveOrSpecialType(((ItemType) keyType).getObjectClass()); - final boolean elemIsPrimitive = elemType.getClass().equals(ItemType.class) && getClassUtils().isPrimitiveOrSpecialType(((ItemType) elemType).getObjectClass()); + final boolean keyIsPrimitive = keyType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) keyType).getObjectClass()); + final boolean elemIsPrimitive = elemType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) elemType).getObjectClass()); Map populatedObject; if (keyIsPrimitive && elemIsPrimitive) { populatedObject = fieldValue; @@ -84,7 +84,7 @@ class MapPopulator extends Populator> { @SuppressWarnings("unchecked") private T getElemValue(final MapElemType mapElemType, final boolean elemIsPrimitiveType, final T value) { final T elemValue; - if (elemIsPrimitiveType || getClassUtils().isPrimitiveOrSpecialType(value.getClass())) { + if (elemIsPrimitiveType || classUtils.isPrimitiveOrSpecialType(value.getClass())) { elemValue = value; } else { if (mapElemType.getClass().equals(ItemType.class)) { diff --git a/src/main/java/com/hotels/beans/populator/Populator.java b/src/main/java/com/hotels/beans/populator/Populator.java index 95e52ad51..ab5006c3d 100644 --- a/src/main/java/com/hotels/beans/populator/Populator.java +++ b/src/main/java/com/hotels/beans/populator/Populator.java @@ -18,8 +18,6 @@ import static com.hotels.beans.populator.PopulatorFactory.getPopulator; -import static lombok.AccessLevel.NONE; - import java.lang.reflect.Field; import java.util.Optional; @@ -27,29 +25,25 @@ import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; -import lombok.Getter; - /** * Populator for collection or map objects. * @param the type of the object to get populated. */ -@Getter public abstract class Populator { /** - * Transformer class instance {@link Transformer} containing the field mapping and transformation functions. + * Reflection utils instance {@link ReflectionUtils}. */ - @Getter(NONE) - private final Transformer transformer; + final ReflectionUtils reflectionUtils; /** - * Reflection utils class {@link ReflectionUtils}. + * Class reflection utils instance {@link ClassUtils}. */ - private final ReflectionUtils reflectionUtils; + final ClassUtils classUtils; /** - * Class reflection utils class {@link ClassUtils}. + * Transformer class instance {@link Transformer} containing the field mapping and transformation functions. */ - private final ClassUtils classUtils; + private final Transformer transformer; /** * Default constructor. diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index b8437ab70..26c70aaca 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -29,38 +29,35 @@ import com.hotels.beans.utils.ReflectionUtils; import com.hotels.beans.utils.ValidationUtils; -import lombok.Getter; - /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * Contains all method implementation that will be common to any {@link Transformer} implementation. */ -@Getter abstract class AbstractTransformer implements Transformer { /** - * Reflection utils class {@link ReflectionUtils}. + * Reflection utils instance {@link ReflectionUtils}. */ - private final ReflectionUtils reflectionUtils; + final ReflectionUtils reflectionUtils; /** - * Class reflection utils class {@link ClassUtils}. + * Class uttils instance {@link ClassUtils}. */ - private final ClassUtils classUtils; + final ClassUtils classUtils; /** - * Validation utils class {@link ValidationUtils}. + * Validation utils instance {@link ValidationUtils}. */ - private final ValidationUtils validationUtils; + final ValidationUtils validationUtils; /** - * CacheManager class {@link CacheManager}. + * CacheManager instance {@link CacheManager}. */ - private final CacheManager cacheManager; + final CacheManager cacheManager; /** * Contains both the field name mapping and the lambda function to be applied on fields. */ - private final TransformerSettings transformerSettings; + final TransformerSettings settings; /** * Default constructor. @@ -69,7 +66,7 @@ abstract class AbstractTransformer implements Transformer { this.reflectionUtils = new ReflectionUtils(); this.classUtils = new ClassUtils(); this.validationUtils = new ValidationUtils(); - this.transformerSettings = new TransformerSettings(); + this.settings = new TransformerSettings(); this.cacheManager = CacheManagerFactory.getCacheManager("transformer"); } @@ -78,7 +75,7 @@ abstract class AbstractTransformer implements Transformer { */ @Override public final Transformer withFieldMapping(final FieldMapping... fieldMapping) { - final Map fieldsNameMapping = transformerSettings.getFieldsNameMapping(); + final Map fieldsNameMapping = settings.getFieldsNameMapping(); for (FieldMapping mapping : fieldMapping) { fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); } @@ -91,7 +88,7 @@ public final Transformer withFieldMapping(final FieldMapping... fieldMapping) { @Override public final void removeFieldMapping(final String destFieldName) { notNull(destFieldName, "The field name for which the mapping has to be removed cannot be null!"); - transformerSettings.getFieldsNameMapping().remove(destFieldName); + settings.getFieldsNameMapping().remove(destFieldName); } /** @@ -99,7 +96,7 @@ public final void removeFieldMapping(final String destFieldName) { */ @Override public final void resetFieldsMapping() { - transformerSettings.getFieldsNameMapping().clear(); + settings.getFieldsNameMapping().clear(); } /** @@ -108,7 +105,7 @@ public final void resetFieldsMapping() { @Override @SuppressWarnings("unchecked") public final Transformer withFieldTransformer(final FieldTransformer... fieldTransformer) { - Map> fieldsTransformers = transformerSettings.getFieldsTransformers(); + Map> fieldsTransformers = settings.getFieldsTransformers(); for (FieldTransformer transformer : fieldTransformer) { fieldsTransformers.put(transformer.getDestFieldName(), transformer.getTransformerFunction()); } @@ -121,7 +118,7 @@ public final Transformer withFieldTransformer(final FieldTransformer... fieldTra @Override public final void removeFieldTransformer(final String destFieldName) { notNull(destFieldName, "The field name for which the transformer function has to be removed cannot be null!"); - transformerSettings.getFieldsTransformers().remove(destFieldName); + settings.getFieldsTransformers().remove(destFieldName); } /** @@ -129,7 +126,7 @@ public final void removeFieldTransformer(final String destFieldName) { */ @Override public final void resetFieldsTransformer() { - transformerSettings.getFieldsTransformers().clear(); + settings.getFieldsTransformers().clear(); } /** @@ -137,7 +134,7 @@ public final void resetFieldsTransformer() { */ @Override public final Transformer setDefaultValueForMissingField(final boolean useDefaultValue) { - transformerSettings.setSetDefaultValue(useDefaultValue); + settings.setSetDefaultValue(useDefaultValue); return this; } @@ -146,7 +143,7 @@ public final Transformer setDefaultValueForMissingField(final boolean useDefault */ @Override public final Transformer setFlatFieldNameTransformation(final boolean useFlatTransformation) { - transformerSettings.setFlatFieldNameTransformation(useFlatTransformation); + settings.setFlatFieldNameTransformation(useFlatTransformation); return this; } @@ -155,7 +152,7 @@ public final Transformer setFlatFieldNameTransformation(final boolean useFlatTra */ @Override public Transformer setValidationDisabled(final boolean validationDisabled) { - transformerSettings.setValidationDisabled(validationDisabled); + settings.setValidationDisabled(validationDisabled); return this; } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index d73243d2b..88e68a033 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -54,7 +54,7 @@ public class TransformerImpl extends AbstractTransformer { @Override protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final ClassType classType = getClassUtils().getClassType(targetClass); + final ClassType classType = classUtils.getClassType(targetClass); if (classType.is(MUTABLE)) { try { k = targetClass.getDeclaredConstructor().newInstance(); @@ -65,13 +65,13 @@ protected final K transform(final T sourceObj, final Class t throw new InvalidBeanException(e.getMessage(), e); } } else { - k = injectValues(sourceObj, targetClass, getClassUtils().getAllArgsConstructor(targetClass), breadcrumb); + k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); if (classType.is(MIXED)) { injectNotFinalFields(sourceObj, k, breadcrumb); } } - if (!getTransformerSettings().isValidationDisabled()) { - getValidationUtils().validate(k); + if (!settings.isValidationDisabled()) { + validationUtils.validate(k); } return k; } @@ -82,8 +82,8 @@ protected final K transform(final T sourceObj, final Class t @Override protected final void transform(final T sourceObj, final K targetObject, final String breadcrumb) { injectAllFields(sourceObj, targetObject, breadcrumb); - if (!getTransformerSettings().isValidationDisabled()) { - getValidationUtils().validate(targetObject); + if (!settings.isValidationDisabled()) { + validationUtils.validate(targetObject); } } @@ -138,10 +138,10 @@ private String getFormattedConstructorArgs(final Class targetClass, final */ private boolean canBeInjectedByConstructorParams(final Constructor constructor, final Class targetClass) { final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getCanonicalName(); - return ofNullable(getCacheManager().getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { - final boolean res = getClassUtils().getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() - && (getClassUtils().areParameterNamesAvailable(constructor) || getClassUtils().allParameterAnnotatedWith(constructor, ConstructorArg.class)); - getCacheManager().cacheObject(cacheKey, res); + return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() + && (classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class)); + cacheManager.cacheObject(cacheKey, res); return res; }); } @@ -159,19 +159,19 @@ private boolean canBeInjectedByConstructorParams(final Constructor construct * @throws InvalidBeanException {@link InvalidBeanException} if there is an error while retrieving the constructor args parameter */ private Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { - final Parameter[] constructorParameters = getClassUtils().getConstructorParameters(constructor); + final Parameter[] constructorParameters = classUtils.getConstructorParameters(constructor); final Object[] constructorArgsValues = new Object[constructorParameters.length]; range(0, constructorParameters.length) //.parallel() .forEach(i -> { String destFieldName = getDestFieldName(constructorParameters[i], targetClass.getCanonicalName()); if (isNull(destFieldName)) { - constructorArgsValues[i] = getClassUtils().getDefaultTypeValue(constructorParameters[i].getType()); + constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); } else { String sourceFieldName = getSourceFieldName(destFieldName); constructorArgsValues[i] = - ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, getClassUtils().getDeclaredField(targetClass, destFieldName), breadcrumb)) - .orElse(getClassUtils().getDefaultTypeValue(constructorParameters[i].getType())); + ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, classUtils.getDeclaredField(targetClass, destFieldName), breadcrumb)) + .orElse(classUtils.getDefaultTypeValue(constructorParameters[i].getType())); } }); return constructorArgsValues; @@ -192,7 +192,7 @@ private String getSourceFieldName(final Field field) { * @return the source field name. */ private String getSourceFieldName(final String fieldName) { - return ofNullable(getTransformerSettings().getFieldsNameMapping().get(fieldName)).orElse(fieldName); + return ofNullable(settings.getFieldsNameMapping().get(fieldName)).orElse(fieldName); } /** @@ -203,17 +203,17 @@ private String getSourceFieldName(final String fieldName) { */ private String getDestFieldName(final Parameter constructorParameter, final String declaringClassName) { String cacheKey = "DestFieldName-" + declaringClassName + "-" + constructorParameter.getName(); - return ofNullable(getCacheManager().getFromCache(cacheKey, String.class)) + return ofNullable(cacheManager.getFromCache(cacheKey, String.class)) .orElseGet(() -> { String destFieldName; if (constructorParameter.isNamePresent()) { destFieldName = constructorParameter.getName(); } else { - destFieldName = ofNullable(getReflectionUtils().getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)) + destFieldName = ofNullable(reflectionUtils.getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)) .map(ConstructorArg::value) .orElse(null); } - getCacheManager().cacheObject(cacheKey, destFieldName); + cacheManager.cacheObject(cacheKey, destFieldName); return destFieldName; }); } @@ -230,7 +230,7 @@ private String getDestFieldName(final Parameter constructorParameter, final Stri * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ private Object[] getConstructorValuesFromFields(final T sourceObj, final Class targetClass, final String breadcrumb) { - final List declaredFields = getClassUtils().getDeclaredFields(targetClass, true); + final List declaredFields = classUtils.getDeclaredFields(targetClass, true); return declaredFields.stream() .map(field -> getFieldValue(sourceObj, targetClass, field, breadcrumb)) .toArray(Object[]::new); @@ -247,9 +247,9 @@ private Object[] getConstructorValuesFromFields(final T sourceObj, final */ private void injectAllFields(final T sourceObj, final K targetObject, final String breadcrumb) { final Class targetObjectClass = targetObject.getClass(); - getClassUtils().getDeclaredFields(targetObjectClass, true) + classUtils.getDeclaredFields(targetObjectClass, true) //.parallelStream() - .forEach(field -> getReflectionUtils().setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); + .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); } /** @@ -263,9 +263,9 @@ private void injectAllFields(final T sourceObj, final K targetObject, fin */ private void injectNotFinalFields(final T sourceObj, final K targetObject, final String breadcrumb) { final Class targetObjectClass = targetObject.getClass(); - getClassUtils().getNotFinalFields(targetObjectClass, true) + classUtils.getNotFinalFields(targetObjectClass, true) //.parallelStream() - .forEach(field -> getReflectionUtils().setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); + .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); } /** @@ -298,13 +298,13 @@ private Object getFieldValue(final T sourceObj, final Class targetClas */ private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); - boolean primitiveType = getClassUtils().isPrimitiveType(field.getType()); - boolean isFieldTransformerDefined = getTransformerSettings().getFieldsTransformers().containsKey(field.getName()); + boolean primitiveType = classUtils.isPrimitiveType(field.getType()); + boolean isFieldTransformerDefined = settings.getFieldsTransformers().containsKey(field.getName()); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function // defined it recursively evaluate the value - boolean notPrimitiveAndNotSpecialType = !primitiveType && !getClassUtils().isSpecialType(field.getType()); + boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(field.getType()); if ((notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass())) && !isFieldTransformerDefined) { fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); @@ -337,9 +337,9 @@ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { private Object getSourceFieldValue(final T sourceObj, final String sourceFieldName, final Field field, final boolean isFieldTransformerDefined) { Object fieldValue = null; try { - fieldValue = getReflectionUtils().getFieldValue(sourceObj, sourceFieldName, field.getType()); + fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); } catch (MissingFieldException e) { - if (!isFieldTransformerDefined && !getTransformerSettings().isSetDefaultValue()) { + if (!isFieldTransformerDefined && !settings.isSetDefaultValue()) { throw e; } } catch (Exception e) { @@ -358,8 +358,8 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie * @return the transformed field. */ private Object getTransformedField(final Field field, final String breadcrumb, final Object fieldValue) { - String fieldName = getTransformerSettings().isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - return ofNullable(getTransformerSettings().getFieldsTransformers().get(fieldName)) + String fieldName = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; + return ofNullable(settings.getFieldsTransformers().get(fieldName)) .map(fieldTransformer -> fieldTransformer.apply(fieldValue)) .orElse(fieldValue); } diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 0a4d84e1d..4fdb73f00 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -70,7 +70,7 @@ public final class ClassUtils { private static final String CLAZZ_CANNOT_BE_NULL = "clazz cannot be null!"; /** - * Reflection utils class {@link ReflectionUtils}. + * Reflection utils instance {@link ReflectionUtils}. */ private final ReflectionUtils reflectionUtils; diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index b606c8f5d..f27136f6c 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -69,7 +69,7 @@ public final class ReflectionUtils { private static final String DOT_SPLIT_REGEX = "\\."; /** - * CacheManager class {@link CacheManager}. + * CacheManager instance {@link CacheManager}. */ private final CacheManager cacheManager; @@ -137,7 +137,9 @@ public Object getFieldValue(final Object target, final Field field) { public Object getFieldValue(final Object target, final String fieldName, final Class fieldType) { Object fieldValue = getRealTarget(target); for (String currFieldName : fieldName.split(DOT_SPLIT_REGEX)) { - if (fieldValue == null) break; + if (fieldValue == null) { + break; + } try { fieldValue = getFieldValue(fieldValue, currFieldName); } catch (final Exception e) { @@ -221,13 +223,13 @@ private Object getFieldValue(final Object target, final String fieldName) { boolean isAccessible = true; Field field = null; try { - field = target.getClass().getDeclaredField(fieldName); + field = getDeclaredField(fieldName, target); isAccessible = isFieldAccessible(field, target); if (!isAccessible) { field.setAccessible(true); } return field.get(target); - } catch (NoSuchFieldException e) { + } catch (MissingFieldException e) { throw new MissingFieldException(target.getClass().getCanonicalName() + " does not contain field: " + fieldName); } catch (final Exception e) { handleReflectionException(e); @@ -239,6 +241,32 @@ private Object getFieldValue(final Object target, final String fieldName) { } } + /** + * Return the field of the given class. + * @param fieldName the name of the filed to retrieve. + * @param target the field's class + * @return the field corresponding to the given name. + */ + private Field getDeclaredField(final String fieldName, final Object target) { + final AtomicReference> targetClass = new AtomicReference<>(target.getClass()); + final String cacheKey = "DeclaredField-" + targetClass.get().getCanonicalName() + "-fieldName-" + fieldName; + return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { + Field field = null; + while (isNull(field) && !targetClass.get().equals(Object.class)) { + try { + field = targetClass.get().getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + targetClass.set(targetClass.get().getSuperclass()); + } + } + if (isNull(field)) { + throw new MissingFieldException(targetClass.get().getCanonicalName() + " does not contain field: " + fieldName); + } + cacheManager.cacheObject(cacheKey, field); + return field; + }); + } + /** * Sets the value of a field through setter method. * @param target the field's class diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index 244807411..fc8b65120 100644 --- a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -34,7 +34,7 @@ public class AbstractTransformerTest { private static final String SOURCE_FIELD_NAME = "sourceFieldName"; private static final String SOURCE_FIELD_NAME_2 = "sourceFieldName2"; private static final String DEST_FIELD_NAME = "destFieldName"; - private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "transformerSettings"; + private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); /** diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index ce43e81e7..5de3663f2 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -115,7 +115,7 @@ public class TransformerTest { private static final String GET_SOURCE_FIELD_VALUE_METHOD_NAME = "getSourceFieldValue"; private static final String DEST_FIELD_NAME = "destFieldName"; private static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; - private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "transformerSettings"; + private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; private static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); private static FromFoo fromFoo; From 429a7c3e278f6e1273b0d9a8c72fee6067b8d4d6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Mar 2019 08:49:22 +0100 Subject: [PATCH 0287/1786] Added all new features to java 8 library version. This would made the library runnable with both java 8 or above --- CHANGELOG.md | 4 ++++ pom.xml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec33dc235..69d28d8e4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.5] 2019.03.03 +#### Added +* Added all new features into the java 8 project version. + ### [1.1.4] 2019.02.20 #### Added * Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/HotelsDotCom/bull/issues/27)). diff --git a/pom.xml b/pom.xml index 0b7ff4a61..70fe36c6b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.1-SNAPSHOT + 1.1.5-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 From 30a7b886f3064d9793c689eeb9edaa1102fd3ebf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Mar 2019 08:54:18 +0100 Subject: [PATCH 0288/1786] [maven-release-plugin] prepare release 1.1.5 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 70fe36c6b..8bee89dca 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.5-SNAPSHOT + 1.1.5 jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.5 From 156770cd1bde7ab794b144b54e7f60eb1df109a1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Mar 2019 08:54:25 +0100 Subject: [PATCH 0289/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8bee89dca..caf1178bb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.5 + 1.1.6-SNAPSHOT jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.5 + HEAD From c0eb8e57ab14a1bb4fb5de15cdadcb307309e013 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Mar 2019 08:56:48 +0100 Subject: [PATCH 0290/1786] minor: restored compilation in java 11 and maven version --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index caf1178bb..0b7ff4a61 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.6-SNAPSHOT + 1.2.1-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 From 1799d57072fe7115590256a0a5c745fa1979a9bd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 3 Mar 2019 09:29:37 +0100 Subject: [PATCH 0291/1786] Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` --- CHANGELOG.md | 2 ++ pom.xml | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e0e7aec7..af3ee7c74 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. ### [1.2.1] TBD #### Added * Implemented new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) +* Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` + ### [1.2.0] 2019.02.25 #### Added * Added possibility to skip the object validation (see: [Issue 31](https://github.com/HotelsDotCom/bull/issues/31)) diff --git a/pom.xml b/pom.xml index 0b7ff4a61..c480e599c 100644 --- a/pom.xml +++ b/pom.xml @@ -140,6 +140,8 @@ false true false + false + false @@ -148,6 +150,18 @@ true false true + true + false + + + + fast + + true + false + true + true + true @@ -219,6 +233,9 @@ org.apache.maven.plugins maven-javadoc-plugin ${maven.javadoc.plugin.version} + + ${javadoc.skip} + attach-javadocs @@ -361,6 +378,7 @@ false false java + ${pmd.check.skip} From 37e9032f013c1504939952e0f091035440f7e5fb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 10:18:40 +0100 Subject: [PATCH 0292/1786] - Finalized possibility to copy on an existing instance - Added usage examples - Updated changelog --- CHANGELOG.md | 2 +- README.md | 19 + docs/site/markdown/transformer/samples.md | 19 + .../transformer/AbstractTransformer.java | 5 + .../hotels/beans/transformer/Transformer.java | 5 + .../transformer/TransformerSettings.java | 5 + .../java/com/hotels/beans/sample/FromFoo.java | 4 +- .../sample/immutable/ImmutableToFoo.java | 1 - .../sample/immutable/ImmutableToSubFoo.java | 3 - .../transformer/AbstractTransformerTest.java | 164 ++-- .../ImmutableObjectTransformationTest.java | 486 ++++++++++++ .../MixedObjectTransformationTest.java | 179 +++++ .../MutableObjectTransformationTest.java | 155 ++++ .../beans/transformer/TransformerTest.java | 745 +----------------- .../beans/utils/ReflectionUtilsTest.java | 3 +- 15 files changed, 1008 insertions(+), 787 deletions(-) create mode 100644 src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java create mode 100644 src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java create mode 100644 src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index af3ee7c74..a22cc4533 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.2.1] TBD +### [1.2.1] 2019.03.05 #### Added * Implemented new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) * Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` diff --git a/README.md b/README.md index 8058014df..d1200577e 100644 --- a/README.md +++ b/README.md @@ -357,6 +357,25 @@ ToBean toBean = beanUtils.getTransformer() .transform(fromBean, ToBean.class); ~~~ +### Copy on an existing instance: + +Given: + +~~~Java +public class FromBean { public class ToBean { + private final String name; private String name; + private final FromSubBean nestedObject; private ToSubBean nestedObject; + + // all args constructor // constructor + // getters... // getters and setters... +} } +~~~ +if you need to perform the copy on an already existing object, just do: +~~~Java +ToBean toBean = new ToBean(); +beanUtils.getTransformer().transform(fromBean, toBean); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` ## Third party library comparison diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 23f872d1f..a18752a19 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -301,4 +301,23 @@ ToBean toBean = beanUtils.getTransformer() .transform(fromBean, ToBean.class); ~~~ +### Copy on an existing instance: + +Given: + +~~~Java +public class FromBean { public class ToBean { + private final String name; private String name; + private final FromSubBean nestedObject; private ToSubBean nestedObject; + + // all args constructor // constructor + // getters... // getters and setters... +} } +~~~ +if you need to perform the copy on an already existing object, just do: +~~~Java +ToBean toBean = new ToBean(); +beanUtils.getTransformer().transform(fromBean, toBean); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` \ No newline at end of file diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 26c70aaca..5f4dc560e 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -187,6 +187,11 @@ public final void transform(final T sourceObj, final K targetObject) { transform(sourceObj, targetObject, null); } + @Override + public void resetFieldsTransformationSkip() { + settings.getFieldsToSkip().clear(); + } + /** * Copies all properties from an object to a new one. * @param sourceObj the source object diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index 986a607e4..ff9de7bf3 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -105,4 +105,9 @@ public interface Transformer { * @return the {@link Transformer} instance */ Transformer setValidationDisabled(boolean validationDisabled); + + /** + * Removes all the configured fields to skip. + */ + void resetFieldsTransformationSkip(); } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 22d4b4433..a270861a3 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -47,6 +47,11 @@ final class TransformerSettings { */ private final Map> fieldsTransformers = new ConcurrentHashMap<>(); + /** + * Contains the list of fields that don't need to be transformed. + */ + private final Map fieldsToSkip = new ConcurrentHashMap<>(); + /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. diff --git a/src/test/java/com/hotels/beans/sample/FromFoo.java b/src/test/java/com/hotels/beans/sample/FromFoo.java index 010259073..d6387a10f 100644 --- a/src/test/java/com/hotels/beans/sample/FromFoo.java +++ b/src/test/java/com/hotels/beans/sample/FromFoo.java @@ -30,8 +30,8 @@ @Getter @Setter public class FromFoo { - private String name; - private final BigInteger id; + private final String name; + private BigInteger id; private final List nestedObjectList; private final List list; private final FromSubFoo nestedObject; diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java index 3e566251e..cd1b0ad58 100644 --- a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java @@ -30,7 +30,6 @@ @AllArgsConstructor @Getter public class ImmutableToFoo { - @NotNull private final String name; @NotNull private final BigInteger id; diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java index 1e7a2c4ec..ec539a5bc 100644 --- a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java @@ -19,8 +19,6 @@ import java.util.List; import java.util.Map; -import javax.validation.constraints.NotNull; - import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; @@ -32,7 +30,6 @@ @Getter @ToString public class ImmutableToSubFoo { - @NotNull private final String name; private final int[] phoneNumbers; private final Map sampleMap; diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index fc8b65120..bc3887720 100644 --- a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -16,111 +16,127 @@ package com.hotels.beans.transformer; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.MockitoAnnotations.initMocks; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; -import org.junit.Before; -import org.junit.Test; +import static com.hotels.beans.constant.ClassType.IMMUTABLE; -import com.hotels.beans.model.FieldMapping; -import com.hotels.beans.model.FieldTransformer; -import com.hotels.beans.utils.ReflectionUtils; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +import org.junit.BeforeClass; + +import com.hotels.beans.sample.FromFoo; +import com.hotels.beans.sample.FromFooAdvFields; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.FromFooSubClass; +import com.hotels.beans.sample.FromFooWithPrimitiveFields; +import com.hotels.beans.sample.FromSubFoo; /** - * Unit test for class: {@link AbstractTransformer}. + * Unit test for {@link Transformer}. */ public class AbstractTransformerTest { - private static final String SOURCE_FIELD_NAME = "sourceFieldName"; - private static final String SOURCE_FIELD_NAME_2 = "sourceFieldName2"; - private static final String DEST_FIELD_NAME = "destFieldName"; - private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; - private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); + protected static final BigInteger ID = new BigInteger("1234"); + protected static final String NAME = "Goofy"; + protected static FromFoo fromFoo; + protected static FromFoo fromFooWithNullProperties; + protected static FromFooSimple fromFooSimple; + protected static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; + protected static List fromSubFooList; + protected static List sourceFooSimpleList; + protected static FromSubFoo fromSubFoo; + protected static FromFooSubClass fromFooSubClass; + protected static FromFooAdvFields fromFooAdvFields; + protected static final int AGE = 34; + protected static final String AGE_FIELD_NAME = "age"; + protected static final String DEST_FIELD_NAME = "destFieldName"; + protected static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; + protected static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; + + private static final String ITEM_1 = "donald"; + private static final String ITEM_2 = "duck"; + private static final String SURNAME = "surname"; + private static final int PHONE = 123; + private static final String INDEX_NUMBER = null; + private static final boolean CHECK = true; + private static final BigDecimal AMOUNT = new BigDecimal(10); + private static final String SUB_FOO_NAME = "Smith"; + private static final int[] SUB_FOO_PHONE_NUMBERS = {12345, 6892, 10873}; + private static final Map SUB_FOO_SAMPLE_MAP = new HashMap<>(); + private static final Map> SUB_FOO_COMPLEX_MAP = new HashMap<>(); + private static final Map> SUB_FOO_VERY_COMPLEX_MAP = new HashMap<>(); /** - * The class to be tested. + * Initializes the arguments and objects. */ - private AbstractTransformer underTest; + @BeforeClass + public static void beforeClass() { + initObjects(); + } /** - * Initialized mocks. + * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. */ - @Before - public void beforeMethod() { - underTest = new TransformerImpl(); - initMocks(this); + private static void initObjects() { + SUB_FOO_SAMPLE_MAP.put(ITEM_1, ITEM_2); + SUB_FOO_COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); + SUB_FOO_VERY_COMPLEX_MAP.put(ITEM_1, SUB_FOO_SAMPLE_MAP); + fromSubFoo = new FromSubFoo(SUB_FOO_NAME, SUB_FOO_PHONE_NUMBERS, SUB_FOO_SAMPLE_MAP, SUB_FOO_COMPLEX_MAP, SUB_FOO_VERY_COMPLEX_MAP); + fromSubFooList = singletonList(fromSubFoo); + sourceFooSimpleList = asList(ITEM_1, ITEM_2); + fromFoo = createFromFoo(fromSubFoo); + fromFooWithNullProperties = createFromFoo(null); + fromFooSimple = createFromFooSimple(); + fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); + fromFooSubClass = createFromFooSubClass(); + fromFooAdvFields = createFromFooAdvFields(); } /** - * Test that is possible to remove a field mapping for a given field. + * Creates a {@link FromFoo} instance. + * @param fromSubFoo the {@link FromSubFoo} instance + * @return the {@link FromFoo} instance. */ - @Test - public void testRemoveFieldMappingWorksProperly() { - //GIVEN - Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); - - //WHEN - beanTransformer.removeFieldMapping(DEST_FIELD_NAME); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - - //THEN - assertFalse(transformerSettings.getFieldsNameMapping().containsKey(DEST_FIELD_NAME)); + private static FromFoo createFromFoo(final FromSubFoo fromSubFoo) { + return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); } /** - * Test that the method {@code removeFieldMapping} raises an {@link IllegalArgumentException} if the parameter is null. + * Creates a {@link FromFooSimple} instance. + * @return the {@link FromFooSimple} instance. */ - @Test(expected = IllegalArgumentException.class) - public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { - //GIVEN - Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); - - //WHEN - beanTransformer.removeFieldMapping(null); + private static FromFooSimple createFromFooSimple() { + return new FromFooSimple(NAME, ID); } + /** - * Test that is possible to remove all the fields mappings defined. + * Creates a {@link FromFooWithPrimitiveFields} instance. + * @return the {@link FromFooWithPrimitiveFields} instance. */ - @Test - public void testResetFieldsMappingWorksProperly() { - //GIVEN - Transformer beanTransformer = underTest - .withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME), new FieldMapping(SOURCE_FIELD_NAME_2, DEST_FIELD_NAME)); - - //WHEN - beanTransformer.resetFieldsMapping(); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - - //THEN - assertTrue(transformerSettings.getFieldsNameMapping().isEmpty()); + private static FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { + return new FromFooWithPrimitiveFields(NAME, ID.intValue(), AGE, fromSubFooList, sourceFooSimpleList, fromSubFoo); } /** - * Test that is possible to remove a field transformer for a given field. + * Creates a {@link FromFooSubClass} instance. + * @return the {@link FromFooSubClass} instance. */ - @Test - public void testRemoveFieldTransformerWorksProperly() { - //GIVEN - Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - - //WHEN - beanTransformer.removeFieldTransformer(DEST_FIELD_NAME); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - - //THEN - assertFalse(transformerSettings.getFieldsTransformers().containsKey(DEST_FIELD_NAME)); + private static FromFooSubClass createFromFooSubClass() { + return new FromFooSubClass(fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObjectList(), fromFoo.getList(), fromFoo.getNestedObject(), SURNAME, PHONE, CHECK, AMOUNT); } /** - * Test that the method {@code removeFieldTransformer} raises an {@link IllegalArgumentException} if the parameter is null. + * Creates a {@link FromFooAdvFields} instance. + * @return the {@link FromFooAdvFields} instance. */ - @Test(expected = IllegalArgumentException.class) - public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() { - //GIVEN - Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - - //WHEN - beanTransformer.removeFieldTransformer(null); + private static FromFooAdvFields createFromFooAdvFields() { + return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage()); } } diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java new file mode 100644 index 000000000..b0735cb91 --- /dev/null +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -0,0 +1,486 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import static java.lang.String.format; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasProperty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Locale; +import java.util.stream.IntStream; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.annotation.ConstructorArg; +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.model.FieldMapping; +import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.sample.FromFoo; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.immutable.ImmutableFlatToFoo; +import com.hotels.beans.sample.immutable.ImmutableToFoo; +import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; +import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; +import com.hotels.beans.sample.immutable.ImmutableToFooDiffFields; +import com.hotels.beans.sample.immutable.ImmutableToFooInvalid; +import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; +import com.hotels.beans.sample.immutable.ImmutableToFooNoConstructors; +import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; +import com.hotels.beans.sample.immutable.ImmutableToFooSimple; +import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; +import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; +import com.hotels.beans.sample.mutable.MutableToFooSubClass; +import com.hotels.beans.utils.ReflectionUtils; + +/** + * Unit test for all {@link Transformer} functions related to Immutable Java Beans. + */ +public class ImmutableObjectTransformationTest extends AbstractTransformerTest { + private static final int TOTAL_ADV_CLASS_FIELDS = 5; + private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; + private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; + + /** + * The class to be tested. + */ + @InjectMocks + private TransformerImpl underTest; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + } + + /** + * Test that immutable beans without constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. + */ + @Test + public void testBeanWithoutCustomAnnotationIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly + * valorized. + */ + @Test + public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected() { + //GIVEN + FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); + + //WHEN + ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFoo, ImmutableFlatToFoo.class); + + //THEN + assertEquals(fromFoo.getName(), actual.getName()); + assertEquals(fromFoo.getId(), actual.getId()); + assertEquals(fromFoo.getNestedObject().getPhoneNumbers(), actual.getPhoneNumbers()); + underTest.resetFieldsMapping(); + } + + /** + * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly + * valorized even if some of them are null. + */ + @Test + public void testTransformationWithCompositeFieldNameWorksEvenWithNullObjects() { + //GIVEN + FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); + + //WHEN + ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFooWithNullProperties, ImmutableFlatToFoo.class); + + //THEN + assertEquals(fromFooWithNullProperties.getName(), actual.getName()); + assertEquals(fromFooWithNullProperties.getId(), actual.getId()); + assertNull(actual.getPhoneNumbers()); + underTest.resetFieldsMapping(); + } + + /** + * Test that immutable beans without custom field mapping. + */ + @Test + public void testBeanWithEmptyFieldMappingIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that immutable beans without custom field mapping. + */ + @Test + public void testBeanWithEmptyFieldTransformerIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. + */ + @Test + public void testBeanWithCustomAnnotationIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFooCustomAnnotation actual = underTest.transform(fromFoo, ImmutableToFooCustomAnnotation.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that an exception is thrown if the constructor invocation throws exception. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsException() { + //GIVEN + FromFoo actual = new FromFoo(NAME, ID, null, null, null); + + //WHEN + underTest.transform(actual, ImmutableToFooCustomAnnotation.class); + } + + /** + * Test that an exception is thrown if no constructors are defined. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionWhenParameterAreNull() { + //GIVEN + FromFoo actual = new FromFoo(NAME, ID, null, null, null); + + //WHEN + underTest.transform(actual, ImmutableToFooNoConstructors.class); + } + + + /** + * Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionWhenImmutableBeanHasAWrongConstructor() { + //GIVEN + + //WHEN + underTest.transform(fromFoo, ImmutableToFooInvalid.class); + } + + /** + * Test that an exception is thrown if the destination object don't met the constraints. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionIfTheDestinationObjectValuesAreNotValid() { + //GIVEN + fromFoo.setId(null); + + //WHEN + underTest.transform(fromFoo, ImmutableToFoo.class); + + // THEN + fromFoo.setId(ID); + } + + /** + * Test that no exception is thrown if the destination object don't met the constraints and the validation is disabled. + */ + @Test + public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotValidAndTheValidationIsDisabled() { + //GIVEN + fromFoo.setId(null); + underTest.setValidationDisabled(true); + + //WHEN + ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); + + // THEN + assertThat(actual, sameBeanAs(fromFoo)); + fromFoo.setId(ID); + underTest.setValidationDisabled(false); + } + + /** + * Test that bean that extends another class are correctly copied. + */ + @Test + public void testBeanWithoutCustomAnnotationAndWithSuperclassIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFooSubClass actual = underTest.transform(fromFooSubClass, ImmutableToFooSubClass.class); + + //THEN + assertThat(actual, sameBeanAs(fromFooSubClass)); + } + + /** + * Test that bean containing final fields (with different field names) are correctly copied. + */ + @Test + public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { + //GIVEN + + //WHEN + final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); + ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); + + //THEN + assertThat(actual, hasProperty("name", equalTo(actual.getName()))); + assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); + assertEquals(actual.getList(), fromFoo.getList()); + IntStream.range(0, actual.getNestedObjectList().size()) + .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); + assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); + } + + /** + * Test that bean containing advanced final fields are correctly copied. + */ + @Test + public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied() { + //GIVEN + + //WHEN + final Transformer beanTransformer = underTest + .withFieldMapping(new FieldMapping("id", "identifier")) + .withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); + ImmutableToFooAdvFields actual = beanTransformer.transform(fromFooAdvFields, ImmutableToFooAdvFields.class); + + //THEN + assertNotNull(actual.getName()); + assertTrue(actual.getName().isPresent()); + assertEquals(fromFooAdvFields.getName().get(), actual.getName().get()); + assertEquals(fromFooAdvFields.getAge().get(), actual.getAge()); + assertEquals(fromFooAdvFields.getClassType(), actual.getClassType()); + assertEquals(fromFooAdvFields.getLocale(), actual.getLocale().getLanguage()); + } + + /** + * Test that immutable bean containing a constructor with some field not annotated with + * {@link com.hotels.beans.annotation.ConstructorArg} is correctly copied. + */ + @Test + public void testImmutableBeanWithMissingConstructorArgIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFooMissingCustomAnnotation actual = underTest.withFieldTransformer().transform(fromFooWithPrimitiveFields, ImmutableToFooMissingCustomAnnotation.class); + + //THEN + assertNotNull(actual); + assertEquals(fromFooWithPrimitiveFields.getName(), actual.getName()); + } + + /** + * Test that method: {@code getDestFieldName} retrieves the param name from the {@link ConstructorArg} if it is not provided from jvm directly. + */ + @Test + public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNotProvidedFromJVM() throws Exception { + //GIVEN + String declaringClassName = ImmutableToFoo.class.getName(); + // Parameter mock setup + Parameter constructorParameter = mock(Parameter.class); + when(constructorParameter.getName()).thenReturn(CONSTRUCTOR_PARAMETER_NAME); + + // CacheManager mock setup + initGetDestFieldNameTestMock(declaringClassName, constructorParameter); + Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); + getDestFieldNameMethod.setAccessible(true); + + //WHEN + String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); + + //THEN + assertEquals(DEST_FIELD_NAME, actual); + + // restore modified objects + restoreObjects(getDestFieldNameMethod); + } + + /** + * Test that the method: {@code getConstructorValuesFromFields} works properly. + */ + @Test + public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { + //GIVEN + underTest.withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); + + //WHEN + final Method getConstructorValuesFromFieldsMethod = + underTest.getClass().getDeclaredMethod(GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME, Object.class, Class.class, String.class); + getConstructorValuesFromFieldsMethod.setAccessible(true); + Object[] actual = (Object[]) getConstructorValuesFromFieldsMethod.invoke(underTest, fromFooAdvFields, ImmutableToFooAdvFields.class, ""); + + //THEN + assertNotNull(actual); + assertEquals(TOTAL_ADV_CLASS_FIELDS, actual.length); + + // restore modified objects + restoreObjects(getConstructorValuesFromFieldsMethod); + } + + /** + * Test that method: {@code getDestFieldName} returns null if the constructor's parameter name is not provided from jvm directly and the {@link ConstructorArg} is not defined. + */ + @Test + public void testGetDestFieldNameReturnsNullIfConstructorParamHasNoNameProvidedFromJVMAndNoConstructorArgIsDefined() throws Exception { + //GIVEN + String declaringClassName = ImmutableToFoo.class.getName(); + // Parameter mock setup + Parameter constructorParameter = mock(Parameter.class); + when(constructorParameter.getName()).thenReturn(null); + + // CacheManager mock setup + initGetDestFieldNameTestMock(declaringClassName, constructorParameter); + Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); + getDestFieldNameMethod.setAccessible(true); + + //WHEN + String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); + + //THEN + assertEquals(DEST_FIELD_NAME, actual); + + // restore modified objects + restoreObjects(getDestFieldNameMethod); + } + + /** + * Test that a meaningful exception is returned when a constructor is invoked with wrong arguments. + */ + @Test + public void testTransformationReturnsAMeaningfulException() { + //GIVEN + Class targetClass = ImmutableToFooSimpleWrongTypes.class; + final String expectedExceptionMessageFormat = + "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " + + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration."; + String targetClassName = targetClass.getCanonicalName(); + String expectedExceptionMessage = + format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getCanonicalName()); + + //WHEN + Exception raisedException = null; + try { + underTest.transform(fromFooSimple, targetClass); + } catch (final Exception e) { + raisedException = e; + } + + //THEN + assertNotNull(raisedException); + assertEquals(InvalidBeanException.class, raisedException.getClass()); + assertEquals(expectedExceptionMessage, raisedException.getMessage()); + } + + /** + * Test transformation on an existing bean is correctly copied. + */ + @Test + public void testTransformationOnAnExistingDestinationWorksProperly() { + //GIVEN + MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); + ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null); + + //WHEN + underTest.transform(fromFooSubClass, mutableToFoo); + underTest.transform(fromFooSimple, immutableToFoo); + + //THEN + assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); + assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); + } + + /** + * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. + */ + @Test + public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); + + //WHEN + underTest.withFieldTransformer(ageFieldTransformer); + ImmutableToFooNotExistingFields immutableObjectBean = underTest.transform(fromFooSimple, ImmutableToFooNotExistingFields.class); + + //THEN + assertThat(immutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + } + + /** + * Initializes the mocks required for testing method: {@code getDestFieldName}. + * @param declaringClassName the declaring class name + * @param constructorParameter the constructor parameter + */ + private void initGetDestFieldNameTestMock(final String declaringClassName, final Parameter constructorParameter) { + CacheManager cacheManager = mock(CacheManager.class); + String cacheKey = "DestFieldName-" + declaringClassName + "-" + CONSTRUCTOR_PARAMETER_NAME; + when(cacheManager.getFromCache(cacheKey, String.class)).thenReturn(null); + // ConstructorArg mock setup + ConstructorArg constructorArg = mock(ConstructorArg.class); + when(constructorArg.value()).thenReturn(DEST_FIELD_NAME); + // ReflectionUtils mock setup + ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + when(reflectionUtils.getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)).thenReturn(constructorArg); + setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); + } + + /** + * Restored the initial object status before testing method: {@code getDestFieldName}. + */ + private void restoreObjects(final Method getDestFieldNameMethod) { + getDestFieldNameMethod.setAccessible(false); + setField(underTest, REFLECTION_UTILS_FIELD_NAME, new ReflectionUtils()); + } + +} diff --git a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java new file mode 100644 index 000000000..69a7b49fb --- /dev/null +++ b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -0,0 +1,179 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasProperty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.mockito.MockitoAnnotations.initMocks; + +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + +import java.math.BigInteger; +import java.util.stream.IntStream; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.error.MissingFieldException; +import com.hotels.beans.model.FieldMapping; +import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.mixed.MixedToFoo; +import com.hotels.beans.sample.mixed.MixedToFooDiffFields; +import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; +import com.hotels.beans.sample.mixed.MixedToFooMissingField; +import com.hotels.beans.sample.mixed.MixedToFooNotExistingFields; + +/** + * Unit test for all {@link Transformer} functions related to Mixed type Java Beans. + */ +public class MixedObjectTransformationTest extends AbstractTransformerTest { + /** + * The class to be tested. + */ + @InjectMocks + private TransformerImpl underTest; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + } + + /** + * Test that a Mixed bean with a constructor containing the final field only is correctly copied. + */ + @Test + public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { + //GIVEN + + //WHEN + MixedToFooMissingAllArgsConstructor actual = underTest.transform(fromFoo, MixedToFooMissingAllArgsConstructor.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that bean containing both final fields and not are correctly copied. + */ + @Test + public void testMixedBeanIsCorrectlyCopied() { + //GIVEN + + //WHEN + MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that bean containing both final fields (with different names) and not are correctly copied. + */ + @Test + public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { + //GIVEN + + //WHEN + final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); + MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); + + //THEN + assertThat(actual, hasProperty("name", equalTo(actual.getName()))); + assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); + assertEquals(actual.getList(), fromFoo.getList()); + IntStream.range(0, actual.getNestedObjectList().size()) + .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); + assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); + } + + /** + * Test that bean containing both final fields (with different names) and not are correctly copied through field transformer. + */ + @Test + public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTransformer() { + //GIVEN + /* Extended declaration. + * Function idTransformer = value -> value.negate(); + * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", idTransformer); + */ + FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); + + //WHEN + underTest.withFieldMapping(new FieldMapping("id", "identifier")).withFieldTransformer(fieldTransformer); + MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); + + //THEN + assertThat(actual, hasProperty("name", equalTo(actual.getName()))); + assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId().negate()))); + assertEquals(actual.getList(), fromFoo.getList()); + IntStream.range(0, actual.getNestedObjectList().size()) + .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); + assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); + } + + /** + * Test that the copy method sets the default value when the source object does not contain a required field. + */ + @Test + public void testMixedBeanWithMissingFieldsReturnsTheDefaultValueWhenTheSourceObjectDoesNotContainARequiredField() { + //GIVEN + underTest.setDefaultValueForMissingField(true); + + //WHEN + MixedToFooMissingField actual = underTest.transform(fromFoo, MixedToFooMissingField.class); + + assertNull(actual.getFooField()); + underTest.setDefaultValueForMissingField(false); + } + + /** + * Test that the copy method raises an exception when the source object does not contain a required field. + */ + @Test(expected = MissingFieldException.class) + public void testMixedBeanWithMissingFieldsThrowsMissingFieldExceptionWhenTheSourceObjectDoesNotContainARequiredField() { + //GIVEN + underTest.setDefaultValueForMissingField(false); + + //WHEN + underTest.transform(fromFoo, MixedToFooMissingField.class); + } + + /** + * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. + */ + @Test + public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); + + //WHEN + underTest.withFieldTransformer(ageFieldTransformer); + MixedToFooNotExistingFields mixedObjectBean = underTest.transform(fromFooSimple, MixedToFooNotExistingFields.class); + + //THEN + assertThat(mixedObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + } +} diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java new file mode 100644 index 000000000..8f0b00b40 --- /dev/null +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -0,0 +1,155 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasProperty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.MockitoAnnotations.initMocks; + +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.FromFooSimpleNoGetters; +import com.hotels.beans.sample.mutable.MutableToFoo; +import com.hotels.beans.sample.mutable.MutableToFooInvalid; +import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; +import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; + +/** + * Unit test for all {@link Transformer} functions related to Mutable type Java Beans. + */ +public class MutableObjectTransformationTest extends AbstractTransformerTest { + /** + * The class to be tested. + */ + @InjectMocks + private TransformerImpl underTest; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + } + + /** + * Test that an exception is thrown if there is no default constructor defined for the mutable bean object. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionWhenMutableBeanHasNoDefaultConstructor() { + //GIVEN + + //WHEN + underTest.transform(fromFoo, MutableToFooInvalid.class); + } + + /** + * Test mutable beans are correctly copied. + */ + @Test + public void testMutableBeanIsCorrectlyCopied() { + //GIVEN + + //WHEN + MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that a given field transformer function is applied only to a specific field even if there are other ones with same name. + */ + @Test + public void testFieldTransformationIsAppliedOnlyToASpecificField() { + //GIVEN + String namePrefix = "prefix-"; + FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", val -> namePrefix + val); + + //WHEN + MutableToFoo actual = underTest + .withFieldTransformer(nameTransformer) + .transform(fromFoo, MutableToFoo.class); + + //THEN + assertEquals(fromFoo.getName(), actual.getName()); + assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); + underTest.resetFieldsTransformer(); + } + + /** + * Test that a given field transformer function is applied to all field matching the given name when {@code flatFieldNameTransformation} is set to true. + */ + @Test + public void testFieldTransformationIsAppliedToAllMatchingFields() { + //GIVEN + String namePrefix = "prefix-"; + FieldTransformer nameTransformer = new FieldTransformer<>("name", val -> namePrefix + val); + + //WHEN + MutableToFoo actual = underTest + .setFlatFieldNameTransformation(true) + .withFieldTransformer(nameTransformer) + .transform(fromFoo, MutableToFoo.class); + + //THEN + assertEquals(namePrefix + fromFoo.getName(), actual.getName()); + assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); + underTest.resetFieldsTransformer(); + } + + /** + * Test that the transformer is able to copy object even if the source object has no setter methods and the destination + * object has no setter methods. + */ + @Test + public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { + //GIVEN + FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, ID); + //WHEN + MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); + + //THEN + assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); + } + + /** + * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. + */ + @Test + public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); + + //WHEN + underTest.withFieldTransformer(ageFieldTransformer); + MutableToFooNotExistingFields mutableObjectBean = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); + + //THEN + assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + } +} diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 5de3663f2..b55393378 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -16,117 +16,30 @@ package com.hotels.beans.transformer; -import static java.lang.String.format; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasProperty; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import static org.springframework.test.util.ReflectionTestUtils.setField; - -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; -import static com.hotels.beans.constant.ClassType.IMMUTABLE; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; -import java.util.stream.IntStream; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.mockito.InjectMocks; -import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.error.MissingFieldException; import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooAdvFields; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSimpleNoGetters; -import com.hotels.beans.sample.FromFooSubClass; -import com.hotels.beans.sample.FromFooWithPrimitiveFields; -import com.hotels.beans.sample.FromSubFoo; -import com.hotels.beans.sample.immutable.ImmutableFlatToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; -import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooDiffFields; -import com.hotels.beans.sample.immutable.ImmutableToFooInvalid; -import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooNoConstructors; -import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; -import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; -import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.beans.sample.immutable.ImmutableToFooSimple; -import com.hotels.beans.sample.mixed.MixedToFoo; -import com.hotels.beans.sample.mixed.MixedToFooDiffFields; -import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; -import com.hotels.beans.sample.mixed.MixedToFooMissingField; -import com.hotels.beans.sample.mixed.MixedToFooNotExistingFields; -import com.hotels.beans.sample.mutable.MutableToFoo; -import com.hotels.beans.sample.mutable.MutableToFooInvalid; -import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; -import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; -import com.hotels.beans.sample.mutable.MutableToFooSubClass; import com.hotels.beans.utils.ReflectionUtils; /** - * Unit test for {@link Transformer}. + * Unit test for class: {@link Transformer}. */ -public class TransformerTest { - private static final BigInteger ID = new BigInteger("1234"); - private static final String ITEM_1 = "donald"; - private static final String ITEM_2 = "duck"; - private static final String NAME = "Goofy"; - private static final String SURNAME = "surname"; - private static final int PHONE = 123; - private static final String INDEX_NUMBER = null; - private static final boolean CHECK = true; - private static final BigDecimal AMOUNT = new BigDecimal(10); - private static final String SUB_FOO_NAME = "Smith"; - private static final int[] SUB_FOO_PHONE_NUMBERS = {12345, 6892, 10873}; - private static final Map SUB_FOO_SAMPLE_MAP = new HashMap<>(); - private static final Map> SUB_FOO_COMPLEX_MAP = new HashMap<>(); - private static final Map> SUB_FOO_VERY_COMPLEX_MAP = new HashMap<>(); - private static final int AGE = 34; - private static final int TOTAL_ADV_CLASS_FIELDS = 5; - private static final String AGE_FIELD_NAME = "age"; - private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; - private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; - private static final String GET_SOURCE_FIELD_VALUE_METHOD_NAME = "getSourceFieldValue"; - private static final String DEST_FIELD_NAME = "destFieldName"; - private static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; +public class TransformerTest extends AbstractTransformerTest { + private static final String SOURCE_FIELD_NAME = "sourceFieldName"; + private static final String SOURCE_FIELD_NAME_2 = "sourceFieldName2"; private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; - private static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; + private static final String GET_SOURCE_FIELD_VALUE_METHOD_NAME = "getSourceFieldValue"; private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); - private static FromFoo fromFoo; - private static FromFoo fromFooWithNullProperties; - private static FromFooSimple fromFooSimple; - private static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; - private static List fromSubFooList; - private static List sourceFooSimpleList; - private static FromSubFoo fromSubFoo; - private static FromFooSubClass fromFooSubClass; - private static FromFooAdvFields fromFooAdvFields; /** * The class to be tested. @@ -134,14 +47,6 @@ public class TransformerTest { @InjectMocks private TransformerImpl underTest; - /** - * Initializes the arguments and objects. - */ - @BeforeClass - public static void beforeClass() { - initObjects(); - } - /** * Initialized mocks. */ @@ -151,530 +56,93 @@ public void beforeMethod() { } /** - * Test that is possible to remove all the fields transformer defined. + * Test that is possible to remove a field mapping for a given field. */ @Test - public void testResetFieldsTransformerWorksProperly() { + public void testRemoveFieldMappingWorksProperly() { //GIVEN - Transformer beanTransformer = underTest - .withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val), new FieldTransformer<>(REFLECTION_UTILS_FIELD_NAME, val -> val)); + Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); //WHEN - beanTransformer.resetFieldsTransformer(); + beanTransformer.removeFieldMapping(DEST_FIELD_NAME); TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertTrue(transformerSettings.getFieldsTransformers().isEmpty()); - } - - /** - * Test that immutable beans without constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. - */ - @Test - public void testBeanWithoutCustomAnnotationIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly - * valorized. - */ - @Test - public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected() { - //GIVEN - FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); - - //WHEN - ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFoo, ImmutableFlatToFoo.class); - - //THEN - assertEquals(fromFoo.getName(), actual.getName()); - assertEquals(fromFoo.getId(), actual.getId()); - assertEquals(fromFoo.getNestedObject().getPhoneNumbers(), actual.getPhoneNumbers()); - underTest.resetFieldsMapping(); - } - - /** - * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly - * valorized even if some of them are null. - */ - @Test - public void testTransformationWithCompositeFieldNameWorksEvenWithNullObjects() { - //GIVEN - FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); - - //WHEN - ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFooWithNullProperties, ImmutableFlatToFoo.class); - - //THEN - assertEquals(fromFooWithNullProperties.getName(), actual.getName()); - assertEquals(fromFooWithNullProperties.getId(), actual.getId()); - assertNull(actual.getPhoneNumbers()); - underTest.resetFieldsMapping(); - } - - /** - * Test that immutable beans without custom field mapping. - */ - @Test - public void testBeanWithEmptyFieldMappingIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertFalse(transformerSettings.getFieldsNameMapping().containsKey(DEST_FIELD_NAME)); } /** - * Test that immutable beans without custom field mapping. + * Test that the method {@code removeFieldMapping} raises an {@link IllegalArgumentException} if the parameter is null. */ - @Test - public void testBeanWithEmptyFieldTransformerIsCorrectlyCopied() { + @Test(expected = IllegalArgumentException.class) + public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { //GIVEN + Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); //WHEN - ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); + beanTransformer.removeFieldMapping(null); } /** - * Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. + * Test that is possible to remove all the fields mappings defined. */ @Test - public void testBeanWithCustomAnnotationIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFooCustomAnnotation actual = underTest.transform(fromFoo, ImmutableToFooCustomAnnotation.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test that an exception is thrown if the constructor invocation throws exception. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsException() { - //GIVEN - FromFoo actual = new FromFoo(NAME, ID, null, null, null); - - //WHEN - underTest.transform(actual, ImmutableToFooCustomAnnotation.class); - } - - /** - * Test that an exception is thrown if no constructors are defined. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionWhenParameterAreNull() { - //GIVEN - FromFoo actual = new FromFoo(NAME, ID, null, null, null); - - //WHEN - underTest.transform(actual, ImmutableToFooNoConstructors.class); - } - - /** - * Test that an exception is thrown if there is no default constructor defined for the mutable bean object. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionWhenMutableBeanHasNoDefaultConstructor() { - //GIVEN - - //WHEN - underTest.transform(fromFoo, MutableToFooInvalid.class); - } - - /** - * Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionWhenImmutableBeanHasAWrongConstructor() { - //GIVEN - - //WHEN - underTest.transform(fromFoo, ImmutableToFooInvalid.class); - } - - /** - * Test that an exception is thrown if the destination object don't met the constraints. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionIfTheDestinationObjectValuesAreNotValid() { - //GIVEN - fromFoo.setName(null); - - //WHEN - underTest.transform(fromFoo, ImmutableToFoo.class); - - // THEN - fromFoo.setName(NAME); - } - - /** - * Test that no exception is thrown if the destination object don't met the constraints and the validation is disabled. - */ - @Test - public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotValidAndTheValidationIsDisabled() { - //GIVEN - fromFoo.setName(null); - underTest.setValidationDisabled(true); - - //WHEN - ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); - - // THEN - assertThat(actual, sameBeanAs(fromFoo)); - fromFoo.setName(NAME); - underTest.setValidationDisabled(false); - } - - /** - * Test that a Mixed bean with a constructor containing the final field only is correctly copied. - */ - @Test - public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { - //GIVEN - - //WHEN - MixedToFooMissingAllArgsConstructor actual = underTest.transform(fromFoo, MixedToFooMissingAllArgsConstructor.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test mutable beans are correctly copied. - */ - @Test - public void testMutableBeanIsCorrectlyCopied() { - //GIVEN - - //WHEN - MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test that a given field transformer function is applied only to a specific field even if there are other ones with same name. - */ - @Test - public void testFieldTransformationIsAppliedOnlyToASpecificField() { - //GIVEN - String namePrefix = "prefix-"; - FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", val -> namePrefix + val); - - //WHEN - MutableToFoo actual = underTest - .withFieldTransformer(nameTransformer) - .transform(fromFoo, MutableToFoo.class); - - //THEN - assertEquals(fromFoo.getName(), actual.getName()); - assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); - underTest.resetFieldsTransformer(); - } - - /** - * Test that a given field transformer function is applied to all field matching the given name when {@code flatFieldNameTransformation} is set to true. - */ - @Test - public void testFieldTransformationIsAppliedToAllMatchingFields() { - //GIVEN - String namePrefix = "prefix-"; - FieldTransformer nameTransformer = new FieldTransformer<>("name", val -> namePrefix + val); - - //WHEN - MutableToFoo actual = underTest - .setFlatFieldNameTransformation(true) - .withFieldTransformer(nameTransformer) - .transform(fromFoo, MutableToFoo.class); - - //THEN - assertEquals(namePrefix + fromFoo.getName(), actual.getName()); - assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); - underTest.resetFieldsTransformer(); - } - - /** - * Test that bean that extends another class are correctly copied. - */ - @Test - public void testBeanWithoutCustomAnnotationAndWithSuperclassIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFooSubClass actual = underTest.transform(fromFooSubClass, ImmutableToFooSubClass.class); - - //THEN - assertThat(actual, sameBeanAs(fromFooSubClass)); - } - - /** - * Test that bean containing both final fields and not are correctly copied. - */ - @Test - public void testMixedBeanIsCorrectlyCopied() { - //GIVEN - - //WHEN - MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test that bean containing both final fields (with different names) and not are correctly copied. - */ - @Test - public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { - //GIVEN - - //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); - MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); - - //THEN - assertThat(actual, hasProperty("name", equalTo(actual.getName()))); - assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); - assertEquals(actual.getList(), fromFoo.getList()); - IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); - assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); - } - - /** - * Test that bean containing both final fields (with different names) and not are correctly copied through field transformer. - */ - @Test - public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTransformer() { - //GIVEN - /* Extended declaration. - * Function idTransformer = value -> value.negate(); - * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", idTransformer); - */ - FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); - - //WHEN - underTest.withFieldMapping(new FieldMapping("id", "identifier")).withFieldTransformer(fieldTransformer); - MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); - - //THEN - assertThat(actual, hasProperty("name", equalTo(actual.getName()))); - assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId().negate()))); - assertEquals(actual.getList(), fromFoo.getList()); - IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); - assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); - } - - /** - * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. - */ - @Test - public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { - //GIVEN - FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); - FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); - - //WHEN - underTest.withFieldTransformer(ageFieldTransformer); - MixedToFooNotExistingFields mixedObjectBean = underTest.transform(fromFooSimple, MixedToFooNotExistingFields.class); - ImmutableToFooNotExistingFields immutableObjectBean = underTest.transform(fromFooSimple, ImmutableToFooNotExistingFields.class); - MutableToFooNotExistingFields mutableObjectBean = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); - - //THEN - assertThat(mixedObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); - assertThat(immutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); - assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); - } - - /** - * Test that the copy method sets the default value when the source object does not contain a required field. - */ - @Test - public void testMixedBeanWithMissingFieldsReturnsTheDefaultValueWhenTheSourceObjectDoesNotContainARequiredField() { - //GIVEN - underTest.setDefaultValueForMissingField(true); - - //WHEN - MixedToFooMissingField actual = underTest.transform(fromFoo, MixedToFooMissingField.class); - - assertNull(actual.getFooField()); - underTest.setDefaultValueForMissingField(false); - } - - /** - * Test that the copy method raises an exception when the source object does not contain a required field. - */ - @Test(expected = MissingFieldException.class) - public void testMixedBeanWithMissingFieldsThrowsMissingFieldExceptionWhenTheSourceObjectDoesNotContainARequiredField() { - //GIVEN - underTest.setDefaultValueForMissingField(false); - - //WHEN - underTest.transform(fromFoo, MixedToFooMissingField.class); - } - - /** - * Test that bean containing final fields (with different field names) are correctly copied. - */ - @Test - public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { - //GIVEN - - //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); - ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); - - //THEN - assertThat(actual, hasProperty("name", equalTo(actual.getName()))); - assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); - assertEquals(actual.getList(), fromFoo.getList()); - IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); - assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); - } - - /** - * Test that bean containing advanced final fields are correctly copied. - */ - @Test - public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied() { - //GIVEN - - //WHEN - final Transformer beanTransformer = underTest - .withFieldMapping(new FieldMapping("id", "identifier")) - .withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); - ImmutableToFooAdvFields actual = beanTransformer.transform(fromFooAdvFields, ImmutableToFooAdvFields.class); - - //THEN - assertNotNull(actual.getName()); - assertTrue(actual.getName().isPresent()); - assertEquals(fromFooAdvFields.getName().get(), actual.getName().get()); - assertEquals(fromFooAdvFields.getAge().get(), actual.getAge()); - assertEquals(fromFooAdvFields.getClassType(), actual.getClassType()); - assertEquals(fromFooAdvFields.getLocale(), actual.getLocale().getLanguage()); - } - - /** - * Test that immutable bean containing a constructor with some field not annotated with - * {@link com.hotels.beans.annotation.ConstructorArg} is correctly copied. - */ - @Test - public void testImmutableBeanWithMissingConstructorArgIsCorrectlyCopied() { + public void testResetFieldsMappingWorksProperly() { //GIVEN + Transformer beanTransformer = underTest + .withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME), new FieldMapping(SOURCE_FIELD_NAME_2, DEST_FIELD_NAME)); //WHEN - ImmutableToFooMissingCustomAnnotation actual = underTest.withFieldTransformer().transform(fromFooWithPrimitiveFields, ImmutableToFooMissingCustomAnnotation.class); + beanTransformer.resetFieldsMapping(); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertNotNull(actual); - assertEquals(fromFooWithPrimitiveFields.getName(), actual.getName()); + assertTrue(transformerSettings.getFieldsNameMapping().isEmpty()); } /** - * Test that method: {@code getDestFieldName} retrieves the param name from the {@link ConstructorArg} if it is not provided from jvm directly. + * Test that is possible to remove all the fields transformer defined. */ @Test - public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNotProvidedFromJVM() throws Exception { + public void testResetFieldsTransformerWorksProperly() { //GIVEN - String declaringClassName = ImmutableToFoo.class.getName(); - // Parameter mock setup - Parameter constructorParameter = mock(Parameter.class); - when(constructorParameter.getName()).thenReturn(CONSTRUCTOR_PARAMETER_NAME); - - // CacheManager mock setup - initGetDestFieldNameTestMock(declaringClassName, constructorParameter); - Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); - getDestFieldNameMethod.setAccessible(true); + Transformer beanTransformer = underTest + .withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val), new FieldTransformer<>(REFLECTION_UTILS_FIELD_NAME, val -> val)); //WHEN - String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); + beanTransformer.resetFieldsTransformer(); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertEquals(DEST_FIELD_NAME, actual); - - // restore modified objects - restoreObjects(getDestFieldNameMethod); + assertTrue(transformerSettings.getFieldsTransformers().isEmpty()); } /** - * Test that the method: {@code getConstructorValuesFromFields} works properly. + * Test that is possible to remove a field transformer for a given field. */ @Test - public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { + public void testRemoveFieldTransformerWorksProperly() { //GIVEN - underTest.withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); + Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); //WHEN - final Method getConstructorValuesFromFieldsMethod = - underTest.getClass().getDeclaredMethod(GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME, Object.class, Class.class, String.class); - getConstructorValuesFromFieldsMethod.setAccessible(true); - Object[] actual = (Object[]) getConstructorValuesFromFieldsMethod.invoke(underTest, fromFooAdvFields, ImmutableToFooAdvFields.class, ""); + beanTransformer.removeFieldTransformer(DEST_FIELD_NAME); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertNotNull(actual); - assertEquals(TOTAL_ADV_CLASS_FIELDS, actual.length); - - // restore modified objects - restoreObjects(getConstructorValuesFromFieldsMethod); + assertFalse(transformerSettings.getFieldsTransformers().containsKey(DEST_FIELD_NAME)); } /** - * Test that method: {@code getDestFieldName} returns null if the constructor's parameter name is not provided from jvm directly and the {@link ConstructorArg} is not defined. + * Test that the method {@code removeFieldTransformer} raises an {@link IllegalArgumentException} if the parameter is null. */ - @Test - public void testGetDestFieldNameReturnsNullIfConstructorParamHasNoNameProvidedFromJVMAndNoConstructorArgIsDefined() throws Exception { + @Test(expected = IllegalArgumentException.class) + public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() { //GIVEN - String declaringClassName = ImmutableToFoo.class.getName(); - // Parameter mock setup - Parameter constructorParameter = mock(Parameter.class); - when(constructorParameter.getName()).thenReturn(null); - - // CacheManager mock setup - initGetDestFieldNameTestMock(declaringClassName, constructorParameter); - Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); - getDestFieldNameMethod.setAccessible(true); - - //WHEN - String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); - - //THEN - assertEquals(DEST_FIELD_NAME, actual); - - // restore modified objects - restoreObjects(getDestFieldNameMethod); - } + Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - /** - * Test that the transformer is able to copy object even if the source object has no setter methods and the destination - * object has no setter methods. - */ - @Test - public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { - //GIVEN - FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, ID); //WHEN - MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); - - //THEN - assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); + beanTransformer.removeFieldTransformer(null); } /** @@ -690,135 +158,4 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro getSourceFieldValueMethod.invoke(underTest, null, null, null, false); } - /** - * Test that a meaningful exception is returned when a constructor is invoked with wrong arguments. - */ - @Test - public void testTransformationReturnsAMeaningfulException() { - //GIVEN - Class targetClass = ImmutableToFooSimpleWrongTypes.class; - final String expectedExceptionMessageFormat = - "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " - + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration."; - String targetClassName = targetClass.getCanonicalName(); - String expectedExceptionMessage = - format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getCanonicalName()); - - //WHEN - Exception raisedException = null; - try { - underTest.transform(fromFooSimple, targetClass); - } catch (final Exception e) { - raisedException = e; - } - - //THEN - assertNotNull(raisedException); - assertEquals(InvalidBeanException.class, raisedException.getClass()); - assertEquals(expectedExceptionMessage, raisedException.getMessage()); - } - - /** - * Test transformation on an existing bean is correctly copied. - */ - @Test - public void testTransformationOnAnExistingDestinationWorksProperly() { - //GIVEN - MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); - ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null); - - //WHEN - underTest.transform(fromFooSubClass, mutableToFoo); - underTest.transform(fromFooSimple, immutableToFoo); - - //THEN - assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); - assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); - } - - /** - * Initializes the mocks required for testing method: {@code getDestFieldName}. - * @param declaringClassName the declaring class name - * @param constructorParameter the constructor parameter - */ - private void initGetDestFieldNameTestMock(final String declaringClassName, final Parameter constructorParameter) { - CacheManager cacheManager = mock(CacheManager.class); - String cacheKey = "DestFieldName-" + declaringClassName + "-" + CONSTRUCTOR_PARAMETER_NAME; - when(cacheManager.getFromCache(cacheKey, String.class)).thenReturn(null); - // ConstructorArg mock setup - ConstructorArg constructorArg = mock(ConstructorArg.class); - when(constructorArg.value()).thenReturn(DEST_FIELD_NAME); - // ReflectionUtils mock setup - ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); - when(reflectionUtils.getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)).thenReturn(constructorArg); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); - } - - /** - * Restored the initial object status before testing method: {@code getDestFieldName}. - */ - private void restoreObjects(final Method getDestFieldNameMethod) { - getDestFieldNameMethod.setAccessible(false); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, new ReflectionUtils()); - } - - /** - * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. - */ - private static void initObjects() { - SUB_FOO_SAMPLE_MAP.put(ITEM_1, ITEM_2); - SUB_FOO_COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); - SUB_FOO_VERY_COMPLEX_MAP.put(ITEM_1, SUB_FOO_SAMPLE_MAP); - fromSubFoo = new FromSubFoo(SUB_FOO_NAME, SUB_FOO_PHONE_NUMBERS, SUB_FOO_SAMPLE_MAP, SUB_FOO_COMPLEX_MAP, SUB_FOO_VERY_COMPLEX_MAP); - fromSubFooList = singletonList(fromSubFoo); - sourceFooSimpleList = asList(ITEM_1, ITEM_2); - fromFoo = createFromFoo(fromSubFoo); - fromFooWithNullProperties = createFromFoo(null); - fromFooSimple = createFromFooSimple(); - fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); - fromFooSubClass = createFromFooSubClass(); - fromFooAdvFields = createFromFooAdvFields(); - } - - /** - * Creates a {@link FromFoo} instance. - * @param fromSubFoo the {@link FromSubFoo} instance - * @return the {@link FromFoo} instance. - */ - private static FromFoo createFromFoo(final FromSubFoo fromSubFoo) { - return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); - } - - /** - * Creates a {@link FromFooSimple} instance. - * @return the {@link FromFooSimple} instance. - */ - private static FromFooSimple createFromFooSimple() { - return new FromFooSimple(NAME, ID); - } - - - /** - * Creates a {@link FromFooWithPrimitiveFields} instance. - * @return the {@link FromFooWithPrimitiveFields} instance. - */ - private static FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { - return new FromFooWithPrimitiveFields(NAME, ID.intValue(), AGE, fromSubFooList, sourceFooSimpleList, fromSubFoo); - } - - /** - * Creates a {@link FromFooSubClass} instance. - * @return the {@link FromFooSubClass} instance. - */ - private static FromFooSubClass createFromFooSubClass() { - return new FromFooSubClass(fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObjectList(), fromFoo.getList(), fromFoo.getNestedObject(), SURNAME, PHONE, CHECK, AMOUNT); - } - - /** - * Creates a {@link FromFooAdvFields} instance. - * @return the {@link FromFooAdvFields} instance. - */ - private static FromFooAdvFields createFromFooAdvFields() { - return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage()); - } } diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index a152ac5c7..a287041f0 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -58,7 +58,6 @@ public class ReflectionUtilsTest { private static final String LIST_FIELD_NAME = "list"; private static final String GETTER_METHOD_PREFIX_METHOD_NAME = "getGetterMethodPrefix"; private static final String CHECK_FIELD_NAME = "check"; - private static final String NAME_FIELD = "name"; private static final String EXPECTED_SETTER_METHOD_NAME = "setId"; /** @@ -198,7 +197,7 @@ public void testGetGetterMethodPrefixWorksAsExpected() throws Exception { @Test public void testGetFieldAnnotationWorksProperly() throws NoSuchFieldException { // GIVEN - Field nameField = ImmutableToFoo.class.getDeclaredField(NAME_FIELD); + Field nameField = ImmutableToFoo.class.getDeclaredField(ID_FIELD_NAME); // WHEN final NotNull notNullFieldAnnotation = underTest.getFieldAnnotation(nameField, NotNull.class); From 99d3b4e0def61438be77f78f62a45e1fadb34ffd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 10:38:42 +0100 Subject: [PATCH 0293/1786] Added test case for the new feature implemented --- CHANGELOG.md | 2 +- .../ImmutableObjectTransformationTest.java | 4 ---- .../MixedObjectTransformationTest.java | 15 +++++++++++++++ .../MutableObjectTransformationTest.java | 16 ++++++++++++++++ 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a22cc4533..d9aa6ba78 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.2.1] 2019.03.05 #### Added -* Implemented new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) +* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) * Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` ### [1.2.0] 2019.02.25 diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index b0735cb91..fb0cc8670 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -60,7 +60,6 @@ import com.hotels.beans.sample.immutable.ImmutableToFooSimple; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.beans.sample.mutable.MutableToFooSubClass; import com.hotels.beans.utils.ReflectionUtils; /** @@ -428,15 +427,12 @@ public void testTransformationReturnsAMeaningfulException() { @Test public void testTransformationOnAnExistingDestinationWorksProperly() { //GIVEN - MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null); //WHEN - underTest.transform(fromFooSubClass, mutableToFoo); underTest.transform(fromFooSimple, immutableToFoo); //THEN - assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); } diff --git a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 69a7b49fb..5d658bc4b 100644 --- a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -176,4 +176,19 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor //THEN assertThat(mixedObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } + + /** + * Test transformation on an existing bean is correctly copied. + */ + @Test + public void testTransformationOnAnExistingDestinationWorksProperly() { + //GIVEN + MixedToFoo mixedToFoo = new MixedToFoo(null, null, null, null, null); + + //WHEN + underTest.transform(fromFoo, mixedToFoo); + + //THEN + assertThat(mixedToFoo, sameBeanAs(fromFoo)); + } } diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 8f0b00b40..7d56f9340 100644 --- a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -36,6 +36,7 @@ import com.hotels.beans.sample.mutable.MutableToFooInvalid; import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; +import com.hotels.beans.sample.mutable.MutableToFooSubClass; /** * Unit test for all {@link Transformer} functions related to Mutable type Java Beans. @@ -152,4 +153,19 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor //THEN assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } + + /** + * Test transformation on an existing bean is correctly copied. + */ + @Test + public void testTransformationOnAnExistingDestinationWorksProperly() { + //GIVEN + MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); + + //WHEN + underTest.transform(fromFooSubClass, mutableToFoo); + + //THEN + assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); + } } From 2cb6074720f4ca81d801c6e72c6ae44cc2d5ec79 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 10:39:27 +0100 Subject: [PATCH 0294/1786] minor: fixed typo error in pr template file --- PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index a199360c1..4009c0b56 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -17,7 +17,7 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code -- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] Any dependent changes have been merged and published in downstream modules From ccb0e93637b7b9e758073cbf8e12eec16fbbee34 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 10:40:24 +0100 Subject: [PATCH 0295/1786] Removed not needed setting --- .../com/hotels/beans/transformer/TransformerSettings.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index a270861a3..22d4b4433 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -47,11 +47,6 @@ final class TransformerSettings { */ private final Map> fieldsTransformers = new ConcurrentHashMap<>(); - /** - * Contains the list of fields that don't need to be transformed. - */ - private final Map fieldsToSkip = new ConcurrentHashMap<>(); - /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. From 443b63a6a36705741e9a2850518e5999bbfedefb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 10:43:13 +0100 Subject: [PATCH 0296/1786] removed reset on a no longer existing property --- .../com/hotels/beans/transformer/AbstractTransformer.java | 5 ----- src/main/java/com/hotels/beans/transformer/Transformer.java | 5 ----- 2 files changed, 10 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 5f4dc560e..26c70aaca 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -187,11 +187,6 @@ public final void transform(final T sourceObj, final K targetObject) { transform(sourceObj, targetObject, null); } - @Override - public void resetFieldsTransformationSkip() { - settings.getFieldsToSkip().clear(); - } - /** * Copies all properties from an object to a new one. * @param sourceObj the source object diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index ff9de7bf3..986a607e4 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -105,9 +105,4 @@ public interface Transformer { * @return the {@link Transformer} instance */ Transformer setValidationDisabled(boolean validationDisabled); - - /** - * Removes all the configured fields to skip. - */ - void resetFieldsTransformationSkip(); } From 4a625891220558dfde7341a65e4ba1008159e6a0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 11:10:37 +0100 Subject: [PATCH 0297/1786] [maven-release-plugin] prepare release 1.2.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c480e599c..0f85d6de5 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.1-SNAPSHOT + 1.2.1 jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.1 From 37d4ad281186834848d6ed624685498dbc381a8a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 11:10:45 +0100 Subject: [PATCH 0298/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 0f85d6de5..6aadf0197 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.1 + 1.2.2-SNAPSHOT jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.1 + HEAD From 2d73ab8fd39b85385f3922539311607221185c09 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 11:52:51 +0100 Subject: [PATCH 0299/1786] Aligned features with master branch, updated javadoc. This gives the possibility to use the project with both java 8 and java 11 --- CHANGELOG.md | 5 +++++ pom.xml | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9aa6ba78..5d2984af7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.6] 2019.03.05 +#### Added +* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) for project compiled with `jdk` 8. +* Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` + ### [1.1.5] 2019.03.03 #### Added * Added all new features into the java 8 project version. diff --git a/pom.xml b/pom.xml index 6aadf0197..a786d59cb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.2-SNAPSHOT + 1.1.6-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 From c06a84f5e3b125d955cc75aac98fa001371330bb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 11:55:31 +0100 Subject: [PATCH 0300/1786] [maven-release-plugin] prepare release 1.1.6 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a786d59cb..6aadf0197 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.6-SNAPSHOT + 1.2.2-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 From a5749facd8999b98cb5cc1814440332f938a002c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 11:55:38 +0100 Subject: [PATCH 0301/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6aadf0197..a9568f205 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.2-SNAPSHOT + 1.1.7-SNAPSHOT jar 2019 From ae64fdbb300dddbbe0186023c595a1c443fcb549 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 11:56:43 +0100 Subject: [PATCH 0302/1786] prepare deploy for java 8 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a9568f205..a786d59cb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.7-SNAPSHOT + 1.1.6-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 From 19b4a2c2731d34d1c33e5a8ad70bf30cf65296cd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 11:58:30 +0100 Subject: [PATCH 0303/1786] [maven-release-plugin] prepare release 1.1.6 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a786d59cb..a07cf6c52 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.6-SNAPSHOT + 1.1.6 jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.6 From 447c78617a890c29381e9b9c7c2bf3c18d129345 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 11:58:37 +0100 Subject: [PATCH 0304/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a07cf6c52..fd2ffd0b4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.6 + 1.1.7-SNAPSHOT jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.6 + HEAD From 08cc083f011f6b028fc8699cc387358978068d58 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 12:02:18 +0100 Subject: [PATCH 0305/1786] [maven-release-plugin] prepare release 1.1.7 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index fd2ffd0b4..21d6b18bf 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.7-SNAPSHOT + 1.1.7 jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.7 From 87f91b70386f628c510277a8c0ac5a573c2d4e1b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 12:02:27 +0100 Subject: [PATCH 0306/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 21d6b18bf..9c8e31990 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.7 + 1.1.8-SNAPSHOT jar 2019 @@ -56,7 +56,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.7 + HEAD From bc905b365e0e68795437bd590cfb7f504ed1ca47 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 5 Mar 2019 12:07:55 +0100 Subject: [PATCH 0307/1786] Restored version and java version settings --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9c8e31990..6aadf0197 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.8-SNAPSHOT + 1.2.2-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 From 818e0e39847e16a6ffa1e508832b40ab1f4aacca Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 7 Mar 2019 15:45:05 +0100 Subject: [PATCH 0308/1786] - Added possibility to skip field transformation - Transformer test class has been split into different files in order to increase the usability --- .../transformer/AbstractTransformer.java | 17 + .../hotels/beans/transformer/Transformer.java | 12 + .../beans/transformer/TransformerImpl.java | 12 + .../transformer/TransformerSettings.java | 5 + .../java/com/hotels/beans/sample/FromFoo.java | 4 +- .../sample/immutable/ImmutableToFoo.java | 1 - .../sample/immutable/ImmutableToSubFoo.java | 3 - .../transformer/AbstractTransformerTest.java | 164 ++-- .../ImmutableObjectTransformationTest.java | 504 ++++++++++++ .../MixedObjectTransformationTest.java | 197 +++++ .../MutableObjectTransformationTest.java | 174 ++++ .../beans/transformer/TransformerTest.java | 745 +----------------- .../beans/utils/ReflectionUtilsTest.java | 3 +- 13 files changed, 1055 insertions(+), 786 deletions(-) create mode 100644 src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java create mode 100644 src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java create mode 100644 src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 26c70aaca..6f7dda121 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -187,6 +187,23 @@ public final void transform(final T sourceObj, final K targetObject) { transform(sourceObj, targetObject, null); } + /** + * {@inheritDoc} + */ + @Override + public Transformer skipTransformationForField(final String... fieldName) { + final Map fieldsToSkip = settings.getFieldsToSkip(); + for (String tmpField: fieldName) { + fieldsToSkip.put(tmpField, tmpField); + } + return this; + } + + @Override + public void resetFieldsTransformationSkip() { + settings.getFieldsToSkip().clear(); + } + /** * Copies all properties from an object to a new one. * @param sourceObj the source object diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index 986a607e4..77b0761f2 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -105,4 +105,16 @@ public interface Transformer { * @return the {@link Transformer} instance */ Transformer setValidationDisabled(boolean validationDisabled); + + /** + * Allows to specify all the fields for which the transformation have to be skipped. + * @param fieldName the destination object's fields names + * @return the {@link Transformer} instance + */ + Transformer skipTransformationForField(String... fieldName); + + /** + * Removes all the configured fields to skip. + */ + void resetFieldsTransformationSkip(); } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 88e68a033..83640c80e 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -177,6 +177,15 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< return constructorArgsValues; } + /** + * Checks if a field has to be transformed or not. + * @param breadcrumb the field path + * @return true if the transformation has to be applied on this field, false in it has to be skipped. + */ + private boolean isAFieldToTransform(final String breadcrumb) { + return isNull(breadcrumb) || !settings.getFieldsToSkip().containsKey(breadcrumb); + } + /** * Returns the field name in the source object. * @param field the field that has to be valorized. @@ -299,6 +308,9 @@ private Object getFieldValue(final T sourceObj, final Class targetClas private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); boolean primitiveType = classUtils.isPrimitiveType(field.getType()); + if (!isAFieldToTransform(fieldBreadcrumb)) { + return !primitiveType ? null : defaultValue(field.getType()); + } boolean isFieldTransformerDefined = settings.getFieldsTransformers().containsKey(field.getName()); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); if (nonNull(fieldValue)) { diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 22d4b4433..a270861a3 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -47,6 +47,11 @@ final class TransformerSettings { */ private final Map> fieldsTransformers = new ConcurrentHashMap<>(); + /** + * Contains the list of fields that don't need to be transformed. + */ + private final Map fieldsToSkip = new ConcurrentHashMap<>(); + /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. diff --git a/src/test/java/com/hotels/beans/sample/FromFoo.java b/src/test/java/com/hotels/beans/sample/FromFoo.java index 010259073..d6387a10f 100644 --- a/src/test/java/com/hotels/beans/sample/FromFoo.java +++ b/src/test/java/com/hotels/beans/sample/FromFoo.java @@ -30,8 +30,8 @@ @Getter @Setter public class FromFoo { - private String name; - private final BigInteger id; + private final String name; + private BigInteger id; private final List nestedObjectList; private final List list; private final FromSubFoo nestedObject; diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java index 3e566251e..cd1b0ad58 100644 --- a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java @@ -30,7 +30,6 @@ @AllArgsConstructor @Getter public class ImmutableToFoo { - @NotNull private final String name; @NotNull private final BigInteger id; diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java index 1e7a2c4ec..ec539a5bc 100644 --- a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java @@ -19,8 +19,6 @@ import java.util.List; import java.util.Map; -import javax.validation.constraints.NotNull; - import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; @@ -32,7 +30,6 @@ @Getter @ToString public class ImmutableToSubFoo { - @NotNull private final String name; private final int[] phoneNumbers; private final Map sampleMap; diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index fc8b65120..bc3887720 100644 --- a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -16,111 +16,127 @@ package com.hotels.beans.transformer; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.MockitoAnnotations.initMocks; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; -import org.junit.Before; -import org.junit.Test; +import static com.hotels.beans.constant.ClassType.IMMUTABLE; -import com.hotels.beans.model.FieldMapping; -import com.hotels.beans.model.FieldTransformer; -import com.hotels.beans.utils.ReflectionUtils; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +import org.junit.BeforeClass; + +import com.hotels.beans.sample.FromFoo; +import com.hotels.beans.sample.FromFooAdvFields; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.FromFooSubClass; +import com.hotels.beans.sample.FromFooWithPrimitiveFields; +import com.hotels.beans.sample.FromSubFoo; /** - * Unit test for class: {@link AbstractTransformer}. + * Unit test for {@link Transformer}. */ public class AbstractTransformerTest { - private static final String SOURCE_FIELD_NAME = "sourceFieldName"; - private static final String SOURCE_FIELD_NAME_2 = "sourceFieldName2"; - private static final String DEST_FIELD_NAME = "destFieldName"; - private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; - private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); + protected static final BigInteger ID = new BigInteger("1234"); + protected static final String NAME = "Goofy"; + protected static FromFoo fromFoo; + protected static FromFoo fromFooWithNullProperties; + protected static FromFooSimple fromFooSimple; + protected static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; + protected static List fromSubFooList; + protected static List sourceFooSimpleList; + protected static FromSubFoo fromSubFoo; + protected static FromFooSubClass fromFooSubClass; + protected static FromFooAdvFields fromFooAdvFields; + protected static final int AGE = 34; + protected static final String AGE_FIELD_NAME = "age"; + protected static final String DEST_FIELD_NAME = "destFieldName"; + protected static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; + protected static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; + + private static final String ITEM_1 = "donald"; + private static final String ITEM_2 = "duck"; + private static final String SURNAME = "surname"; + private static final int PHONE = 123; + private static final String INDEX_NUMBER = null; + private static final boolean CHECK = true; + private static final BigDecimal AMOUNT = new BigDecimal(10); + private static final String SUB_FOO_NAME = "Smith"; + private static final int[] SUB_FOO_PHONE_NUMBERS = {12345, 6892, 10873}; + private static final Map SUB_FOO_SAMPLE_MAP = new HashMap<>(); + private static final Map> SUB_FOO_COMPLEX_MAP = new HashMap<>(); + private static final Map> SUB_FOO_VERY_COMPLEX_MAP = new HashMap<>(); /** - * The class to be tested. + * Initializes the arguments and objects. */ - private AbstractTransformer underTest; + @BeforeClass + public static void beforeClass() { + initObjects(); + } /** - * Initialized mocks. + * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. */ - @Before - public void beforeMethod() { - underTest = new TransformerImpl(); - initMocks(this); + private static void initObjects() { + SUB_FOO_SAMPLE_MAP.put(ITEM_1, ITEM_2); + SUB_FOO_COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); + SUB_FOO_VERY_COMPLEX_MAP.put(ITEM_1, SUB_FOO_SAMPLE_MAP); + fromSubFoo = new FromSubFoo(SUB_FOO_NAME, SUB_FOO_PHONE_NUMBERS, SUB_FOO_SAMPLE_MAP, SUB_FOO_COMPLEX_MAP, SUB_FOO_VERY_COMPLEX_MAP); + fromSubFooList = singletonList(fromSubFoo); + sourceFooSimpleList = asList(ITEM_1, ITEM_2); + fromFoo = createFromFoo(fromSubFoo); + fromFooWithNullProperties = createFromFoo(null); + fromFooSimple = createFromFooSimple(); + fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); + fromFooSubClass = createFromFooSubClass(); + fromFooAdvFields = createFromFooAdvFields(); } /** - * Test that is possible to remove a field mapping for a given field. + * Creates a {@link FromFoo} instance. + * @param fromSubFoo the {@link FromSubFoo} instance + * @return the {@link FromFoo} instance. */ - @Test - public void testRemoveFieldMappingWorksProperly() { - //GIVEN - Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); - - //WHEN - beanTransformer.removeFieldMapping(DEST_FIELD_NAME); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - - //THEN - assertFalse(transformerSettings.getFieldsNameMapping().containsKey(DEST_FIELD_NAME)); + private static FromFoo createFromFoo(final FromSubFoo fromSubFoo) { + return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); } /** - * Test that the method {@code removeFieldMapping} raises an {@link IllegalArgumentException} if the parameter is null. + * Creates a {@link FromFooSimple} instance. + * @return the {@link FromFooSimple} instance. */ - @Test(expected = IllegalArgumentException.class) - public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { - //GIVEN - Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); - - //WHEN - beanTransformer.removeFieldMapping(null); + private static FromFooSimple createFromFooSimple() { + return new FromFooSimple(NAME, ID); } + /** - * Test that is possible to remove all the fields mappings defined. + * Creates a {@link FromFooWithPrimitiveFields} instance. + * @return the {@link FromFooWithPrimitiveFields} instance. */ - @Test - public void testResetFieldsMappingWorksProperly() { - //GIVEN - Transformer beanTransformer = underTest - .withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME), new FieldMapping(SOURCE_FIELD_NAME_2, DEST_FIELD_NAME)); - - //WHEN - beanTransformer.resetFieldsMapping(); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - - //THEN - assertTrue(transformerSettings.getFieldsNameMapping().isEmpty()); + private static FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { + return new FromFooWithPrimitiveFields(NAME, ID.intValue(), AGE, fromSubFooList, sourceFooSimpleList, fromSubFoo); } /** - * Test that is possible to remove a field transformer for a given field. + * Creates a {@link FromFooSubClass} instance. + * @return the {@link FromFooSubClass} instance. */ - @Test - public void testRemoveFieldTransformerWorksProperly() { - //GIVEN - Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - - //WHEN - beanTransformer.removeFieldTransformer(DEST_FIELD_NAME); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - - //THEN - assertFalse(transformerSettings.getFieldsTransformers().containsKey(DEST_FIELD_NAME)); + private static FromFooSubClass createFromFooSubClass() { + return new FromFooSubClass(fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObjectList(), fromFoo.getList(), fromFoo.getNestedObject(), SURNAME, PHONE, CHECK, AMOUNT); } /** - * Test that the method {@code removeFieldTransformer} raises an {@link IllegalArgumentException} if the parameter is null. + * Creates a {@link FromFooAdvFields} instance. + * @return the {@link FromFooAdvFields} instance. */ - @Test(expected = IllegalArgumentException.class) - public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() { - //GIVEN - Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - - //WHEN - beanTransformer.removeFieldTransformer(null); + private static FromFooAdvFields createFromFooAdvFields() { + return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage()); } } diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java new file mode 100644 index 000000000..6d20e3e8a --- /dev/null +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -0,0 +1,504 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import static java.lang.String.format; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasProperty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Locale; +import java.util.stream.IntStream; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.annotation.ConstructorArg; +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.model.FieldMapping; +import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.sample.FromFoo; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.immutable.ImmutableFlatToFoo; +import com.hotels.beans.sample.immutable.ImmutableToFoo; +import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; +import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; +import com.hotels.beans.sample.immutable.ImmutableToFooDiffFields; +import com.hotels.beans.sample.immutable.ImmutableToFooInvalid; +import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; +import com.hotels.beans.sample.immutable.ImmutableToFooNoConstructors; +import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; +import com.hotels.beans.sample.immutable.ImmutableToFooSimple; +import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; +import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; +import com.hotels.beans.sample.mutable.MutableToFooSubClass; +import com.hotels.beans.utils.ReflectionUtils; + +/** + * Unit test for all {@link Transformer} functions related to Immutable Java Beans. + */ +public class ImmutableObjectTransformationTest extends AbstractTransformerTest { + private static final int TOTAL_ADV_CLASS_FIELDS = 5; + private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; + private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; + + /** + * The class to be tested. + */ + @InjectMocks + private TransformerImpl underTest; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + } + + /** + * Test that immutable beans without constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. + */ + @Test + public void testBeanWithoutCustomAnnotationIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly + * valorized. + */ + @Test + public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected() { + //GIVEN + FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); + + //WHEN + ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFoo, ImmutableFlatToFoo.class); + + //THEN + assertEquals(fromFoo.getName(), actual.getName()); + assertEquals(fromFoo.getId(), actual.getId()); + assertEquals(fromFoo.getNestedObject().getPhoneNumbers(), actual.getPhoneNumbers()); + underTest.resetFieldsMapping(); + } + + /** + * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly + * valorized even if some of them are null. + */ + @Test + public void testTransformationWithCompositeFieldNameWorksEvenWithNullObjects() { + //GIVEN + FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); + + //WHEN + ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFooWithNullProperties, ImmutableFlatToFoo.class); + + //THEN + assertEquals(fromFooWithNullProperties.getName(), actual.getName()); + assertEquals(fromFooWithNullProperties.getId(), actual.getId()); + assertNull(actual.getPhoneNumbers()); + underTest.resetFieldsMapping(); + } + + /** + * Test that immutable beans without custom field mapping. + */ + @Test + public void testBeanWithEmptyFieldMappingIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that immutable beans without custom field mapping. + */ + @Test + public void testBeanWithEmptyFieldTransformerIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. + */ + @Test + public void testBeanWithCustomAnnotationIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFooCustomAnnotation actual = underTest.transform(fromFoo, ImmutableToFooCustomAnnotation.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that an exception is thrown if the constructor invocation throws exception. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsException() { + //GIVEN + FromFoo actual = new FromFoo(NAME, ID, null, null, null); + + //WHEN + underTest.transform(actual, ImmutableToFooCustomAnnotation.class); + } + + /** + * Test that an exception is thrown if no constructors are defined. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionWhenParameterAreNull() { + //GIVEN + FromFoo actual = new FromFoo(NAME, ID, null, null, null); + + //WHEN + underTest.transform(actual, ImmutableToFooNoConstructors.class); + } + + + /** + * Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionWhenImmutableBeanHasAWrongConstructor() { + //GIVEN + + //WHEN + underTest.transform(fromFoo, ImmutableToFooInvalid.class); + } + + /** + * Test that an exception is thrown if the destination object don't met the constraints. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionIfTheDestinationObjectValuesAreNotValid() { + //GIVEN + fromFoo.setId(null); + + //WHEN + underTest.transform(fromFoo, ImmutableToFoo.class); + + // THEN + fromFoo.setId(ID); + } + + /** + * Test that no exception is thrown if the destination object don't met the constraints and the validation is disabled. + */ + @Test + public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotValidAndTheValidationIsDisabled() { + //GIVEN + fromFoo.setId(null); + underTest.setValidationDisabled(true); + + //WHEN + ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); + + // THEN + assertThat(actual, sameBeanAs(fromFoo)); + fromFoo.setId(ID); + underTest.setValidationDisabled(false); + } + + /** + * Test that bean that extends another class are correctly copied. + */ + @Test + public void testBeanWithoutCustomAnnotationAndWithSuperclassIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFooSubClass actual = underTest.transform(fromFooSubClass, ImmutableToFooSubClass.class); + + //THEN + assertThat(actual, sameBeanAs(fromFooSubClass)); + } + + /** + * Test that bean containing final fields (with different field names) are correctly copied. + */ + @Test + public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { + //GIVEN + + //WHEN + final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); + ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); + + //THEN + assertThat(actual, hasProperty("name", equalTo(actual.getName()))); + assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); + assertEquals(actual.getList(), fromFoo.getList()); + IntStream.range(0, actual.getNestedObjectList().size()) + .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); + assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); + } + + /** + * Test that bean containing advanced final fields are correctly copied. + */ + @Test + public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied() { + //GIVEN + + //WHEN + final Transformer beanTransformer = underTest + .withFieldMapping(new FieldMapping("id", "identifier")) + .withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); + ImmutableToFooAdvFields actual = beanTransformer.transform(fromFooAdvFields, ImmutableToFooAdvFields.class); + + //THEN + assertNotNull(actual.getName()); + assertTrue(actual.getName().isPresent()); + assertEquals(fromFooAdvFields.getName().get(), actual.getName().get()); + assertEquals(fromFooAdvFields.getAge().get(), actual.getAge()); + assertEquals(fromFooAdvFields.getClassType(), actual.getClassType()); + assertEquals(fromFooAdvFields.getLocale(), actual.getLocale().getLanguage()); + } + + /** + * Test that immutable bean containing a constructor with some field not annotated with + * {@link com.hotels.beans.annotation.ConstructorArg} is correctly copied. + */ + @Test + public void testImmutableBeanWithMissingConstructorArgIsCorrectlyCopied() { + //GIVEN + + //WHEN + ImmutableToFooMissingCustomAnnotation actual = underTest.withFieldTransformer().transform(fromFooWithPrimitiveFields, ImmutableToFooMissingCustomAnnotation.class); + + //THEN + assertNotNull(actual); + assertEquals(fromFooWithPrimitiveFields.getName(), actual.getName()); + } + + /** + * Test that method: {@code getDestFieldName} retrieves the param name from the {@link ConstructorArg} if it is not provided from jvm directly. + */ + @Test + public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNotProvidedFromJVM() throws Exception { + //GIVEN + String declaringClassName = ImmutableToFoo.class.getName(); + // Parameter mock setup + Parameter constructorParameter = mock(Parameter.class); + when(constructorParameter.getName()).thenReturn(CONSTRUCTOR_PARAMETER_NAME); + + // CacheManager mock setup + initGetDestFieldNameTestMock(declaringClassName, constructorParameter); + Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); + getDestFieldNameMethod.setAccessible(true); + + //WHEN + String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); + + //THEN + assertEquals(DEST_FIELD_NAME, actual); + + // restore modified objects + restoreObjects(getDestFieldNameMethod); + } + + /** + * Test that the method: {@code getConstructorValuesFromFields} works properly. + */ + @Test + public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { + //GIVEN + underTest.withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); + + //WHEN + final Method getConstructorValuesFromFieldsMethod = + underTest.getClass().getDeclaredMethod(GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME, Object.class, Class.class, String.class); + getConstructorValuesFromFieldsMethod.setAccessible(true); + Object[] actual = (Object[]) getConstructorValuesFromFieldsMethod.invoke(underTest, fromFooAdvFields, ImmutableToFooAdvFields.class, ""); + + //THEN + assertNotNull(actual); + assertEquals(TOTAL_ADV_CLASS_FIELDS, actual.length); + + // restore modified objects + restoreObjects(getConstructorValuesFromFieldsMethod); + } + + /** + * Test that method: {@code getDestFieldName} returns null if the constructor's parameter name is not provided from jvm directly and the {@link ConstructorArg} is not defined. + */ + @Test + public void testGetDestFieldNameReturnsNullIfConstructorParamHasNoNameProvidedFromJVMAndNoConstructorArgIsDefined() throws Exception { + //GIVEN + String declaringClassName = ImmutableToFoo.class.getName(); + // Parameter mock setup + Parameter constructorParameter = mock(Parameter.class); + when(constructorParameter.getName()).thenReturn(null); + + // CacheManager mock setup + initGetDestFieldNameTestMock(declaringClassName, constructorParameter); + Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); + getDestFieldNameMethod.setAccessible(true); + + //WHEN + String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); + + //THEN + assertEquals(DEST_FIELD_NAME, actual); + + // restore modified objects + restoreObjects(getDestFieldNameMethod); + } + + /** + * Test that a meaningful exception is returned when a constructor is invoked with wrong arguments. + */ + @Test + public void testTransformationReturnsAMeaningfulException() { + //GIVEN + Class targetClass = ImmutableToFooSimpleWrongTypes.class; + final String expectedExceptionMessageFormat = + "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " + + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration."; + String targetClassName = targetClass.getCanonicalName(); + String expectedExceptionMessage = + format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getCanonicalName()); + + //WHEN + Exception raisedException = null; + try { + underTest.transform(fromFooSimple, targetClass); + } catch (final Exception e) { + raisedException = e; + } + + //THEN + assertNotNull(raisedException); + assertEquals(InvalidBeanException.class, raisedException.getClass()); + assertEquals(expectedExceptionMessage, raisedException.getMessage()); + } + + /** + * Test transformation on an existing bean is correctly copied. + */ + @Test + public void testTransformationOnAnExistingDestinationWorksProperly() { + //GIVEN + MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); + ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null); + + //WHEN + underTest.transform(fromFooSubClass, mutableToFoo); + underTest.transform(fromFooSimple, immutableToFoo); + + //THEN + assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); + assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); + } + + /** + * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. + */ + @Test + public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); + + //WHEN + underTest.withFieldTransformer(ageFieldTransformer); + ImmutableToFooNotExistingFields immutableObjectBean = underTest.transform(fromFooSimple, ImmutableToFooNotExistingFields.class); + + //THEN + assertThat(immutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + } + + /** + * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. + */ + @Test + public void testFieldTransformationSkipWorksProperly() { + //GIVEN + underTest.skipTransformationForField("name", "nestedObject.phoneNumbers"); + + //WHEN + ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); + + //THEN + assertEquals(fromFoo.getId(), actual.getId()); + assertNull(actual.getName()); + assertNull(actual.getNestedObject().getPhoneNumbers()); + underTest.resetFieldsTransformationSkip(); + } + + /** + * Initializes the mocks required for testing method: {@code getDestFieldName}. + * @param declaringClassName the declaring class name + * @param constructorParameter the constructor parameter + */ + private void initGetDestFieldNameTestMock(final String declaringClassName, final Parameter constructorParameter) { + CacheManager cacheManager = mock(CacheManager.class); + String cacheKey = "DestFieldName-" + declaringClassName + "-" + CONSTRUCTOR_PARAMETER_NAME; + when(cacheManager.getFromCache(cacheKey, String.class)).thenReturn(null); + // ConstructorArg mock setup + ConstructorArg constructorArg = mock(ConstructorArg.class); + when(constructorArg.value()).thenReturn(DEST_FIELD_NAME); + // ReflectionUtils mock setup + ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + when(reflectionUtils.getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)).thenReturn(constructorArg); + setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); + } + + /** + * Restored the initial object status before testing method: {@code getDestFieldName}. + */ + private void restoreObjects(final Method getDestFieldNameMethod) { + getDestFieldNameMethod.setAccessible(false); + setField(underTest, REFLECTION_UTILS_FIELD_NAME, new ReflectionUtils()); + } + +} diff --git a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java new file mode 100644 index 000000000..023d7355b --- /dev/null +++ b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -0,0 +1,197 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasProperty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.mockito.MockitoAnnotations.initMocks; + +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + +import java.math.BigInteger; +import java.util.stream.IntStream; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.error.MissingFieldException; +import com.hotels.beans.model.FieldMapping; +import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.mixed.MixedToFoo; +import com.hotels.beans.sample.mixed.MixedToFooDiffFields; +import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; +import com.hotels.beans.sample.mixed.MixedToFooMissingField; +import com.hotels.beans.sample.mixed.MixedToFooNotExistingFields; + +/** + * Unit test for all {@link Transformer} functions related to Mixed type Java Beans. + */ +public class MixedObjectTransformationTest extends AbstractTransformerTest { + /** + * The class to be tested. + */ + @InjectMocks + private TransformerImpl underTest; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + } + + /** + * Test that a Mixed bean with a constructor containing the final field only is correctly copied. + */ + @Test + public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { + //GIVEN + + //WHEN + MixedToFooMissingAllArgsConstructor actual = underTest.transform(fromFoo, MixedToFooMissingAllArgsConstructor.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that bean containing both final fields and not are correctly copied. + */ + @Test + public void testMixedBeanIsCorrectlyCopied() { + //GIVEN + + //WHEN + MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that bean containing both final fields (with different names) and not are correctly copied. + */ + @Test + public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { + //GIVEN + + //WHEN + final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); + MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); + + //THEN + assertThat(actual, hasProperty("name", equalTo(actual.getName()))); + assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); + assertEquals(actual.getList(), fromFoo.getList()); + IntStream.range(0, actual.getNestedObjectList().size()) + .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); + assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); + } + + /** + * Test that bean containing both final fields (with different names) and not are correctly copied through field transformer. + */ + @Test + public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTransformer() { + //GIVEN + /* Extended declaration. + * Function idTransformer = value -> value.negate(); + * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", idTransformer); + */ + FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); + + //WHEN + underTest.withFieldMapping(new FieldMapping("id", "identifier")).withFieldTransformer(fieldTransformer); + MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); + + //THEN + assertThat(actual, hasProperty("name", equalTo(actual.getName()))); + assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId().negate()))); + assertEquals(actual.getList(), fromFoo.getList()); + IntStream.range(0, actual.getNestedObjectList().size()) + .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); + assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); + } + + /** + * Test that the copy method sets the default value when the source object does not contain a required field. + */ + @Test + public void testMixedBeanWithMissingFieldsReturnsTheDefaultValueWhenTheSourceObjectDoesNotContainARequiredField() { + //GIVEN + underTest.setDefaultValueForMissingField(true); + + //WHEN + MixedToFooMissingField actual = underTest.transform(fromFoo, MixedToFooMissingField.class); + + assertNull(actual.getFooField()); + underTest.setDefaultValueForMissingField(false); + } + + /** + * Test that the copy method raises an exception when the source object does not contain a required field. + */ + @Test(expected = MissingFieldException.class) + public void testMixedBeanWithMissingFieldsThrowsMissingFieldExceptionWhenTheSourceObjectDoesNotContainARequiredField() { + //GIVEN + underTest.setDefaultValueForMissingField(false); + + //WHEN + underTest.transform(fromFoo, MixedToFooMissingField.class); + } + + /** + * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. + */ + @Test + public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); + + //WHEN + underTest.withFieldTransformer(ageFieldTransformer); + MixedToFooNotExistingFields mixedObjectBean = underTest.transform(fromFooSimple, MixedToFooNotExistingFields.class); + + //THEN + assertThat(mixedObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + } + + /** + * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. + */ + @Test + public void testFieldTransformationSkipWorksProperly() { + //GIVEN + underTest.skipTransformationForField("name", "nestedObject.phoneNumbers"); + + //WHEN + MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); + + //THEN + assertEquals(fromFoo.getId(), actual.getId()); + assertNull(actual.getName()); + assertNull(actual.getNestedObject().getPhoneNumbers()); + underTest.resetFieldsTransformationSkip(); + } +} diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java new file mode 100644 index 000000000..d2f980a70 --- /dev/null +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -0,0 +1,174 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasProperty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.mockito.MockitoAnnotations.initMocks; + +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.FromFooSimpleNoGetters; +import com.hotels.beans.sample.mutable.MutableToFoo; +import com.hotels.beans.sample.mutable.MutableToFooInvalid; +import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; +import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; + +/** + * Unit test for all {@link Transformer} functions related to Mutable type Java Beans. + */ +public class MutableObjectTransformationTest extends AbstractTransformerTest { + /** + * The class to be tested. + */ + @InjectMocks + private TransformerImpl underTest; + + /** + * Initialized mocks. + */ + @Before + public void beforeMethod() { + initMocks(this); + } + + /** + * Test that an exception is thrown if there is no default constructor defined for the mutable bean object. + */ + @Test(expected = InvalidBeanException.class) + public void testTransformThrowsExceptionWhenMutableBeanHasNoDefaultConstructor() { + //GIVEN + + //WHEN + underTest.transform(fromFoo, MutableToFooInvalid.class); + } + + /** + * Test mutable beans are correctly copied. + */ + @Test + public void testMutableBeanIsCorrectlyCopied() { + //GIVEN + + //WHEN + MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + /** + * Test that a given field transformer function is applied only to a specific field even if there are other ones with same name. + */ + @Test + public void testFieldTransformationIsAppliedOnlyToASpecificField() { + //GIVEN + String namePrefix = "prefix-"; + FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", val -> namePrefix + val); + + //WHEN + MutableToFoo actual = underTest + .withFieldTransformer(nameTransformer) + .transform(fromFoo, MutableToFoo.class); + + //THEN + assertEquals(fromFoo.getName(), actual.getName()); + assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); + underTest.resetFieldsTransformer(); + } + + /** + * Test that a given field transformer function is applied to all field matching the given name when {@code flatFieldNameTransformation} is set to true. + */ + @Test + public void testFieldTransformationIsAppliedToAllMatchingFields() { + //GIVEN + String namePrefix = "prefix-"; + FieldTransformer nameTransformer = new FieldTransformer<>("name", val -> namePrefix + val); + + //WHEN + MutableToFoo actual = underTest + .setFlatFieldNameTransformation(true) + .withFieldTransformer(nameTransformer) + .transform(fromFoo, MutableToFoo.class); + + //THEN + assertEquals(namePrefix + fromFoo.getName(), actual.getName()); + assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); + underTest.resetFieldsTransformer(); + } + + /** + * Test that the transformer is able to copy object even if the source object has no setter methods and the destination + * object has no setter methods. + */ + @Test + public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { + //GIVEN + FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, ID); + //WHEN + MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); + + //THEN + assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); + } + + /** + * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. + */ + @Test + public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); + + //WHEN + underTest.withFieldTransformer(ageFieldTransformer); + MutableToFooNotExistingFields mutableObjectBean = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); + + //THEN + assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + } + + /** + * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. + */ + @Test + public void testFieldTransformationSkipWorksProperly() { + //GIVEN + underTest.skipTransformationForField("name", "nestedObject.phoneNumbers"); + + //WHEN + MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); + + //THEN + assertEquals(fromFoo.getId(), actual.getId()); + assertNull(actual.getName()); + assertNull(actual.getNestedObject().getPhoneNumbers()); + underTest.resetFieldsTransformationSkip(); + } +} diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 5de3663f2..b55393378 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -16,117 +16,30 @@ package com.hotels.beans.transformer; -import static java.lang.String.format; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasProperty; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import static org.springframework.test.util.ReflectionTestUtils.setField; - -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; -import static com.hotels.beans.constant.ClassType.IMMUTABLE; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; -import java.util.stream.IntStream; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.mockito.InjectMocks; -import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.error.MissingFieldException; import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooAdvFields; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSimpleNoGetters; -import com.hotels.beans.sample.FromFooSubClass; -import com.hotels.beans.sample.FromFooWithPrimitiveFields; -import com.hotels.beans.sample.FromSubFoo; -import com.hotels.beans.sample.immutable.ImmutableFlatToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; -import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooDiffFields; -import com.hotels.beans.sample.immutable.ImmutableToFooInvalid; -import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooNoConstructors; -import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; -import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; -import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.beans.sample.immutable.ImmutableToFooSimple; -import com.hotels.beans.sample.mixed.MixedToFoo; -import com.hotels.beans.sample.mixed.MixedToFooDiffFields; -import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; -import com.hotels.beans.sample.mixed.MixedToFooMissingField; -import com.hotels.beans.sample.mixed.MixedToFooNotExistingFields; -import com.hotels.beans.sample.mutable.MutableToFoo; -import com.hotels.beans.sample.mutable.MutableToFooInvalid; -import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; -import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; -import com.hotels.beans.sample.mutable.MutableToFooSubClass; import com.hotels.beans.utils.ReflectionUtils; /** - * Unit test for {@link Transformer}. + * Unit test for class: {@link Transformer}. */ -public class TransformerTest { - private static final BigInteger ID = new BigInteger("1234"); - private static final String ITEM_1 = "donald"; - private static final String ITEM_2 = "duck"; - private static final String NAME = "Goofy"; - private static final String SURNAME = "surname"; - private static final int PHONE = 123; - private static final String INDEX_NUMBER = null; - private static final boolean CHECK = true; - private static final BigDecimal AMOUNT = new BigDecimal(10); - private static final String SUB_FOO_NAME = "Smith"; - private static final int[] SUB_FOO_PHONE_NUMBERS = {12345, 6892, 10873}; - private static final Map SUB_FOO_SAMPLE_MAP = new HashMap<>(); - private static final Map> SUB_FOO_COMPLEX_MAP = new HashMap<>(); - private static final Map> SUB_FOO_VERY_COMPLEX_MAP = new HashMap<>(); - private static final int AGE = 34; - private static final int TOTAL_ADV_CLASS_FIELDS = 5; - private static final String AGE_FIELD_NAME = "age"; - private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; - private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; - private static final String GET_SOURCE_FIELD_VALUE_METHOD_NAME = "getSourceFieldValue"; - private static final String DEST_FIELD_NAME = "destFieldName"; - private static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; +public class TransformerTest extends AbstractTransformerTest { + private static final String SOURCE_FIELD_NAME = "sourceFieldName"; + private static final String SOURCE_FIELD_NAME_2 = "sourceFieldName2"; private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; - private static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; + private static final String GET_SOURCE_FIELD_VALUE_METHOD_NAME = "getSourceFieldValue"; private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); - private static FromFoo fromFoo; - private static FromFoo fromFooWithNullProperties; - private static FromFooSimple fromFooSimple; - private static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; - private static List fromSubFooList; - private static List sourceFooSimpleList; - private static FromSubFoo fromSubFoo; - private static FromFooSubClass fromFooSubClass; - private static FromFooAdvFields fromFooAdvFields; /** * The class to be tested. @@ -134,14 +47,6 @@ public class TransformerTest { @InjectMocks private TransformerImpl underTest; - /** - * Initializes the arguments and objects. - */ - @BeforeClass - public static void beforeClass() { - initObjects(); - } - /** * Initialized mocks. */ @@ -151,530 +56,93 @@ public void beforeMethod() { } /** - * Test that is possible to remove all the fields transformer defined. + * Test that is possible to remove a field mapping for a given field. */ @Test - public void testResetFieldsTransformerWorksProperly() { + public void testRemoveFieldMappingWorksProperly() { //GIVEN - Transformer beanTransformer = underTest - .withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val), new FieldTransformer<>(REFLECTION_UTILS_FIELD_NAME, val -> val)); + Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); //WHEN - beanTransformer.resetFieldsTransformer(); + beanTransformer.removeFieldMapping(DEST_FIELD_NAME); TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertTrue(transformerSettings.getFieldsTransformers().isEmpty()); - } - - /** - * Test that immutable beans without constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. - */ - @Test - public void testBeanWithoutCustomAnnotationIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly - * valorized. - */ - @Test - public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected() { - //GIVEN - FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); - - //WHEN - ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFoo, ImmutableFlatToFoo.class); - - //THEN - assertEquals(fromFoo.getName(), actual.getName()); - assertEquals(fromFoo.getId(), actual.getId()); - assertEquals(fromFoo.getNestedObject().getPhoneNumbers(), actual.getPhoneNumbers()); - underTest.resetFieldsMapping(); - } - - /** - * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly - * valorized even if some of them are null. - */ - @Test - public void testTransformationWithCompositeFieldNameWorksEvenWithNullObjects() { - //GIVEN - FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); - - //WHEN - ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFooWithNullProperties, ImmutableFlatToFoo.class); - - //THEN - assertEquals(fromFooWithNullProperties.getName(), actual.getName()); - assertEquals(fromFooWithNullProperties.getId(), actual.getId()); - assertNull(actual.getPhoneNumbers()); - underTest.resetFieldsMapping(); - } - - /** - * Test that immutable beans without custom field mapping. - */ - @Test - public void testBeanWithEmptyFieldMappingIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertFalse(transformerSettings.getFieldsNameMapping().containsKey(DEST_FIELD_NAME)); } /** - * Test that immutable beans without custom field mapping. + * Test that the method {@code removeFieldMapping} raises an {@link IllegalArgumentException} if the parameter is null. */ - @Test - public void testBeanWithEmptyFieldTransformerIsCorrectlyCopied() { + @Test(expected = IllegalArgumentException.class) + public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { //GIVEN + Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); //WHEN - ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); + beanTransformer.removeFieldMapping(null); } /** - * Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. + * Test that is possible to remove all the fields mappings defined. */ @Test - public void testBeanWithCustomAnnotationIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFooCustomAnnotation actual = underTest.transform(fromFoo, ImmutableToFooCustomAnnotation.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test that an exception is thrown if the constructor invocation throws exception. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsException() { - //GIVEN - FromFoo actual = new FromFoo(NAME, ID, null, null, null); - - //WHEN - underTest.transform(actual, ImmutableToFooCustomAnnotation.class); - } - - /** - * Test that an exception is thrown if no constructors are defined. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionWhenParameterAreNull() { - //GIVEN - FromFoo actual = new FromFoo(NAME, ID, null, null, null); - - //WHEN - underTest.transform(actual, ImmutableToFooNoConstructors.class); - } - - /** - * Test that an exception is thrown if there is no default constructor defined for the mutable bean object. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionWhenMutableBeanHasNoDefaultConstructor() { - //GIVEN - - //WHEN - underTest.transform(fromFoo, MutableToFooInvalid.class); - } - - /** - * Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionWhenImmutableBeanHasAWrongConstructor() { - //GIVEN - - //WHEN - underTest.transform(fromFoo, ImmutableToFooInvalid.class); - } - - /** - * Test that an exception is thrown if the destination object don't met the constraints. - */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionIfTheDestinationObjectValuesAreNotValid() { - //GIVEN - fromFoo.setName(null); - - //WHEN - underTest.transform(fromFoo, ImmutableToFoo.class); - - // THEN - fromFoo.setName(NAME); - } - - /** - * Test that no exception is thrown if the destination object don't met the constraints and the validation is disabled. - */ - @Test - public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotValidAndTheValidationIsDisabled() { - //GIVEN - fromFoo.setName(null); - underTest.setValidationDisabled(true); - - //WHEN - ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); - - // THEN - assertThat(actual, sameBeanAs(fromFoo)); - fromFoo.setName(NAME); - underTest.setValidationDisabled(false); - } - - /** - * Test that a Mixed bean with a constructor containing the final field only is correctly copied. - */ - @Test - public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { - //GIVEN - - //WHEN - MixedToFooMissingAllArgsConstructor actual = underTest.transform(fromFoo, MixedToFooMissingAllArgsConstructor.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test mutable beans are correctly copied. - */ - @Test - public void testMutableBeanIsCorrectlyCopied() { - //GIVEN - - //WHEN - MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test that a given field transformer function is applied only to a specific field even if there are other ones with same name. - */ - @Test - public void testFieldTransformationIsAppliedOnlyToASpecificField() { - //GIVEN - String namePrefix = "prefix-"; - FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", val -> namePrefix + val); - - //WHEN - MutableToFoo actual = underTest - .withFieldTransformer(nameTransformer) - .transform(fromFoo, MutableToFoo.class); - - //THEN - assertEquals(fromFoo.getName(), actual.getName()); - assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); - underTest.resetFieldsTransformer(); - } - - /** - * Test that a given field transformer function is applied to all field matching the given name when {@code flatFieldNameTransformation} is set to true. - */ - @Test - public void testFieldTransformationIsAppliedToAllMatchingFields() { - //GIVEN - String namePrefix = "prefix-"; - FieldTransformer nameTransformer = new FieldTransformer<>("name", val -> namePrefix + val); - - //WHEN - MutableToFoo actual = underTest - .setFlatFieldNameTransformation(true) - .withFieldTransformer(nameTransformer) - .transform(fromFoo, MutableToFoo.class); - - //THEN - assertEquals(namePrefix + fromFoo.getName(), actual.getName()); - assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); - underTest.resetFieldsTransformer(); - } - - /** - * Test that bean that extends another class are correctly copied. - */ - @Test - public void testBeanWithoutCustomAnnotationAndWithSuperclassIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFooSubClass actual = underTest.transform(fromFooSubClass, ImmutableToFooSubClass.class); - - //THEN - assertThat(actual, sameBeanAs(fromFooSubClass)); - } - - /** - * Test that bean containing both final fields and not are correctly copied. - */ - @Test - public void testMixedBeanIsCorrectlyCopied() { - //GIVEN - - //WHEN - MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); - } - - /** - * Test that bean containing both final fields (with different names) and not are correctly copied. - */ - @Test - public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { - //GIVEN - - //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); - MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); - - //THEN - assertThat(actual, hasProperty("name", equalTo(actual.getName()))); - assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); - assertEquals(actual.getList(), fromFoo.getList()); - IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); - assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); - } - - /** - * Test that bean containing both final fields (with different names) and not are correctly copied through field transformer. - */ - @Test - public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTransformer() { - //GIVEN - /* Extended declaration. - * Function idTransformer = value -> value.negate(); - * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", idTransformer); - */ - FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); - - //WHEN - underTest.withFieldMapping(new FieldMapping("id", "identifier")).withFieldTransformer(fieldTransformer); - MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); - - //THEN - assertThat(actual, hasProperty("name", equalTo(actual.getName()))); - assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId().negate()))); - assertEquals(actual.getList(), fromFoo.getList()); - IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); - assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); - } - - /** - * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. - */ - @Test - public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { - //GIVEN - FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); - FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); - - //WHEN - underTest.withFieldTransformer(ageFieldTransformer); - MixedToFooNotExistingFields mixedObjectBean = underTest.transform(fromFooSimple, MixedToFooNotExistingFields.class); - ImmutableToFooNotExistingFields immutableObjectBean = underTest.transform(fromFooSimple, ImmutableToFooNotExistingFields.class); - MutableToFooNotExistingFields mutableObjectBean = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); - - //THEN - assertThat(mixedObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); - assertThat(immutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); - assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); - } - - /** - * Test that the copy method sets the default value when the source object does not contain a required field. - */ - @Test - public void testMixedBeanWithMissingFieldsReturnsTheDefaultValueWhenTheSourceObjectDoesNotContainARequiredField() { - //GIVEN - underTest.setDefaultValueForMissingField(true); - - //WHEN - MixedToFooMissingField actual = underTest.transform(fromFoo, MixedToFooMissingField.class); - - assertNull(actual.getFooField()); - underTest.setDefaultValueForMissingField(false); - } - - /** - * Test that the copy method raises an exception when the source object does not contain a required field. - */ - @Test(expected = MissingFieldException.class) - public void testMixedBeanWithMissingFieldsThrowsMissingFieldExceptionWhenTheSourceObjectDoesNotContainARequiredField() { - //GIVEN - underTest.setDefaultValueForMissingField(false); - - //WHEN - underTest.transform(fromFoo, MixedToFooMissingField.class); - } - - /** - * Test that bean containing final fields (with different field names) are correctly copied. - */ - @Test - public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { - //GIVEN - - //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); - ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); - - //THEN - assertThat(actual, hasProperty("name", equalTo(actual.getName()))); - assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); - assertEquals(actual.getList(), fromFoo.getList()); - IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); - assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); - } - - /** - * Test that bean containing advanced final fields are correctly copied. - */ - @Test - public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied() { - //GIVEN - - //WHEN - final Transformer beanTransformer = underTest - .withFieldMapping(new FieldMapping("id", "identifier")) - .withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); - ImmutableToFooAdvFields actual = beanTransformer.transform(fromFooAdvFields, ImmutableToFooAdvFields.class); - - //THEN - assertNotNull(actual.getName()); - assertTrue(actual.getName().isPresent()); - assertEquals(fromFooAdvFields.getName().get(), actual.getName().get()); - assertEquals(fromFooAdvFields.getAge().get(), actual.getAge()); - assertEquals(fromFooAdvFields.getClassType(), actual.getClassType()); - assertEquals(fromFooAdvFields.getLocale(), actual.getLocale().getLanguage()); - } - - /** - * Test that immutable bean containing a constructor with some field not annotated with - * {@link com.hotels.beans.annotation.ConstructorArg} is correctly copied. - */ - @Test - public void testImmutableBeanWithMissingConstructorArgIsCorrectlyCopied() { + public void testResetFieldsMappingWorksProperly() { //GIVEN + Transformer beanTransformer = underTest + .withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME), new FieldMapping(SOURCE_FIELD_NAME_2, DEST_FIELD_NAME)); //WHEN - ImmutableToFooMissingCustomAnnotation actual = underTest.withFieldTransformer().transform(fromFooWithPrimitiveFields, ImmutableToFooMissingCustomAnnotation.class); + beanTransformer.resetFieldsMapping(); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertNotNull(actual); - assertEquals(fromFooWithPrimitiveFields.getName(), actual.getName()); + assertTrue(transformerSettings.getFieldsNameMapping().isEmpty()); } /** - * Test that method: {@code getDestFieldName} retrieves the param name from the {@link ConstructorArg} if it is not provided from jvm directly. + * Test that is possible to remove all the fields transformer defined. */ @Test - public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNotProvidedFromJVM() throws Exception { + public void testResetFieldsTransformerWorksProperly() { //GIVEN - String declaringClassName = ImmutableToFoo.class.getName(); - // Parameter mock setup - Parameter constructorParameter = mock(Parameter.class); - when(constructorParameter.getName()).thenReturn(CONSTRUCTOR_PARAMETER_NAME); - - // CacheManager mock setup - initGetDestFieldNameTestMock(declaringClassName, constructorParameter); - Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); - getDestFieldNameMethod.setAccessible(true); + Transformer beanTransformer = underTest + .withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val), new FieldTransformer<>(REFLECTION_UTILS_FIELD_NAME, val -> val)); //WHEN - String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); + beanTransformer.resetFieldsTransformer(); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertEquals(DEST_FIELD_NAME, actual); - - // restore modified objects - restoreObjects(getDestFieldNameMethod); + assertTrue(transformerSettings.getFieldsTransformers().isEmpty()); } /** - * Test that the method: {@code getConstructorValuesFromFields} works properly. + * Test that is possible to remove a field transformer for a given field. */ @Test - public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { + public void testRemoveFieldTransformerWorksProperly() { //GIVEN - underTest.withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); + Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); //WHEN - final Method getConstructorValuesFromFieldsMethod = - underTest.getClass().getDeclaredMethod(GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME, Object.class, Class.class, String.class); - getConstructorValuesFromFieldsMethod.setAccessible(true); - Object[] actual = (Object[]) getConstructorValuesFromFieldsMethod.invoke(underTest, fromFooAdvFields, ImmutableToFooAdvFields.class, ""); + beanTransformer.removeFieldTransformer(DEST_FIELD_NAME); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertNotNull(actual); - assertEquals(TOTAL_ADV_CLASS_FIELDS, actual.length); - - // restore modified objects - restoreObjects(getConstructorValuesFromFieldsMethod); + assertFalse(transformerSettings.getFieldsTransformers().containsKey(DEST_FIELD_NAME)); } /** - * Test that method: {@code getDestFieldName} returns null if the constructor's parameter name is not provided from jvm directly and the {@link ConstructorArg} is not defined. + * Test that the method {@code removeFieldTransformer} raises an {@link IllegalArgumentException} if the parameter is null. */ - @Test - public void testGetDestFieldNameReturnsNullIfConstructorParamHasNoNameProvidedFromJVMAndNoConstructorArgIsDefined() throws Exception { + @Test(expected = IllegalArgumentException.class) + public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() { //GIVEN - String declaringClassName = ImmutableToFoo.class.getName(); - // Parameter mock setup - Parameter constructorParameter = mock(Parameter.class); - when(constructorParameter.getName()).thenReturn(null); - - // CacheManager mock setup - initGetDestFieldNameTestMock(declaringClassName, constructorParameter); - Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); - getDestFieldNameMethod.setAccessible(true); - - //WHEN - String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); - - //THEN - assertEquals(DEST_FIELD_NAME, actual); - - // restore modified objects - restoreObjects(getDestFieldNameMethod); - } + Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - /** - * Test that the transformer is able to copy object even if the source object has no setter methods and the destination - * object has no setter methods. - */ - @Test - public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { - //GIVEN - FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, ID); //WHEN - MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); - - //THEN - assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); + beanTransformer.removeFieldTransformer(null); } /** @@ -690,135 +158,4 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro getSourceFieldValueMethod.invoke(underTest, null, null, null, false); } - /** - * Test that a meaningful exception is returned when a constructor is invoked with wrong arguments. - */ - @Test - public void testTransformationReturnsAMeaningfulException() { - //GIVEN - Class targetClass = ImmutableToFooSimpleWrongTypes.class; - final String expectedExceptionMessageFormat = - "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " - + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration."; - String targetClassName = targetClass.getCanonicalName(); - String expectedExceptionMessage = - format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getCanonicalName()); - - //WHEN - Exception raisedException = null; - try { - underTest.transform(fromFooSimple, targetClass); - } catch (final Exception e) { - raisedException = e; - } - - //THEN - assertNotNull(raisedException); - assertEquals(InvalidBeanException.class, raisedException.getClass()); - assertEquals(expectedExceptionMessage, raisedException.getMessage()); - } - - /** - * Test transformation on an existing bean is correctly copied. - */ - @Test - public void testTransformationOnAnExistingDestinationWorksProperly() { - //GIVEN - MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); - ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null); - - //WHEN - underTest.transform(fromFooSubClass, mutableToFoo); - underTest.transform(fromFooSimple, immutableToFoo); - - //THEN - assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); - assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); - } - - /** - * Initializes the mocks required for testing method: {@code getDestFieldName}. - * @param declaringClassName the declaring class name - * @param constructorParameter the constructor parameter - */ - private void initGetDestFieldNameTestMock(final String declaringClassName, final Parameter constructorParameter) { - CacheManager cacheManager = mock(CacheManager.class); - String cacheKey = "DestFieldName-" + declaringClassName + "-" + CONSTRUCTOR_PARAMETER_NAME; - when(cacheManager.getFromCache(cacheKey, String.class)).thenReturn(null); - // ConstructorArg mock setup - ConstructorArg constructorArg = mock(ConstructorArg.class); - when(constructorArg.value()).thenReturn(DEST_FIELD_NAME); - // ReflectionUtils mock setup - ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); - when(reflectionUtils.getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)).thenReturn(constructorArg); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); - } - - /** - * Restored the initial object status before testing method: {@code getDestFieldName}. - */ - private void restoreObjects(final Method getDestFieldNameMethod) { - getDestFieldNameMethod.setAccessible(false); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, new ReflectionUtils()); - } - - /** - * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. - */ - private static void initObjects() { - SUB_FOO_SAMPLE_MAP.put(ITEM_1, ITEM_2); - SUB_FOO_COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); - SUB_FOO_VERY_COMPLEX_MAP.put(ITEM_1, SUB_FOO_SAMPLE_MAP); - fromSubFoo = new FromSubFoo(SUB_FOO_NAME, SUB_FOO_PHONE_NUMBERS, SUB_FOO_SAMPLE_MAP, SUB_FOO_COMPLEX_MAP, SUB_FOO_VERY_COMPLEX_MAP); - fromSubFooList = singletonList(fromSubFoo); - sourceFooSimpleList = asList(ITEM_1, ITEM_2); - fromFoo = createFromFoo(fromSubFoo); - fromFooWithNullProperties = createFromFoo(null); - fromFooSimple = createFromFooSimple(); - fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); - fromFooSubClass = createFromFooSubClass(); - fromFooAdvFields = createFromFooAdvFields(); - } - - /** - * Creates a {@link FromFoo} instance. - * @param fromSubFoo the {@link FromSubFoo} instance - * @return the {@link FromFoo} instance. - */ - private static FromFoo createFromFoo(final FromSubFoo fromSubFoo) { - return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); - } - - /** - * Creates a {@link FromFooSimple} instance. - * @return the {@link FromFooSimple} instance. - */ - private static FromFooSimple createFromFooSimple() { - return new FromFooSimple(NAME, ID); - } - - - /** - * Creates a {@link FromFooWithPrimitiveFields} instance. - * @return the {@link FromFooWithPrimitiveFields} instance. - */ - private static FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { - return new FromFooWithPrimitiveFields(NAME, ID.intValue(), AGE, fromSubFooList, sourceFooSimpleList, fromSubFoo); - } - - /** - * Creates a {@link FromFooSubClass} instance. - * @return the {@link FromFooSubClass} instance. - */ - private static FromFooSubClass createFromFooSubClass() { - return new FromFooSubClass(fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObjectList(), fromFoo.getList(), fromFoo.getNestedObject(), SURNAME, PHONE, CHECK, AMOUNT); - } - - /** - * Creates a {@link FromFooAdvFields} instance. - * @return the {@link FromFooAdvFields} instance. - */ - private static FromFooAdvFields createFromFooAdvFields() { - return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage()); - } } diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index a152ac5c7..a287041f0 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -58,7 +58,6 @@ public class ReflectionUtilsTest { private static final String LIST_FIELD_NAME = "list"; private static final String GETTER_METHOD_PREFIX_METHOD_NAME = "getGetterMethodPrefix"; private static final String CHECK_FIELD_NAME = "check"; - private static final String NAME_FIELD = "name"; private static final String EXPECTED_SETTER_METHOD_NAME = "setId"; /** @@ -198,7 +197,7 @@ public void testGetGetterMethodPrefixWorksAsExpected() throws Exception { @Test public void testGetFieldAnnotationWorksProperly() throws NoSuchFieldException { // GIVEN - Field nameField = ImmutableToFoo.class.getDeclaredField(NAME_FIELD); + Field nameField = ImmutableToFoo.class.getDeclaredField(ID_FIELD_NAME); // WHEN final NotNull notNullFieldAnnotation = underTest.getFieldAnnotation(nameField, NotNull.class); From 87914421a1e28de6edb2a753d73f64e49cda7aae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Mar 2019 18:01:21 +0100 Subject: [PATCH 0309/1786] Replaced Junit with TestNG in order to use data providers without creating too much subclasses --- pom.xml | 7 + .../beans/transformer/TransformerImpl.java | 2 +- .../java/com/hotels/beans/BeanUtilsTest.java | 6 +- .../beans/cache/CacheManagerFactoryTest.java | 8 +- .../hotels/beans/cache/CacheManagerTest.java | 10 +- .../beans/performance/PerformanceTest.java | 70 +++---- .../beans/populator/ArrayPopulatorTest.java | 46 ++-- .../beans/populator/PopulatorFactoryTest.java | 46 ++-- .../transformer/AbstractTransformerTest.java | 16 +- .../ImmutableObjectTransformationTest.java | 197 ++++++++---------- .../MixedObjectTransformationTest.java | 8 +- .../MutableObjectTransformationTest.java | 9 +- .../beans/transformer/TransformerTest.java | 12 +- .../hotels/beans/utils/ClassUtilsTest.java | 8 +- .../beans/utils/ReflectionUtilsTest.java | 20 +- .../beans/utils/ValidationUtilsTest.java | 10 +- 16 files changed, 209 insertions(+), 266 deletions(-) diff --git a/pom.xml b/pom.xml index 6aadf0197..d9bc3a7b6 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,7 @@ 3.8.1 0.11 2.8.5 + 6.14.3 2.0.1.Final 6.0.14.Final @@ -127,6 +128,12 @@ ${gson.version} test + + org.testng + testng + ${testng.version} + test + diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 83640c80e..2975584b6 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -112,7 +112,7 @@ private K injectValues(final T sourceObj, final Class targetClass, fin throw new InvalidBeanException("Constructor invoked with arguments. Expected: " + constructor + "; Found: " + getFormattedConstructorArgs(targetClass, constructorArgs) + ". Double check that each " + targetClass.getSimpleName() + "'s field have the same type and name than the source object: " - + sourceObj.getClass().getCanonicalName() + " otherwise specify a transformer configuration.", e); + + sourceObj.getClass().getCanonicalName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(), e); } } diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/src/test/java/com/hotels/beans/BeanUtilsTest.java index 887963a17..020c80ea2 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -29,9 +29,9 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import org.junit.Before; -import org.junit.Test; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.immutable.ImmutableToFooSimple; @@ -53,7 +53,7 @@ public class BeanUtilsTest { /** * Initialized mocks. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java index 707641c0a..bd05d3217 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java @@ -19,9 +19,9 @@ import static org.junit.Assert.assertNotNull; import static org.mockito.MockitoAnnotations.initMocks; -import org.junit.Before; -import org.junit.Test; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; /** * Unit test for class: {@link CacheManagerFactory}. @@ -41,7 +41,7 @@ public class CacheManagerFactoryTest { /** * Initializes mock. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } @@ -49,7 +49,7 @@ public void beforeMethod() { /** * Tests that the method: {@code getCacheManager} returns a {@link CacheManager} instance. */ - @Test(expected = IllegalArgumentException.class) + @Test(expectedExceptions = IllegalArgumentException.class) public void testGetCacheThrowsExceptionIfTheCacheNameIsNull() { // GIVEN diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index d9312cd6a..8bf1859e0 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -23,8 +23,8 @@ import java.util.concurrent.ConcurrentHashMap; -import org.junit.Before; -import org.junit.Test; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; /** * Unit test for {@link CacheManager}. @@ -41,7 +41,7 @@ public class CacheManagerTest { /** * Initializes mock. */ - @Before + @BeforeMethod public void before() { underTest = new CacheManager(new ConcurrentHashMap<>()); } @@ -66,7 +66,7 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { /** * Tests that the method {@code getFromCache} throw exception when the cache key. */ - @Test(expected = IllegalArgumentException.class) + @Test(expectedExceptions = IllegalArgumentException.class) public void testGetFromCacheThrowsExceptionWhenTheCacheKeyIsNull() { // GIVEN @@ -77,7 +77,7 @@ public void testGetFromCacheThrowsExceptionWhenTheCacheKeyIsNull() { /** * Tests that the method {@code getFromCache} throw exception when the cached value class is null. */ - @Test(expected = IllegalArgumentException.class) + @Test(expectedExceptions = IllegalArgumentException.class) public void testGetFromCacheThrowsExceptionWhenTheCachedValueClassIsNull() { // GIVEN diff --git a/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/src/test/java/com/hotels/beans/performance/PerformanceTest.java index 3822a4012..c7087dd57 100644 --- a/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -18,7 +18,6 @@ import static java.lang.String.valueOf; import static java.lang.Thread.sleep; -import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -28,18 +27,17 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.IntStream; import org.apache.commons.lang3.time.StopWatch; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; import com.hotels.beans.BeanUtils; import com.hotels.beans.sample.FromFoo; @@ -58,7 +56,6 @@ * Unit test for {@link BeanUtils}. */ @Slf4j -@RunWith(value = Parameterized.class) public class PerformanceTest { private static final BigInteger ID = new BigInteger("1234"); private static final String ITEM_1 = "donald"; @@ -85,12 +82,6 @@ public class PerformanceTest { private static FromSubFoo fromSubFoo; private static FromFooSubClass fromFooSubClass; - private final double totalTransformation; - private final int waitInterval; - private final Object sourceObject; - private final Class destObjectClass; - private final double maxTransformationTime; - /** * The class to be tested. */ @@ -98,38 +89,35 @@ public class PerformanceTest { private BeanUtils underTest; /** - * All args constructor. - * @param totalTransformation Total transformation to be performed - * @param waitInterval time between one transformation and the other - * @param sourceObject the Source object to copy - * @param destObjectClass the total destination object - * @param maxTransformationTime expected maximum transformation time + * Initialized data provider objects. */ - public PerformanceTest(final double totalTransformation, final int waitInterval, - final Object sourceObject, final Class destObjectClass, final double maxTransformationTime) { - this.totalTransformation = totalTransformation; - this.waitInterval = waitInterval; - this.sourceObject = sourceObject; - this.destObjectClass = destObjectClass; - this.maxTransformationTime = maxTransformationTime; + @BeforeClass + public void beforeClass() { + initObjects(); } /** * Initialized mocks. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); - warmUp(); } /** * Test that the bean copy gets completed by the expected time. + * @param totalTransformation Total transformation to be performed + * @param waitInterval time between one transformation and the other + * @param sourceObject the Source object to copy + * @param destObjectClass the total destination object + * @param maxTransformationTime expected maximum transformation time * @throws InterruptedException */ - @Test - public void testCopyPropertiesGetsCompletedInTheExpectedTime() throws InterruptedException { + @Test(dataProvider = "dataPerformanceTest") + public void testCopyPropertiesGetsCompletedInTheExpectedTime(final double totalTransformation, final int waitInterval, + final Object sourceObject, final Class destObjectClass, final double maxTransformationTime) throws InterruptedException { //GIVEN + warmUp(sourceObject, destObjectClass); //WHEN StopWatch stopWatch = new StopWatch(); @@ -150,15 +138,17 @@ public void testCopyPropertiesGetsCompletedInTheExpectedTime() throws Interrupte /** * Warm up transformation. + * @param sourceObject the Source object to copy + * @param destObjectClass the total destination object */ - private void warmUp() { + private void warmUp(final Object sourceObject, final Class destObjectClass) { underTest.getTransformer().transform(sourceObject, destObjectClass); } /** * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. */ - private static void initObjects() { + private void initObjects() { Map subFooSampleMap = new HashMap<>(); Map> subFooComplexMap = new HashMap<>(); Map> subFooVeryComplexMap = new HashMap<>(); @@ -180,7 +170,7 @@ private static void initObjects() { * Creates a {@link FromFoo} instance. * @return the {@link FromFoo} instance. */ - private static FromFoo createFromFoo() { + private FromFoo createFromFoo() { return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); } @@ -188,7 +178,7 @@ private static FromFoo createFromFoo() { * Creates a {@link FromFooSimple} instance. * @return the {@link FromFooSimple} instance. */ - private static FromFooSimple createFromFooSimple() { + private FromFooSimple createFromFooSimple() { return new FromFooSimple(NAME, ID); } @@ -196,7 +186,7 @@ private static FromFooSimple createFromFooSimple() { * Creates a {@link FromFooSubClass} instance. * @return the {@link FromFooSubClass} instance. */ - private static FromFooSubClass createFromFooSubClass() { + private FromFooSubClass createFromFooSubClass() { return new FromFooSubClass(fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObjectList(), fromFoo.getList(), fromFoo.getNestedObject(), SURNAME, PHONE, CHECK, AMOUNT); } @@ -204,16 +194,14 @@ private static FromFooSubClass createFromFooSubClass() { * Data provider for the required test cases. * @return the test cases. */ - @Parameterized.Parameters(name = "{index}. Number of iterations:{0}, Wait interval: {1}, Expected max transformation time: {2}," - + " Source object:{3}, Destination object: {4}.") - public static Collection dataProvider() { - initObjects(); - return asList(new Object[][]{ + @DataProvider + public Object[][] dataPerformanceTest() { + return new Object[][]{ {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, MutableToFooSimple.class, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, MutableToFooSubClass.class, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSimple, ImmutableToFooSimple.class, SIMPLE_OBJECTS_MAX_TRANSFORMATION_TIME}, {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFooSubClass, ImmutableToFooSubClass.class, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME}, {TOTAL_TRANSFORMATIONS, NO_WAIT_INTERVAL, fromFoo, MixedToFoo.class, COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME} - }); + }; } } diff --git a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 6643a99f8..b991060de 100644 --- a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -16,8 +16,6 @@ package com.hotels.beans.populator; -import static java.util.Arrays.asList; - import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -25,15 +23,13 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import java.util.Collection; import java.util.stream.IntStream; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; import com.hotels.beans.sample.mixed.MixedToFooStaticField; import com.hotels.beans.transformer.Transformer; @@ -41,7 +37,6 @@ /** * Unit test for class: {@link ArrayPopulator}. */ -@RunWith(value = Parameterized.class) public class ArrayPopulatorTest { private static final String VAL_1 = "val1"; private static final String VAL_2 = "val2"; @@ -52,10 +47,6 @@ public class ArrayPopulatorTest { private static final int[] INT_ARRAY = new int[] {ZERO}; private static final MixedToFooStaticField MIXED_TO_FOO_STATIC_FIELDS_OBJECTS = new MixedToFooStaticField(); - private final Class genericFieldType; - private final Class nestedGenericClass; - private final Object array; - @Mock private Transformer transformer; @@ -65,32 +56,23 @@ public class ArrayPopulatorTest { @InjectMocks private ArrayPopulator underTest; - /** - * All args constructor. - * @param genericFieldType the field to be populated class - * @param array the source object from which extract the values - * @param nestedGenericClass the nested generic object class. - */ - public ArrayPopulatorTest(final Class genericFieldType, final Object array, final Class nestedGenericClass) { - this.genericFieldType = genericFieldType; - this.array = array; - this.nestedGenericClass = nestedGenericClass; - MIXED_TO_FOO_STATIC_FIELDS_OBJECTS.setNormalField(VAL_1); - } - /** * Initializes mock. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); + MIXED_TO_FOO_STATIC_FIELDS_OBJECTS.setNormalField(VAL_1); } /** * Tests that the method {@code getPopulatedObject} works as expected. + * @param genericFieldType the field to be populated class + * @param array the source object from which extract the values + * @param nestedGenericClass the nested generic object class. */ - @Test - public void testGetPopulatedObjectWorksProperly() { + @Test(dataProvider = "dataProvider") + public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, final Object array, final Class nestedGenericClass) { // GIVEN when(transformer.transform(any(), eq(MixedToFooStaticField.class))).thenReturn(MIXED_TO_FOO_STATIC_FIELDS_OBJECTS); @@ -116,14 +98,14 @@ public void testGetPopulatedObjectWorksProperly() { * Data provider for the required test cases. * @return the test cases. */ - @Parameterized.Parameters(name = "{index}. Type: {0}, Expected value: {1}.") - public static Collection dataProvider() { - return asList(new Object[][]{ + @DataProvider(parallel = true) + public Object[][] dataProvider() { + return new Object[][]{ {String.class, STRING_ARRAY, null}, {Character.class, CHAR_ARRAY, null}, {Integer.class, INT_ARRAY, null}, {MixedToFooStaticField.class, createMixedToFooArray(), null} - }); + }; } /** diff --git a/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index 79ffcb5c0..f07d7900c 100644 --- a/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -16,23 +16,20 @@ package com.hotels.beans.populator; -import static java.util.Arrays.asList; import static java.util.Objects.nonNull; import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; import com.hotels.beans.sample.FromFoo; import com.hotels.beans.transformer.Transformer; @@ -40,18 +37,7 @@ /** * Unit test for class: {@link PopulatorFactory}. */ -@RunWith(value = Parameterized.class) public class PopulatorFactoryTest { - /** - * The class type. - */ - private final Class type; - - /** - * The expected result. - */ - private final Class expectedResult; - /** * The class to be tested. */ @@ -64,29 +50,21 @@ public class PopulatorFactoryTest { @Mock private Transformer transformer; - /** - * All args constructor. - * @param type the type for wich a populator needs to be found - * @param expectedResult the expected populator - */ - public PopulatorFactoryTest(final Class type, final Class expectedResult) { - this.type = type; - this.expectedResult = expectedResult; - } - /** * Initializes mock. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } /** * Tests that the method: {@code defaultValue} returns the expected result for the given type. + * @param type the type for wich a populator needs to be found + * @param expectedResult the expected populator */ - @Test - public void testGetPopulatorReturnsTheExpectedResult() { + @Test(dataProvider = "dataProvider") + public void testGetPopulatorReturnsTheExpectedResult(final Class type, final Class expectedResult) { // GIVEN // WHEN @@ -104,14 +82,14 @@ public void testGetPopulatorReturnsTheExpectedResult() { * Data provider for the required test cases. * @return the test cases. */ - @Parameterized.Parameters(name = "{index}. Type: {0}, Expected populator: {1}.") - public static Collection dataProvider() { - return asList(new Object[][]{ + @DataProvider(parallel = true) + public Object[][] dataProvider() { + return new Object[][]{ {String[].class, ArrayPopulator.class}, {List.class, CollectionPopulator.class}, {Map.class, MapPopulator.class}, {FromFoo.class, null}, {Optional.class, OptionalPopulator.class} - }); + }; } } diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index bc3887720..4311d520f 100644 --- a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -29,7 +29,7 @@ import java.util.Map; import java.util.Optional; -import org.junit.BeforeClass; +import org.testng.annotations.BeforeClass; import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooAdvFields; @@ -76,14 +76,14 @@ public class AbstractTransformerTest { * Initializes the arguments and objects. */ @BeforeClass - public static void beforeClass() { + public void beforeClass() { initObjects(); } /** * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. */ - private static void initObjects() { + private void initObjects() { SUB_FOO_SAMPLE_MAP.put(ITEM_1, ITEM_2); SUB_FOO_COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); SUB_FOO_VERY_COMPLEX_MAP.put(ITEM_1, SUB_FOO_SAMPLE_MAP); @@ -103,7 +103,7 @@ private static void initObjects() { * @param fromSubFoo the {@link FromSubFoo} instance * @return the {@link FromFoo} instance. */ - private static FromFoo createFromFoo(final FromSubFoo fromSubFoo) { + private FromFoo createFromFoo(final FromSubFoo fromSubFoo) { return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); } @@ -111,7 +111,7 @@ private static FromFoo createFromFoo(final FromSubFoo fromSubFoo) { * Creates a {@link FromFooSimple} instance. * @return the {@link FromFooSimple} instance. */ - private static FromFooSimple createFromFooSimple() { + private FromFooSimple createFromFooSimple() { return new FromFooSimple(NAME, ID); } @@ -120,7 +120,7 @@ private static FromFooSimple createFromFooSimple() { * Creates a {@link FromFooWithPrimitiveFields} instance. * @return the {@link FromFooWithPrimitiveFields} instance. */ - private static FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { + private FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { return new FromFooWithPrimitiveFields(NAME, ID.intValue(), AGE, fromSubFooList, sourceFooSimpleList, fromSubFoo); } @@ -128,7 +128,7 @@ private static FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { * Creates a {@link FromFooSubClass} instance. * @return the {@link FromFooSubClass} instance. */ - private static FromFooSubClass createFromFooSubClass() { + private FromFooSubClass createFromFooSubClass() { return new FromFooSubClass(fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObjectList(), fromFoo.getList(), fromFoo.getNestedObject(), SURNAME, PHONE, CHECK, AMOUNT); } @@ -136,7 +136,7 @@ private static FromFooSubClass createFromFooSubClass() { * Creates a {@link FromFooAdvFields} instance. * @return the {@link FromFooAdvFields} instance. */ - private static FromFooAdvFields createFromFooAdvFields() { + private FromFooAdvFields createFromFooAdvFields() { return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage()); } } diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index ace87d23d..72b316018 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -34,13 +34,16 @@ import java.lang.reflect.Method; import java.lang.reflect.Parameter; +import java.math.BigInteger; import java.util.Locale; import java.util.stream.IntStream; -import org.junit.Before; -import org.junit.Test; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import com.hotels.beans.BeanUtils; import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.cache.CacheManager; import com.hotels.beans.error.InvalidBeanException; @@ -70,6 +73,21 @@ public class ImmutableObjectTransformationTest extends AbstractTransformerTest { private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; + private static final String FIRST_COMPOSITE_TRANSFORMATION_TEST_DESCRIPTION = "Test that, in case a destination object field is contained into a nested object of the source " + + "field, defining a composite FieldMapping the field is correctly valorized."; + private static final String SECOND_COMPOSITE_TRANSFORMATION_TEST_DESCRIPTION = "Test that, in case a destination object field is contained into a nested object of the source " + + "field, defining a composite {@link FieldMapping} the field is correctly valorized even if some of them are null."; + + private static final String FIRST_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION = "Test that immutable beans without constructor arguments parameter annotated with: @ConstructorArg " + + "are correctly copied."; + private static final String SECOND_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION = "Test that immutable beans without custom field mapping are correctly transformed."; + private static final String THIRD_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION = "Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg " + + "are correctly copied."; + private static final String FOURTH_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION = "Test that bean that extends another class are correctly copied"; + + private static final String FIRST_CONSTRUCTOR_EXCEPTION_TEST_DESCRIPTION = "Test that an exception is thrown if the constructor invocation throws exception"; + private static final String SECOND_CONSTRUCTOR_EXCEPTION_TEST_DESCRIPTION = "Test that an exception is thrown if no constructors are defined"; + /** * The class to be tested. */ @@ -79,134 +97,128 @@ public class ImmutableObjectTransformationTest extends AbstractTransformerTest { /** * Initialized mocks. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } /** - * Test that immutable beans without constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. + * Test that default transformation of immutable beans works properly. + * @param testCaseDescription the test case description + * @param transformer the transform to use + * @param sourceObject the object to transform + * @param targetObjectClass the target object class */ - @Test - public void testBeanWithoutCustomAnnotationIsCorrectlyCopied() { + @Test(dataProvider = "dataDefaultTransformationTesting") + public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, final Transformer transformer, final Object sourceObject, + final Class targetObjectClass) { //GIVEN //WHEN - ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); + Object actual = transformer.transform(sourceObject, targetObjectClass); //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertThat(actual, sameBeanAs(sourceObject)); } /** - * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly - * valorized. + * Creates the parameters to be used for testing the default transformation operations. + * @return parameters to be used for testing the default transformation operations. */ - @Test - public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected() { - //GIVEN - FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); - - //WHEN - ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFoo, ImmutableFlatToFoo.class); - - //THEN - assertEquals(fromFoo.getName(), actual.getName()); - assertEquals(fromFoo.getId(), actual.getId()); - assertEquals(fromFoo.getNestedObject().getPhoneNumbers(), actual.getPhoneNumbers()); - underTest.resetFieldsMapping(); + @DataProvider(parallel = true) + private Object[][] dataDefaultTransformationTesting() { + BeanUtils beanUtils = new BeanUtils(); + return new Object[][] { + {FIRST_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION, beanUtils.getTransformer(), fromFoo, ImmutableToFoo.class}, + {SECOND_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION, beanUtils.getTransformer().withFieldMapping(), fromFoo, ImmutableToFoo.class}, + {THIRD_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION, beanUtils.getTransformer(), fromFoo, ImmutableToFooCustomAnnotation.class}, + {FOURTH_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION, beanUtils.getTransformer(), fromFooSubClass, ImmutableToFooSubClass.class}, + }; } /** - * Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping} the field is correctly - * valorized even if some of them are null. - */ - @Test - public void testTransformationWithCompositeFieldNameWorksEvenWithNullObjects() { - //GIVEN - FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); - - //WHEN - ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(fromFooWithNullProperties, ImmutableFlatToFoo.class); - - //THEN - assertEquals(fromFooWithNullProperties.getName(), actual.getName()); - assertEquals(fromFooWithNullProperties.getId(), actual.getId()); - assertNull(actual.getPhoneNumbers()); - underTest.resetFieldsMapping(); - } - - /** - * Test that immutable beans without custom field mapping. + * Test transformation on an existing bean is correctly copied. */ @Test - public void testBeanWithEmptyFieldMappingIsCorrectlyCopied() { + public void testTransformationOnAnExistingDestinationWorksProperly() { //GIVEN + ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null); //WHEN - ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); + underTest.transform(fromFooSimple, immutableToFoo); //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); } /** - * Test that immutable beans without custom field mapping. + * Test transformation field with composite field name mapping. + * @param testCaseDescription the test case description + * @param sourceObject the object to transform + * @param expectedName the expected name + * @param expectedId the expected id + * @param expectedPhoneNumbers the expected phone number */ - @Test - public void testBeanWithEmptyFieldTransformerIsCorrectlyCopied() { + @Test(dataProvider = "dataCompositeFieldNameTesting") + public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(final String testCaseDescription, final Object sourceObject, final String expectedName, + final BigInteger expectedId, final int[] expectedPhoneNumbers) { //GIVEN + FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); //WHEN - ImmutableToFoo actual = underTest.withFieldMapping().transform(fromFoo, ImmutableToFoo.class); + ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(sourceObject, ImmutableFlatToFoo.class); //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertEquals(expectedName, actual.getName()); + assertEquals(expectedId, actual.getId()); + assertEquals(expectedPhoneNumbers, actual.getPhoneNumbers()); + underTest.resetFieldsMapping(); } /** - * Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg {@link com.hotels.beans.annotation.ConstructorArg} are correctly copied. + * Creates the parameters to be used for testing the transformation with composite field name mapping. + * @return parameters to be used for testing the transformation with composite field name mapping. */ - @Test - public void testBeanWithCustomAnnotationIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFooCustomAnnotation actual = underTest.transform(fromFoo, ImmutableToFooCustomAnnotation.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); + @DataProvider(parallel = true) + private Object[][] dataCompositeFieldNameTesting() { + return new Object[][] { + {FIRST_COMPOSITE_TRANSFORMATION_TEST_DESCRIPTION, fromFoo, fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObject().getPhoneNumbers()}, + {SECOND_COMPOSITE_TRANSFORMATION_TEST_DESCRIPTION, fromFooWithNullProperties, fromFooWithNullProperties.getName(), fromFooWithNullProperties.getId(), null} + }; } /** * Test that an exception is thrown if the constructor invocation throws exception. + * @param testCaseDescription the test case description + * @param sourceObject the object to transform + * @param targetObjectClass the target object class */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsException() { + @Test(dataProvider = "dataConstructorErrorTesting", expectedExceptions = InvalidBeanException.class) + public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsException(final String testCaseDescription, final Object sourceObject, + final Class targetObjectClass) { //GIVEN - FromFoo actual = new FromFoo(NAME, ID, null, null, null); //WHEN - underTest.transform(actual, ImmutableToFooCustomAnnotation.class); + underTest.transform(sourceObject, targetObjectClass); } /** - * Test that an exception is thrown if no constructors are defined. + * Creates the parameters to be used for testing the exception raised in case of error during the constructor invocation. + * @return parameters to be used for testing the transformation with composite field name mapping. */ - @Test(expected = InvalidBeanException.class) - public void testTransformThrowsExceptionWhenParameterAreNull() { - //GIVEN + @DataProvider(parallel = true) + private Object[][] dataConstructorErrorTesting() { FromFoo actual = new FromFoo(NAME, ID, null, null, null); - - //WHEN - underTest.transform(actual, ImmutableToFooNoConstructors.class); + return new Object[][] { + {FIRST_CONSTRUCTOR_EXCEPTION_TEST_DESCRIPTION, actual, ImmutableToFooCustomAnnotation.class}, + {SECOND_CONSTRUCTOR_EXCEPTION_TEST_DESCRIPTION, actual, ImmutableToFooNoConstructors.class}, + }; } - /** * Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object. */ - @Test(expected = InvalidBeanException.class) + @Test(expectedExceptions = InvalidBeanException.class) public void testTransformThrowsExceptionWhenImmutableBeanHasAWrongConstructor() { //GIVEN @@ -217,7 +229,7 @@ public void testTransformThrowsExceptionWhenImmutableBeanHasAWrongConstructor() /** * Test that an exception is thrown if the destination object don't met the constraints. */ - @Test(expected = InvalidBeanException.class) + @Test(expectedExceptions = InvalidBeanException.class) public void testTransformThrowsExceptionIfTheDestinationObjectValuesAreNotValid() { //GIVEN fromFoo.setId(null); @@ -247,20 +259,6 @@ public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotVali underTest.setValidationDisabled(false); } - /** - * Test that bean that extends another class are correctly copied. - */ - @Test - public void testBeanWithoutCustomAnnotationAndWithSuperclassIsCorrectlyCopied() { - //GIVEN - - //WHEN - ImmutableToFooSubClass actual = underTest.transform(fromFooSubClass, ImmutableToFooSubClass.class); - - //THEN - assertThat(actual, sameBeanAs(fromFooSubClass)); - } - /** * Test that bean containing final fields (with different field names) are correctly copied. */ @@ -321,6 +319,7 @@ public void testImmutableBeanWithMissingConstructorArgIsCorrectlyCopied() { /** * Test that method: {@code getDestFieldName} retrieves the param name from the {@link ConstructorArg} if it is not provided from jvm directly. + * @throws Exception the thrown exception */ @Test public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNotProvidedFromJVM() throws Exception { @@ -347,6 +346,7 @@ public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNot /** * Test that the method: {@code getConstructorValuesFromFields} works properly. + * @throws Exception the thrown exception */ @Test public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { @@ -369,6 +369,7 @@ public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { /** * Test that method: {@code getDestFieldName} returns null if the constructor's parameter name is not provided from jvm directly and the {@link ConstructorArg} is not defined. + * @throws Exception the thrown exception */ @Test public void testGetDestFieldNameReturnsNullIfConstructorParamHasNoNameProvidedFromJVMAndNoConstructorArgIsDefined() throws Exception { @@ -402,7 +403,8 @@ public void testTransformationReturnsAMeaningfulException() { Class targetClass = ImmutableToFooSimpleWrongTypes.class; final String expectedExceptionMessageFormat = "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " - + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration."; + + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration. " + + "Error message: argument type mismatch"; String targetClassName = targetClass.getCanonicalName(); String expectedExceptionMessage = format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getCanonicalName()); @@ -421,21 +423,6 @@ public void testTransformationReturnsAMeaningfulException() { assertEquals(expectedExceptionMessage, raisedException.getMessage()); } - /** - * Test transformation on an existing bean is correctly copied. - */ - @Test - public void testTransformationOnAnExistingDestinationWorksProperly() { - //GIVEN - ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null); - - //WHEN - underTest.transform(fromFooSimple, immutableToFoo); - - //THEN - assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); - } - /** * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. */ diff --git a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index b8e6f4be6..4a1413a26 100644 --- a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -28,9 +28,9 @@ import java.math.BigInteger; import java.util.stream.IntStream; -import org.junit.Before; -import org.junit.Test; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; import com.hotels.beans.error.MissingFieldException; import com.hotels.beans.model.FieldMapping; @@ -55,7 +55,7 @@ public class MixedObjectTransformationTest extends AbstractTransformerTest { /** * Initialized mocks. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } @@ -151,7 +151,7 @@ public void testMixedBeanWithMissingFieldsReturnsTheDefaultValueWhenTheSourceObj /** * Test that the copy method raises an exception when the source object does not contain a required field. */ - @Test(expected = MissingFieldException.class) + @Test(expectedExceptions = MissingFieldException.class) public void testMixedBeanWithMissingFieldsThrowsMissingFieldExceptionWhenTheSourceObjectDoesNotContainARequiredField() { //GIVEN underTest.setDefaultValueForMissingField(false); diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index c3acd3967..ab8f1f2f1 100644 --- a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -25,9 +25,9 @@ import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; -import org.junit.Before; -import org.junit.Test; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.model.FieldTransformer; @@ -52,7 +52,7 @@ public class MutableObjectTransformationTest extends AbstractTransformerTest { /** * Initialized mocks. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } @@ -60,7 +60,7 @@ public void beforeMethod() { /** * Test that an exception is thrown if there is no default constructor defined for the mutable bean object. */ - @Test(expected = InvalidBeanException.class) + @Test(expectedExceptions = InvalidBeanException.class) public void testTransformThrowsExceptionWhenMutableBeanHasNoDefaultConstructor() { //GIVEN @@ -131,6 +131,7 @@ public void testFieldTransformationIsAppliedToAllMatchingFields() { public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { //GIVEN FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, ID); + //WHEN MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index b55393378..5e8725596 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -23,9 +23,9 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; -import org.junit.Before; -import org.junit.Test; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; @@ -50,7 +50,7 @@ public class TransformerTest extends AbstractTransformerTest { /** * Initialized mocks. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } @@ -74,7 +74,7 @@ public void testRemoveFieldMappingWorksProperly() { /** * Test that the method {@code removeFieldMapping} raises an {@link IllegalArgumentException} if the parameter is null. */ - @Test(expected = IllegalArgumentException.class) + @Test(expectedExceptions = IllegalArgumentException.class) public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { //GIVEN Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); @@ -136,7 +136,7 @@ public void testRemoveFieldTransformerWorksProperly() { /** * Test that the method {@code removeFieldTransformer} raises an {@link IllegalArgumentException} if the parameter is null. */ - @Test(expected = IllegalArgumentException.class) + @Test(expectedExceptions = IllegalArgumentException.class) public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() { //GIVEN Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); @@ -148,7 +148,7 @@ public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() /** * Test that the method: {@code getSourceFieldValue} raises a {@link NullPointerException} in case any of the parameters null. */ - @Test(expected = Exception.class) + @Test(expectedExceptions = Exception.class) public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() throws Exception { //GIVEN Method getSourceFieldValueMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_VALUE_METHOD_NAME, Object.class, String.class, Field.class, boolean.class); diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 33d36a482..3065fb0bf 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -35,9 +35,9 @@ import javax.validation.constraints.NotNull; -import org.junit.Before; -import org.junit.Test; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.constant.ClassType; @@ -93,7 +93,7 @@ public class ClassUtilsTest { /** * Initializes mock. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } @@ -302,7 +302,7 @@ public void testGetAllArgsConstructorWorksAsExpected() { /** * Tests that the method {@code getAllArgsConstructor} throws exception if the class has no all args constructor. */ - @Test(expected = InvalidBeanException.class) + @Test(expectedExceptions = InvalidBeanException.class) public void testGetAllArgsConstructorThrowsExceptionIfTheConstructorIsMissing() { // GIVEN diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index a287041f0..dce395c15 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -39,9 +39,9 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import org.junit.Before; -import org.junit.Test; +import org.testng.annotations.Test; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; import com.hotels.beans.error.MissingMethodException; import com.hotels.beans.error.MissingFieldException; @@ -69,7 +69,7 @@ public class ReflectionUtilsTest { /** * Initializes mock. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } @@ -96,7 +96,7 @@ public void testGetFieldValueWorksAsExpected() throws NoSuchFieldException { /** * Tests that the method {@code getFieldValue} throws Exception if the field does not exists. */ - @Test(expected = MissingFieldException.class) + @Test(expectedExceptions = MissingFieldException.class) public void testGetFieldValueThrowsExceptionIfTheFieldDoesNotExists() { // GIVEN MutableToFoo mutableToFoo = new MutableToFoo(); @@ -112,7 +112,7 @@ public void testGetFieldValueThrowsExceptionIfTheFieldDoesNotExists() { /** * Tests that the method {@code handleReflectionException} raises the expected exception. */ - @Test(expected = IllegalStateException.class) + @Test(expectedExceptions = IllegalStateException.class) public void testHandleReflectionExceptionThrowsIllegalStateExceptionWhenGivenExceptionIsNoSuchMethodException() { // GIVEN NoSuchMethodException noSuchMethodException = new NoSuchMethodException(); @@ -124,7 +124,7 @@ public void testHandleReflectionExceptionThrowsIllegalStateExceptionWhenGivenExc /** * Tests that the method {@code handleReflectionException} raises the expected exception. */ - @Test(expected = IllegalStateException.class) + @Test(expectedExceptions = IllegalStateException.class) public void testHandleReflectionExceptionThrowsIllegalStateExceptionWhenGivenExceptionIsIllegalAccessException() { // GIVEN IllegalAccessException illegalAccessException = new IllegalAccessException(); @@ -136,7 +136,7 @@ public void testHandleReflectionExceptionThrowsIllegalStateExceptionWhenGivenExc /** * Tests that the method {@code handleReflectionException} raises the expected exception. */ - @Test(expected = RuntimeException.class) + @Test(expectedExceptions = RuntimeException.class) public void testHandleReflectionExceptionThrowsRuntimeExceptionWhenGivenExceptionIsRuntimeException() { // GIVEN RuntimeException runtimeException = new RuntimeException(); @@ -148,7 +148,7 @@ public void testHandleReflectionExceptionThrowsRuntimeExceptionWhenGivenExceptio /** * Tests that the method {@code handleReflectionException} raises the expected exception. */ - @Test(expected = UndeclaredThrowableException.class) + @Test(expectedExceptions = UndeclaredThrowableException.class) public void testHandleReflectionExceptionThrowsUndeclaredThrowableExceptionWhenGivenExceptionIsInvalidBeanException() { // GIVEN Exception exception = new Exception(); @@ -160,7 +160,7 @@ public void testHandleReflectionExceptionThrowsUndeclaredThrowableExceptionWhenG /** * Tests that the method {@code getMapGenericType} throws Exception when the given type is not a map. */ - @Test(expected = IllegalArgumentException.class) + @Test(expectedExceptions = IllegalArgumentException.class) public void testGetMapGenericTypeThrowsIllegalArgumentExceptionWhenTheGivenTypeIsNotAMap() { // GIVEN @@ -226,7 +226,7 @@ public void testGetSetterMethodForFieldWorksProperly() { /** * Tests that the method {@code getSetterMethodForField} raises a MissingMethodException if the setter method for the given field does not exists. */ - @Test(expected = MissingMethodException.class) + @Test(expectedExceptions = MissingMethodException.class) public void testGetSetterMethodForFieldThrowsExceptionIfTheMethodDoesNotExists() { // GIVEN diff --git a/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java index ad0e90f68..ddb0a551d 100644 --- a/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java @@ -18,9 +18,9 @@ import static org.mockito.MockitoAnnotations.initMocks; -import org.junit.Before; -import org.junit.Test; import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; /** * Unit test for {@link ValidationUtils}. @@ -45,7 +45,7 @@ public class ValidationUtilsTest { /** * Initialized mocks. */ - @Before + @BeforeMethod public void beforeMethod() { initMocks(this); } @@ -53,7 +53,7 @@ public void beforeMethod() { /** * Test that an exception is thrown when the given parameter is null. */ - @Test(expected = IllegalArgumentException.class) + @Test(expectedExceptions = IllegalArgumentException.class) public void testNotNullRaisesAnExceptionWhenTheGivenObjectIsNull() { //GIVEN @@ -75,7 +75,7 @@ public void testThatNoExceptionAreThrownWhenTheGivenObjectIsNotNull() { /** * Test that an exception is thrown when the given parameter is null. */ - @Test(expected = IllegalArgumentException.class) + @Test(expectedExceptions = IllegalArgumentException.class) public void testNotNullRaisesAnExceptionWhenTheGivenObjectIsNullEvenWithoutACustomMessage() { //GIVEN From 49197625e83350c41b450a7b7f461a2d2616c481 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Mar 2019 21:00:24 +0100 Subject: [PATCH 0310/1786] Enabled parallel test execution --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d9bc3a7b6..bfa4c173b 100644 --- a/pom.xml +++ b/pom.xml @@ -280,7 +280,7 @@ maven-surefire-plugin ${maven.surefire.plugin.version} - false + true From d2698d16dd2d7f4166c48b3bf17e25fedececab1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Mar 2019 07:28:09 +0100 Subject: [PATCH 0311/1786] Started adding data provider to ClassUtils Test class --- pom.xml | 2 +- .../beans/populator/ArrayPopulatorTest.java | 3 +-- .../beans/populator/PopulatorFactoryTest.java | 2 +- .../ImmutableObjectTransformationTest.java | 6 ++--- .../hotels/beans/utils/ClassUtilsTest.java | 26 ++++++++++++++----- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index bfa4c173b..d9bc3a7b6 100644 --- a/pom.xml +++ b/pom.xml @@ -280,7 +280,7 @@ maven-surefire-plugin ${maven.surefire.plugin.version} - true + false diff --git a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index b991060de..cc62631ab 100644 --- a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -98,7 +98,7 @@ public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, * Data provider for the required test cases. * @return the test cases. */ - @DataProvider(parallel = true) + @DataProvider public Object[][] dataProvider() { return new Object[][]{ {String.class, STRING_ARRAY, null}, @@ -114,6 +114,5 @@ public Object[][] dataProvider() { */ private static MixedToFooStaticField[] createMixedToFooArray() { return new MixedToFooStaticField[] {MIXED_TO_FOO_STATIC_FIELDS_OBJECTS}; - } } diff --git a/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index f07d7900c..5fd1ef31b 100644 --- a/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -82,7 +82,7 @@ public void testGetPopulatorReturnsTheExpectedResult(final Class type, final Cla * Data provider for the required test cases. * @return the test cases. */ - @DataProvider(parallel = true) + @DataProvider public Object[][] dataProvider() { return new Object[][]{ {String[].class, ArrayPopulator.class}, diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 72b316018..5f5abbea8 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -125,7 +125,7 @@ public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, * Creates the parameters to be used for testing the default transformation operations. * @return parameters to be used for testing the default transformation operations. */ - @DataProvider(parallel = true) + @DataProvider private Object[][] dataDefaultTransformationTesting() { BeanUtils beanUtils = new BeanUtils(); return new Object[][] { @@ -179,7 +179,7 @@ public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(f * Creates the parameters to be used for testing the transformation with composite field name mapping. * @return parameters to be used for testing the transformation with composite field name mapping. */ - @DataProvider(parallel = true) + @DataProvider private Object[][] dataCompositeFieldNameTesting() { return new Object[][] { {FIRST_COMPOSITE_TRANSFORMATION_TEST_DESCRIPTION, fromFoo, fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObject().getPhoneNumbers()}, @@ -206,7 +206,7 @@ public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsExceptio * Creates the parameters to be used for testing the exception raised in case of error during the constructor invocation. * @return parameters to be used for testing the transformation with composite field name mapping. */ - @DataProvider(parallel = true) + @DataProvider private Object[][] dataConstructorErrorTesting() { FromFoo actual = new FromFoo(NAME, ID, null, null, null); return new Object[][] { diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 3065fb0bf..ea4d498db 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -37,6 +37,7 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.hotels.beans.annotation.ConstructorArg; @@ -100,18 +101,31 @@ public void beforeMethod() { /** * Tests that the method {@code isPrimitiveType} returns the expected value. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result */ - @Test - public void testIsPrimitiveTypeWorksAsExpected() { + @Test(dataProvider = "dataIsPrimitiveTypeObjectTesting") + public void testIsPrimitiveTypeWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { // GIVEN // WHEN - boolean actualPrimitiveClass = underTest.isPrimitiveType(PRIMITIVE_CLASS); - boolean actualNotPrimitiveClass = underTest.isPrimitiveType(NOT_PRIMITIVE_CLASS); + boolean actual = underTest.isPrimitiveType(testClass); // THEN - assertTrue(actualPrimitiveClass); - assertFalse(actualNotPrimitiveClass); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code isPrimitiveType}. + * @return parameters to be used for testing the the method {@code isPrimitiveType}. + */ + @DataProvider + private Object[][] dataIsPrimitiveTypeObjectTesting() { + return new Object[][] { + {"Tests that the method returns true if the class is a primitive type object", BigDecimal.class, true}, + {"Tests that the method returns false if the class is not a primitive type object", FromFoo.class, false} + }; } /** From c6864530431bc35756d20ccbbf1fcd5e23e56a63 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Mar 2019 14:49:51 +0100 Subject: [PATCH 0312/1786] Continuing data provider implementation on ClassUtils test class --- .../hotels/beans/utils/ClassUtilsTest.java | 227 +++++++++++------- 1 file changed, 146 insertions(+), 81 deletions(-) diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index ea4d498db..0feb7b451 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -57,8 +57,6 @@ * Unit test for {@link ClassUtils}. */ public class ClassUtilsTest { - private static final Class PRIMITIVE_CLASS = BigDecimal.class; - private static final Class NOT_PRIMITIVE_CLASS = FromFoo.class; private static final Class CLASS_WITHOUT_PRIVATE_FINAL_FIELDS = MutableToFoo.class; private static final Class CLASS_WITH_PRIVATE_FINAL_FIELDS = ImmutableToFoo.class; private static final int EXPECTED_PRIVATE_FINAL_FIELDS = 5; @@ -84,6 +82,7 @@ public class ClassUtilsTest { private static final double[] PRIMITIVE_DOUBLE_ARRAY = {}; private static final float[] PRIMITIVE_FLOAT_ARRAY = {}; private static final long[] PRIMITIVE_LONG_ARRAY = {}; + private static final FromFoo[] NOT_PRIMITIVE_ARRAY = {}; /** * The class to be tested. @@ -130,158 +129,224 @@ private Object[][] dataIsPrimitiveTypeObjectTesting() { /** * Tests that the method {@code isSpecialType} returns the expected value. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result */ - @Test - public void testIsSpecialTypeWorksAsExpected() { + @Test(dataProvider = "dataSpecialTypeObjectTesting") + public void testIsSpecialTypeWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { // GIVEN // WHEN - boolean actualSpecialClass = underTest.isSpecialType(Locale.class); - boolean actualNotSpecialClass = underTest.isSpecialType(PRIMITIVE_CLASS); + boolean actual = underTest.isSpecialType(testClass); // THEN - assertTrue(actualSpecialClass); - assertFalse(actualNotSpecialClass); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code isSpecialType}. + * @return parameters to be used for testing the the method {@code isSpecialType}. + */ + @DataProvider + private Object[][] dataSpecialTypeObjectTesting() { + return new Object[][] { + {"Tests that the method returns true if the class is a special type object", Locale.class, true}, + {"Tests that the method returns false if the class is not a special type object", BigDecimal.class, false} + }; } /** * Tests that the method {@code isPrimitiveOrSpecialType} returns the expected value. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result */ - @Test - public void testIsPrimitiveOrSpecialTypeWorksAsExpected() { + @Test(dataProvider = "dataPrimitiveOrSpecialTypeObjectTesting") + public void testIsPrimitiveOrSpecialTypeWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { // GIVEN // WHEN - boolean actualPrimitiveOrSpecialClass = underTest.isPrimitiveOrSpecialType(Locale.class); - boolean actualPrimitiveOrSpecialClass2 = underTest.isPrimitiveOrSpecialType(BigDecimal.class); - boolean actualNotPrimitiveOrSpecialClass = underTest.isPrimitiveOrSpecialType(NOT_PRIMITIVE_CLASS); + boolean actual = underTest.isPrimitiveOrSpecialType(testClass); // THEN - assertTrue(actualPrimitiveOrSpecialClass); - assertTrue(actualPrimitiveOrSpecialClass2); - assertFalse(actualNotPrimitiveOrSpecialClass); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code isPrimitiveOrSpecialType}. + * @return parameters to be used for testing the the method {@code isPrimitiveOrSpecialType}. + */ + @DataProvider + private Object[][] dataPrimitiveOrSpecialTypeObjectTesting() { + return new Object[][] { + {"Tests that the method returns true if the class is a primitive or special type object", Locale.class, true}, + {"Tests that the method returns false if the class is a primitive nor a special type object", BigDecimal.class, true}, + {"Tests that the method returns false if the class is not a primitive nor a special type object", FromFoo.class, false} + }; } /** * Tests that the method {@code isPrimitiveArrayType} returns the expected value. + * @param testCaseDescription the test case description + * @param testArray the array to test + * @param expectedResult the expected result */ - @Test - public void testIsPrimitiveArrayTypeWorksAsExpected() { + @Test(dataProvider = "dataPrimitiveArrayTypeTesting") + public void testIsPrimitiveArrayTypeWorksAsExpected(final String testCaseDescription, final Object testArray, final boolean expectedResult) { // GIVEN // WHEN - boolean actualPrimitiveIntArrayClass = underTest.isPrimitiveTypeArray(PRIMITIVE_INT_ARRAY); - boolean actualPrimitiveShortArrayClass = underTest.isPrimitiveTypeArray(PRIMITIVE_SHORT_ARRAY); - boolean actualPrimitiveCharArrayClass = underTest.isPrimitiveTypeArray(PRIMITIVE_CHAR_ARRAY); - boolean actualPrimitiveByteArrayClass = underTest.isPrimitiveTypeArray(PRIMITIVE_BYTE_ARRAY); - boolean actualPrimitiveDoubleArrayClass = underTest.isPrimitiveTypeArray(PRIMITIVE_DOUBLE_ARRAY); - boolean actualPrimitiveFloatArrayClass = underTest.isPrimitiveTypeArray(PRIMITIVE_FLOAT_ARRAY); - boolean actualPrimitiveLongArrayClass = underTest.isPrimitiveTypeArray(PRIMITIVE_LONG_ARRAY); + boolean actual = underTest.isPrimitiveTypeArray(testArray); // THEN - assertTrue(actualPrimitiveIntArrayClass); - assertTrue(actualPrimitiveShortArrayClass); - assertTrue(actualPrimitiveCharArrayClass); - assertTrue(actualPrimitiveByteArrayClass); - assertTrue(actualPrimitiveDoubleArrayClass); - assertTrue(actualPrimitiveFloatArrayClass); - assertTrue(actualPrimitiveLongArrayClass); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code isPrimitiveArrayType}. + * @return parameters to be used for testing the the method {@code isPrimitiveArrayType}. + */ + @DataProvider + private Object[][] dataPrimitiveArrayTypeTesting() { + return new Object[][] { + {"Tests that the method returns true if the array is of type int[]", PRIMITIVE_INT_ARRAY, true}, + {"Tests that the method returns true if the array is of type short[]", PRIMITIVE_SHORT_ARRAY, true}, + {"Tests that the method returns true if the array is of type char[]", PRIMITIVE_CHAR_ARRAY, true}, + {"Tests that the method returns true if the array is of type byte[]", PRIMITIVE_BYTE_ARRAY, true}, + {"Tests that the method returns true if the array is of type double[]", PRIMITIVE_DOUBLE_ARRAY, true}, + {"Tests that the method returns true if the array is of type float[]", PRIMITIVE_FLOAT_ARRAY, true}, + {"Tests that the method returns true if the array is of type long[]", PRIMITIVE_LONG_ARRAY, true}, + {"Tests that the method returns false if the array is of type FromFoo[]", NOT_PRIMITIVE_ARRAY, false} + }; } /** * Tests that the method {@code getPrivateFinalFields} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result */ - @Test - public void testGetPrivateFinalFieldsWorksAsExpected() { + @Test(dataProvider = "dataGetPrivateFinalFieldsTesting") + public void testGetPrivateFinalFieldsWorksAsExpected(final String testCaseDescription, final Class testClass, final int expectedResult) { // GIVEN // WHEN - List mutableClassPrivateFinalFields = underTest.getPrivateFinalFields(CLASS_WITHOUT_PRIVATE_FINAL_FIELDS); - List immutableClassPrivateFinalFields = underTest.getPrivateFinalFields(CLASS_WITH_PRIVATE_FINAL_FIELDS); + List actual = underTest.getPrivateFinalFields(testClass); // THEN - assertTrue(mutableClassPrivateFinalFields.isEmpty()); - assertEquals(EXPECTED_PRIVATE_FINAL_FIELDS, immutableClassPrivateFinalFields.size()); + assertEquals(expectedResult, actual.size()); + } + + /** + * Creates the parameters to be used for testing the method {@code getPrivateFinalFields}. + * @return parameters to be used for testing the the method {@code getPrivateFinalFields}. + */ + @DataProvider + private Object[][] dataGetPrivateFinalFieldsTesting() { + return new Object[][] { + {"Tests that the method returns 0 if the given class has no private final fields", CLASS_WITHOUT_PRIVATE_FINAL_FIELDS, ZERO}, + {"Tests that the method returns the expected value if the class has private final fields", CLASS_WITH_PRIVATE_FINAL_FIELDS, EXPECTED_PRIVATE_FINAL_FIELDS} + }; } /** * Tests that the method {@code getTotalFields} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param fieldPredicate the predicate to apply + * @param expectedResult the expected result */ - @Test - public void testGetTotalFieldsWorksAsExpected() { + @Test(dataProvider = "dataGetTotalFieldsTesting") + public void testGetTotalFieldsWorksAsExpected(final String testCaseDescription, final Class testClass, final Predicate fieldPredicate, final int expectedResult) { // GIVEN // WHEN - long mutableClassTotPrivateFinalFields = underTest.getTotalFields(CLASS_WITHOUT_PRIVATE_FINAL_FIELDS, IS_FINAL_FIELD_PREDICATE); - long immutableClassPrivateFinalFields = underTest.getTotalFields(CLASS_WITH_PRIVATE_FINAL_FIELDS, IS_FINAL_FIELD_PREDICATE); + long actual = underTest.getTotalFields(testClass, fieldPredicate); // THEN - assertEquals(ZERO, mutableClassTotPrivateFinalFields); - assertEquals(EXPECTED_PRIVATE_FINAL_FIELDS, immutableClassPrivateFinalFields); + assertEquals(expectedResult, actual); } /** - * Tests that the method {@code getPrivateFields} works as expected. + * Creates the parameters to be used for testing the method {@code getTotalFields}. + * @return parameters to be used for testing the the method {@code getTotalFields}. */ - @Test - public void testGetPrivateFieldsWorksAsExpected() { - // GIVEN - - // WHEN - List mixedToFooPrivateFields = underTest.getPrivateFields(CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS); - List immutableClassPrivateFields = underTest.getPrivateFields(CLASS_WITH_PRIVATE_FINAL_FIELDS); - - // THEN - assertEquals(EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS, mixedToFooPrivateFields.size()); - assertEquals(EXPECTED_PRIVATE_FINAL_FIELDS, immutableClassPrivateFields.size()); + @DataProvider + private Object[][] dataGetTotalFieldsTesting() { + return new Object[][] { + {"Tests that the method returns 0 if the given class has no private final fields", CLASS_WITHOUT_PRIVATE_FINAL_FIELDS, IS_FINAL_FIELD_PREDICATE, ZERO}, + {"Tests that the method returns the expected value if the class has private final fields", CLASS_WITH_PRIVATE_FINAL_FIELDS, IS_FINAL_FIELD_PREDICATE, + EXPECTED_PRIVATE_FINAL_FIELDS} + }; } /** - * Tests that the method {@code getPrivateFields} works as expected with sub classes. + * Tests that the method {@code getPrivateFields} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param skipFinal if true the final fields are skipped + * @param expectedResult the expected result */ - @Test - public void testGetPrivateFieldsWorksAsExpectedOnSubLasses() { + @Test(dataProvider = "dataGetPrivateFieldsTesting") + public void testGetPrivateFieldsWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean skipFinal, final int expectedResult) { // GIVEN // WHEN - List immutableClassPrivateFinalFields = underTest.getPrivateFields(ImmutableToFooSubClass.class); + List actual = underTest.getPrivateFields(testClass, skipFinal); // THEN - assertEquals(EXPECTED_SUB_CLASS_PRIVATE_FIELDS, immutableClassPrivateFinalFields.size()); + assertEquals(expectedResult, actual.size()); } - /** - * Tests that the method {@code getPrivateFields} with the skipFinal option one works as expected. + * Creates the parameters to be used for testing the method {@code getPrivateFields}. + * @return parameters to be used for testing the the method {@code getPrivateFields}. */ - @Test - public void testGetPrivateFieldsSkippingFinalWorksAsExpected() { - // GIVEN - - // WHEN - List mixedToFooPrivateFieldsNotFinal = underTest.getPrivateFields(CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, true); - List immutableClassPrivateOrFinalFields = underTest.getPrivateFields(CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, false); - - // THEN - assertEquals(EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_NOT_FINAL_FIELDS, mixedToFooPrivateFieldsNotFinal.size()); - assertEquals(EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS, immutableClassPrivateOrFinalFields.size()); + @DataProvider + private Object[][] dataGetPrivateFieldsTesting() { + return new Object[][] { + {"Tests that the method returns the expected value if the class has private and public fields", CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, false, + EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS}, + {"Tests that the method returns the expected value if the class has private final fields only", CLASS_WITH_PRIVATE_FINAL_FIELDS, false, + EXPECTED_PRIVATE_FINAL_FIELDS}, + {"Tests that the method returns the expected value if the class extends another class", ImmutableToFooSubClass.class, false, + EXPECTED_SUB_CLASS_PRIVATE_FIELDS}, + {"Tests that the method returns the expected value if the skipFinal is enabled", CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, true, + EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_NOT_FINAL_FIELDS} + }; } /** * Tests that the method {@code getDeclaredFields} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param skipStatic if true the static fields are skipped + * @param expectedResult the expected result */ - @Test - public void testGetDeclaredFieldsWorksAsExpected() { + @Test(dataProvider = "dataGetDeclaredFieldsTesting") + public void testGetDeclaredFieldsWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean skipStatic, final int expectedResult) { // GIVEN - final int totalClassFields = CLASS_WITH_STATIC_FIELDS.getDeclaredFields().length; // WHEN - List notStaticFields = underTest.getDeclaredFields(CLASS_WITH_STATIC_FIELDS, true); - List allFields = underTest.getDeclaredFields(CLASS_WITH_STATIC_FIELDS, false); + List actual = underTest.getDeclaredFields(testClass, skipStatic); // THEN - assertEquals(EXPECTED_NOT_STATIC_FIELDS, notStaticFields.size()); - assertEquals(totalClassFields, allFields.size()); + assertEquals(expectedResult, actual.size()); + } + + /** + * Creates the parameters to be used for testing the method {@code getDeclaredFields}. + * @return parameters to be used for testing the the method {@code getDeclaredFields}. + */ + @DataProvider + private Object[][] dataGetDeclaredFieldsTesting() { + return new Object[][] { + {"Tests that the method returns the expected total number of fields when the skipStatic param is true", CLASS_WITH_STATIC_FIELDS, true, + EXPECTED_NOT_STATIC_FIELDS}, + {"Tests that the method returns the expected value if the class has private final fields only", CLASS_WITH_STATIC_FIELDS, false, + CLASS_WITH_STATIC_FIELDS.getDeclaredFields().length}, + }; } /** From f68787783ba66f8112aa7f093b8b4d1e67e63f51 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 14 Mar 2019 14:07:49 +0100 Subject: [PATCH 0313/1786] Finalized class utils data provider testing --- .../hotels/beans/utils/ClassUtilsTest.java | 243 +++++++++++++----- 1 file changed, 178 insertions(+), 65 deletions(-) diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 0feb7b451..e442aac74 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -19,11 +19,10 @@ import static java.lang.reflect.Modifier.isFinal; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; +import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -345,7 +344,7 @@ private Object[][] dataGetDeclaredFieldsTesting() { {"Tests that the method returns the expected total number of fields when the skipStatic param is true", CLASS_WITH_STATIC_FIELDS, true, EXPECTED_NOT_STATIC_FIELDS}, {"Tests that the method returns the expected value if the class has private final fields only", CLASS_WITH_STATIC_FIELDS, false, - CLASS_WITH_STATIC_FIELDS.getDeclaredFields().length}, + CLASS_WITH_STATIC_FIELDS.getDeclaredFields().length} }; } @@ -407,123 +406,212 @@ public void testGetConstructorParameters() { /** * Tests that the method {@code hasField} works as expected. + * @param testCaseDescription the test case description + * @param fieldName the field's name to retrieve + * @param expectedResult the expected result */ - @Test - public void testHasFieldWorksAsExpected() { + @Test(dataProvider = "dataHasFieldTesting") + public void testHasFieldWorksAsExpected(final String testCaseDescription, final String fieldName, final boolean expectedResult) { // GIVEN final ImmutableToFooSubClass immutableToFooSubClass = new ImmutableToFooSubClass(null, null, null, null, null, null, 0, false, null); // WHEN - boolean classContainsNotExistingField = underTest.hasField(immutableToFooSubClass, NOT_EXISTING_FIELD_NAME); - boolean classContainsExistingField = underTest.hasField(immutableToFooSubClass, NAME); + boolean actual = underTest.hasField(immutableToFooSubClass, fieldName); // THEN - assertFalse(classContainsNotExistingField); - assertTrue(classContainsExistingField); + assertEquals(expectedResult, actual); } /** - * Tests that the method {@code hasSetterMethods} works as expected. + * Creates the parameters to be used for testing the method {@code hasField}. + * @return parameters to be used for testing the the method {@code hasField}. */ - @Test - public void testHasSetterMethodsWorksAsExpected() { + @DataProvider + private Object[][] dataHasFieldTesting() { + return new Object[][] { + {"Tests that the method returns false if the given field does not exists", NOT_EXISTING_FIELD_NAME, false}, + {"Tests that the method returns true if the given field exists", NAME, true} + }; + } + + /** + * Tests that the method {@code hasFinalFields} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataHasFinalFieldTesting") + public void testHasPrivateFinalFieldsWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { // GIVEN // WHEN - boolean mixedFooStaticFieldHasSetterMethods = underTest.hasSetterMethods(CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS); - boolean immutableClassHasSetterMethods = underTest.hasSetterMethods(CLASS_WITH_PRIVATE_FINAL_FIELDS); + boolean actual = underTest.hasFinalFields(testClass); // THEN - assertTrue(mixedFooStaticFieldHasSetterMethods); - assertFalse(immutableClassHasSetterMethods); + assertEquals(expectedResult, actual); } /** - * Tests that the method {@code hasFinalFields} works as expected. + * Creates the parameters to be used for testing the method {@code hasFinalFields}. + * @return parameters to be used for testing the the method {@code hasFinalFields}. */ - @Test - public void testHasPrivateFinalFieldsWorksAsExpected() { - // GIVEN + @DataProvider + private Object[][] dataHasFinalFieldTesting() { + return new Object[][] { + {"Tests that the method returns true if the given class has private final fields", CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS, true}, + {"Tests that the method returns true if the given class has no private final fields", CLASS_WITHOUT_PRIVATE_FINAL_FIELDS, false} + }; + } + /** + * Tests that the method {@code hasSetterMethods} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataHasSetterMethodsTesting") + public void testHasSetterMethodsWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { + // GIVEN // WHEN - boolean immutableClassHasPrivateFinalFields = underTest.hasFinalFields(CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS); - boolean mutableClassHasPrivateFinalFields = underTest.hasFinalFields(CLASS_WITHOUT_PRIVATE_FINAL_FIELDS); + boolean actual = underTest.hasSetterMethods(testClass); // THEN - assertTrue(immutableClassHasPrivateFinalFields); - assertFalse(mutableClassHasPrivateFinalFields); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code hasSetterMethods}. + * @return parameters to be used for testing the the method {@code hasSetterMethods}. + */ + @DataProvider + private Object[][] dataHasSetterMethodsTesting() { + return new Object[][] { + {"Tests that the method returns true if the given class has private final fields", CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, true}, + {"Tests that the method returns true if the given class has no private final fields", CLASS_WITH_PRIVATE_FINAL_FIELDS, false}, + }; } /** * Tests that the method {@code containsAnnotation} works as expected. + * @param testCaseDescription the test case description + * @param annotationClass the annotation to search + * @param expectedResult the expected result */ - @Test - public void testContainsAnnotationWorksAsExpected() { + @Test(dataProvider = "dataContainsAnnotationTesting") + public void testContainsAnnotationWorksAsExpected(final String testCaseDescription, final Class annotationClass, final boolean expectedResult) { // GIVEN Constructor constructor = ImmutableToFooCustomAnnotation.class.getConstructors()[0]; // WHEN - boolean containsExistingAnnotation = underTest.containsAnnotation(constructor, ConstructorArg.class); - boolean containsNotExistingAnnotation = underTest.containsAnnotation(constructor, NotNull.class); + boolean actual = underTest.containsAnnotation(constructor, annotationClass); // THEN - assertTrue(containsExistingAnnotation); - assertFalse(containsNotExistingAnnotation); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code containsAnnotation}. + * @return parameters to be used for testing the the method {@code containsAnnotation}. + */ + @DataProvider + private Object[][] dataContainsAnnotationTesting() { + return new Object[][] { + {"Tests that the method returns true if the constructor contains parameters annotated with @ConstructorArg", ConstructorArg.class, true}, + {"Tests that the method returns false if the constructor does not contain parameters annotated with @NotNull", NotNull.class, false}, + }; } /** * Tests that the method {@code notAllParameterAnnotatedWith} works as expected. + * @param testCaseDescription the test case description + * @param annotationClass the annotation to search + * @param expectedResult the expected result */ - @Test - public void testAllParameterAnnotatedWithWorksAsExpected() { + @Test(dataProvider = "dataNotAllParameterAnnotatedWithTesting") + public void testAllParameterAnnotatedWithWorksAsExpected(final String testCaseDescription, final Class annotationClass, final boolean expectedResult) { // GIVEN Constructor constructor = ImmutableToFooCustomAnnotation.class.getConstructors()[0]; // WHEN - boolean allParamContainsExistingAnnotation = underTest.allParameterAnnotatedWith(constructor, ConstructorArg.class); - boolean allParamContainsNotExistingAnnotation = underTest.allParameterAnnotatedWith(constructor, NotNull.class); + boolean actual = underTest.allParameterAnnotatedWith(constructor, annotationClass); // THEN - assertTrue(allParamContainsExistingAnnotation); - assertFalse(allParamContainsNotExistingAnnotation); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code notAllParameterAnnotatedWith}. + * @return parameters to be used for testing the the method {@code notAllParameterAnnotatedWith}. + */ + @DataProvider + private Object[][] dataNotAllParameterAnnotatedWithTesting() { + return new Object[][] { + {"Tests that the method returns true if all constructor's parameter are annotated with @ConstructorArg", ConstructorArg.class, true}, + {"Tests that the method returns false if not all constructor's parameter are annotated with @NotNull", NotNull.class, false}, + }; } /** * Tests that the method {@code getClassType} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result */ - @Test - public void testGetClassTypeWorksAsExpected() { + @Test(dataProvider = "dataGetClassTypeTesting") + public void testGetClassTypeWorksAsExpected(final String testCaseDescription, final Class testClass, final ClassType expectedResult) { // GIVEN // WHEN - final ClassType immutableToFooClassType = underTest.getClassType(ImmutableToFoo.class); - final ClassType mutableToFooClassType = underTest.getClassType(MutableToFoo.class); - final ClassType mixedToFooClassType = underTest.getClassType(MixedToFoo.class); + final ClassType actual = underTest.getClassType(testClass); // THEN - assertEquals(ClassType.IMMUTABLE, immutableToFooClassType); - assertEquals(ClassType.MUTABLE, mutableToFooClassType); - assertEquals(ClassType.MIXED, mixedToFooClassType); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code getClassType}. + * @return parameters to be used for testing the the method {@code getClassType}. + */ + @DataProvider + private Object[][] dataGetClassTypeTesting() { + return new Object[][] { + {"Tests that the method returns immutable if the given class is immutable", ImmutableToFoo.class, ClassType.IMMUTABLE}, + {"Tests that the method returns mutable if the given class is mutable", MutableToFoo.class, ClassType.MUTABLE}, + {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED} + }; } /** * Tests that the method {@code getSetterMethods} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result */ - @Test - public void testGetSetterMethodsWorksAsExpected() { + @Test(dataProvider = "dataGetSetterMethodsTesting") + public void testGetSetterMethodsWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { // GIVEN // WHEN - final List immutableClassSetterMethods = underTest.getSetterMethods(ImmutableToFooSubClass.class); - final List mutableClassSetterMethods = underTest.getSetterMethods(MutableToFoo.class); + final List actual = underTest.getSetterMethods(testClass); // THEN - assertTrue(immutableClassSetterMethods.isEmpty()); - assertFalse(mutableClassSetterMethods.isEmpty()); + assertEquals(expectedResult, actual.isEmpty()); + } + + /** + * Creates the parameters to be used for testing the method {@code getSetterMethods}. + * @return parameters to be used for testing the the method {@code getSetterMethods}. + */ + @DataProvider + private Object[][] dataGetSetterMethodsTesting() { + return new Object[][] { + {"Tests that the method returns an empty list if the class has no setter methods", ImmutableToFooSubClass.class, true}, + {"Tests that the method returns a not empty list if the class has setter methods", MutableToFoo.class, false} + }; } /** @@ -541,36 +629,61 @@ public void testGetDefaultTypeValueWorksAsExpected() { } /** - * Tests that the method {@code getDefaultTypeValue} works as expected. + * Tests that the method {@code usesBuilderPattern} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result */ - @Test - public void testUsesBuilderPatternWorksAsExpected() { + @Test(dataProvider = "dataUsesBuilderPatternTesting") + public void testUsesBuilderPatternWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { // GIVEN - final Constructor constructorWithBuilder = underTest.getAllArgsConstructor(FromFooWithBuilder.class); - final Constructor constructorWithoutBuilder = underTest.getAllArgsConstructor(FromFoo.class); + final Constructor constructor = underTest.getAllArgsConstructor(testClass); // WHEN - final boolean usesBuilderPattern = underTest.usesBuilderPattern(constructorWithBuilder, FromFooWithBuilder.class); - final boolean notUseBuilderPattern = underTest.usesBuilderPattern(constructorWithoutBuilder, FromFoo.class); + final boolean usesBuilderPattern = underTest.usesBuilderPattern(constructor, testClass); // THEN - assertTrue(usesBuilderPattern); - assertFalse(notUseBuilderPattern); + assertEquals(expectedResult, usesBuilderPattern); + } + + /** + * Creates the parameters to be used for testing the method {@code usesBuilderPattern}. + * @return parameters to be used for testing the the method {@code usesBuilderPattern}. + */ + @DataProvider + private Object[][] dataUsesBuilderPatternTesting() { + return new Object[][] { + {"Tests that the method returns true if the class has a builder", FromFooWithBuilder.class, true}, + {"Tests that the method returns false if the class hasn't a builder", FromFoo.class, false} + }; } /** * Tests that the method {@code hasAccessibleConstructors} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result */ - @Test - public void testHasAccessibleConstructorsWorksAsExpected() { + @Test(dataProvider = "dataHasAccessibleConstructorsTesting") + public void testHasAccessibleConstructorsWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { // GIVEN // WHEN - final boolean notAccessibleConstructors = underTest.hasAccessibleConstructors(FromFooWithBuilder.class); - final boolean accessibleConstructors = underTest.hasAccessibleConstructors(FromFoo.class); + final boolean actual = underTest.hasAccessibleConstructors(testClass); // THEN - assertFalse(notAccessibleConstructors); - assertTrue(accessibleConstructors); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code hasAccessibleConstructors}. + * @return parameters to be used for testing the the method {@code hasAccessibleConstructors}. + */ + @DataProvider + private Object[][] dataHasAccessibleConstructorsTesting() { + return new Object[][] { + {"Tests that the method returns false if the constructor is private", FromFooWithBuilder.class, false}, + {"Tests that the method returns false if the constructor is public", FromFoo.class, true} + }; } } From 7b775d7c006f897370243a3dec1a78ae80d12797 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 15 Mar 2019 18:08:45 +0100 Subject: [PATCH 0314/1786] - Fixed typo in java comment - Modified getFieldValue method implementation - Made class abstract --- .../com/hotels/beans/transformer/AbstractTransformer.java | 2 +- .../java/com/hotels/beans/transformer/TransformerImpl.java | 4 ++-- .../com/hotels/beans/transformer/AbstractTransformerTest.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 6f7dda121..d1169ad2a 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -40,7 +40,7 @@ abstract class AbstractTransformer implements Transformer { final ReflectionUtils reflectionUtils; /** - * Class uttils instance {@link ClassUtils}. + * Class utils instance {@link ClassUtils}. */ final ClassUtils classUtils; diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 2975584b6..c184a135e 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -307,10 +307,10 @@ private Object getFieldValue(final T sourceObj, final Class targetClas */ private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); - boolean primitiveType = classUtils.isPrimitiveType(field.getType()); if (!isAFieldToTransform(fieldBreadcrumb)) { - return !primitiveType ? null : defaultValue(field.getType()); + return defaultValue(field.getType()); } + boolean primitiveType = classUtils.isPrimitiveType(field.getType()); boolean isFieldTransformerDefined = settings.getFieldsTransformers().containsKey(field.getName()); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); if (nonNull(fieldValue)) { diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index 4311d520f..af0a24b8e 100644 --- a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -41,7 +41,7 @@ /** * Unit test for {@link Transformer}. */ -public class AbstractTransformerTest { +public abstract class AbstractTransformerTest { protected static final BigInteger ID = new BigInteger("1234"); protected static final String NAME = "Goofy"; protected static FromFoo fromFoo; From 3bbe146d350522f8aa954a93d7f24f4afc24aad7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 17 Mar 2019 15:37:49 +0100 Subject: [PATCH 0315/1786] - Finalized feature that allow to skip the validation on some given fields - Used data provider on all test classes --- .../com/hotels/beans/constant/Filters.java | 20 +++--- .../transformer/AbstractTransformer.java | 7 +- .../beans/transformer/TransformerImpl.java | 6 +- .../transformer/TransformerSettings.java | 4 +- .../com/hotels/beans/utils/ClassUtils.java | 2 +- .../hotels/beans/utils/ReflectionUtils.java | 2 +- .../hotels/beans/cache/CacheManagerTest.java | 2 +- .../transformer/AbstractTransformerTest.java | 38 ++++++----- .../ImmutableObjectTransformationTest.java | 47 ++++++------- .../MixedObjectTransformationTest.java | 16 ++--- .../MutableObjectTransformationTest.java | 34 +++++----- .../hotels/beans/utils/ClassUtilsTest.java | 11 ++- .../beans/utils/ReflectionUtilsTest.java | 67 +++++++++++++------ .../beans/utils/ValidationUtilsTest.java | 62 +++++++++++------ 14 files changed, 186 insertions(+), 132 deletions(-) diff --git a/src/main/java/com/hotels/beans/constant/Filters.java b/src/main/java/com/hotels/beans/constant/Filters.java index 86067c567..b1d1de247 100644 --- a/src/main/java/com/hotels/beans/constant/Filters.java +++ b/src/main/java/com/hotels/beans/constant/Filters.java @@ -31,16 +31,6 @@ */ @NoArgsConstructor(access = PRIVATE) public final class Filters { - /** - * Returns only the final field. - */ - public static final Predicate IS_FINAL_FIELD = field -> isFinal(field.getModifiers()); - - /** - * Returns only the not final field. - */ - public static final Predicate IS_NOT_FINAL_FIELD = IS_FINAL_FIELD.negate(); - /** * Returns only the final not static field. */ @@ -57,4 +47,14 @@ public final class Filters { return !isFinal(modifiers) && !isStatic(modifiers); }; + /** + * Returns only the final field. + */ + private static final Predicate IS_FINAL_FIELD = field -> isFinal(field.getModifiers()); + + /** + * Returns only the not final field. + */ + public static final Predicate IS_NOT_FINAL_FIELD = IS_FINAL_FIELD.negate(); + } diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index d1169ad2a..6d2dd619c 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -16,6 +16,8 @@ package com.hotels.beans.transformer; +import static java.util.Arrays.asList; + import static com.hotels.beans.utils.ValidationUtils.notNull; import java.util.Map; @@ -192,10 +194,7 @@ public final void transform(final T sourceObj, final K targetObject) { */ @Override public Transformer skipTransformationForField(final String... fieldName) { - final Map fieldsToSkip = settings.getFieldsToSkip(); - for (String tmpField: fieldName) { - fieldsToSkip.put(tmpField, tmpField); - } + settings.getFieldsToSkip().addAll(asList(fieldName)); return this; } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index c184a135e..11f02f0db 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -182,8 +182,8 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< * @param breadcrumb the field path * @return true if the transformation has to be applied on this field, false in it has to be skipped. */ - private boolean isAFieldToTransform(final String breadcrumb) { - return isNull(breadcrumb) || !settings.getFieldsToSkip().containsKey(breadcrumb); + private boolean doSkipTransformation(final String breadcrumb) { + return settings.getFieldsToSkip().contains(breadcrumb); } /** @@ -307,7 +307,7 @@ private Object getFieldValue(final T sourceObj, final Class targetClas */ private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); - if (!isAFieldToTransform(fieldBreadcrumb)) { + if (doSkipTransformation(fieldBreadcrumb)) { return defaultValue(field.getType()); } boolean primitiveType = classUtils.isPrimitiveType(field.getType()); diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index a270861a3..6aaf7c82d 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -16,7 +16,9 @@ package com.hotels.beans.transformer; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; @@ -50,7 +52,7 @@ final class TransformerSettings { /** * Contains the list of fields that don't need to be transformed. */ - private final Map fieldsToSkip = new ConcurrentHashMap<>(); + private final Set fieldsToSkip = new HashSet<>(); /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 4fdb73f00..b1ac4ff42 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -516,7 +516,7 @@ public boolean hasFinalFields(final Class clazz) { * @param clazz class from which gets the field * @return true if it has private final field, false otherwise. */ - public boolean hasNotFinalFields(final Class clazz) { + private boolean hasNotFinalFields(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); return hasFieldsMatchingCondition(clazz, IS_NOT_FINAL_AND_NOT_STATIC_FIELD, "HasNotFinalNotStaticFields-"); } diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index f27136f6c..50d7e9499 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -314,7 +314,7 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f * @return true id is accessible, false otherwise */ private boolean isFieldAccessible(final Field field, final Object target) { - return field.isAccessible(); + return field.canAccess(target); } /** diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index 8bf1859e0..193536d37 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -95,9 +95,9 @@ public void testRemoveFromCacheRemovesTheObject() { // WHEN underTest.removeFromCache(CACHE_KEY); + Object actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - Object actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); assertNull(actual); } } diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index af0a24b8e..25695b384 100644 --- a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -42,22 +42,25 @@ * Unit test for {@link Transformer}. */ public abstract class AbstractTransformerTest { - protected static final BigInteger ID = new BigInteger("1234"); - protected static final String NAME = "Goofy"; - protected static FromFoo fromFoo; - protected static FromFoo fromFooWithNullProperties; - protected static FromFooSimple fromFooSimple; - protected static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; - protected static List fromSubFooList; - protected static List sourceFooSimpleList; - protected static FromSubFoo fromSubFoo; - protected static FromFooSubClass fromFooSubClass; - protected static FromFooAdvFields fromFooAdvFields; - protected static final int AGE = 34; - protected static final String AGE_FIELD_NAME = "age"; - protected static final String DEST_FIELD_NAME = "destFieldName"; - protected static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; - protected static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; + static final BigInteger ID = new BigInteger("1234"); + static final String NAME = "Goofy"; + static FromFoo fromFoo; + static FromFoo fromFooWithNullProperties; + static FromFooSimple fromFooSimple; + static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; + static FromFooSubClass fromFooSubClass; + static FromFooAdvFields fromFooAdvFields; + static final int AGE = 34; + static final String AGE_FIELD_NAME = "age"; + static final String DEST_FIELD_NAME = "destFieldName"; + static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; + static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; + static final String ID_FIELD_NAME = "id"; + static final String IDENTIFIER_FIELD_NAME = "identifier"; + static final String LOCALE_FIELD_NAME = "locale"; + static final String PHONE_NUMBER_DEST_FIELD_NAME = "phoneNumbers"; + static final String PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME = "nestedObject.phoneNumbers"; + static final String NAME_FIELD_NAME = "name"; private static final String ITEM_1 = "donald"; private static final String ITEM_2 = "duck"; @@ -71,6 +74,9 @@ public abstract class AbstractTransformerTest { private static final Map SUB_FOO_SAMPLE_MAP = new HashMap<>(); private static final Map> SUB_FOO_COMPLEX_MAP = new HashMap<>(); private static final Map> SUB_FOO_VERY_COMPLEX_MAP = new HashMap<>(); + private static List fromSubFooList; + private static List sourceFooSimpleList; + private static FromSubFoo fromSubFoo; /** * Initializes the arguments and objects. diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 5f5abbea8..2de7cde54 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -73,21 +73,6 @@ public class ImmutableObjectTransformationTest extends AbstractTransformerTest { private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; - private static final String FIRST_COMPOSITE_TRANSFORMATION_TEST_DESCRIPTION = "Test that, in case a destination object field is contained into a nested object of the source " - + "field, defining a composite FieldMapping the field is correctly valorized."; - private static final String SECOND_COMPOSITE_TRANSFORMATION_TEST_DESCRIPTION = "Test that, in case a destination object field is contained into a nested object of the source " - + "field, defining a composite {@link FieldMapping} the field is correctly valorized even if some of them are null."; - - private static final String FIRST_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION = "Test that immutable beans without constructor arguments parameter annotated with: @ConstructorArg " - + "are correctly copied."; - private static final String SECOND_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION = "Test that immutable beans without custom field mapping are correctly transformed."; - private static final String THIRD_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION = "Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg " - + "are correctly copied."; - private static final String FOURTH_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION = "Test that bean that extends another class are correctly copied"; - - private static final String FIRST_CONSTRUCTOR_EXCEPTION_TEST_DESCRIPTION = "Test that an exception is thrown if the constructor invocation throws exception"; - private static final String SECOND_CONSTRUCTOR_EXCEPTION_TEST_DESCRIPTION = "Test that an exception is thrown if no constructors are defined"; - /** * The class to be tested. */ @@ -129,10 +114,13 @@ public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, private Object[][] dataDefaultTransformationTesting() { BeanUtils beanUtils = new BeanUtils(); return new Object[][] { - {FIRST_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION, beanUtils.getTransformer(), fromFoo, ImmutableToFoo.class}, - {SECOND_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION, beanUtils.getTransformer().withFieldMapping(), fromFoo, ImmutableToFoo.class}, - {THIRD_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION, beanUtils.getTransformer(), fromFoo, ImmutableToFooCustomAnnotation.class}, - {FOURTH_DEFAULT_TRANSFORMATION_TEST_DESCRIPTION, beanUtils.getTransformer(), fromFooSubClass, ImmutableToFooSubClass.class}, + {"Test that immutable beans without constructor arguments parameter annotated with: @ConstructorArg are correctly copied.", + beanUtils.getTransformer(), fromFoo, ImmutableToFoo.class}, + {"Test that immutable beans without custom field mapping are correctly transformed.", + beanUtils.getTransformer().withFieldMapping(), fromFoo, ImmutableToFoo.class}, + {"Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg are correctly copied.", + beanUtils.getTransformer(), fromFoo, ImmutableToFooCustomAnnotation.class}, + {"Test that bean that extends another class are correctly copied", beanUtils.getTransformer(), fromFooSubClass, ImmutableToFooSubClass.class}, }; } @@ -163,7 +151,7 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(final String testCaseDescription, final Object sourceObject, final String expectedName, final BigInteger expectedId, final int[] expectedPhoneNumbers) { //GIVEN - FieldMapping phoneNumbersMapping = new FieldMapping("nestedObject.phoneNumbers", "phoneNumbers"); + FieldMapping phoneNumbersMapping = new FieldMapping(PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME, PHONE_NUMBER_DEST_FIELD_NAME); //WHEN ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(sourceObject, ImmutableFlatToFoo.class); @@ -182,8 +170,11 @@ public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(f @DataProvider private Object[][] dataCompositeFieldNameTesting() { return new Object[][] { - {FIRST_COMPOSITE_TRANSFORMATION_TEST_DESCRIPTION, fromFoo, fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObject().getPhoneNumbers()}, - {SECOND_COMPOSITE_TRANSFORMATION_TEST_DESCRIPTION, fromFooWithNullProperties, fromFooWithNullProperties.getName(), fromFooWithNullProperties.getId(), null} + {"Test that, in case a destination object field is contained into a nested object of the source field, defining a composite FieldMapping" + + "the field is correctly valorized.", fromFoo, fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObject().getPhoneNumbers()}, + {"Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping}" + + " the field is correctly valorized even if some of them are null.", fromFooWithNullProperties, fromFooWithNullProperties.getName(), + fromFooWithNullProperties.getId(), null} }; } @@ -210,8 +201,8 @@ public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsExceptio private Object[][] dataConstructorErrorTesting() { FromFoo actual = new FromFoo(NAME, ID, null, null, null); return new Object[][] { - {FIRST_CONSTRUCTOR_EXCEPTION_TEST_DESCRIPTION, actual, ImmutableToFooCustomAnnotation.class}, - {SECOND_CONSTRUCTOR_EXCEPTION_TEST_DESCRIPTION, actual, ImmutableToFooNoConstructors.class}, + {"Test that an exception is thrown if the constructor invocation throws exception", actual, ImmutableToFooCustomAnnotation.class}, + {"Test that an exception is thrown if no constructors are defined", actual, ImmutableToFooNoConstructors.class}, }; } @@ -267,7 +258,7 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); + final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); //THEN @@ -288,8 +279,8 @@ public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied() { //WHEN final Transformer beanTransformer = underTest - .withFieldMapping(new FieldMapping("id", "identifier")) - .withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); + .withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)) + .withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); ImmutableToFooAdvFields actual = beanTransformer.transform(fromFooAdvFields, ImmutableToFooAdvFields.class); //THEN @@ -351,7 +342,7 @@ public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNot @Test public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { //GIVEN - underTest.withFieldTransformer(new FieldTransformer<>("locale", Locale::forLanguageTag)); + underTest.withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); //WHEN final Method getConstructorValuesFromFieldsMethod = diff --git a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 4a1413a26..03b8f0da4 100644 --- a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -96,12 +96,12 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping("id", "identifier")); + final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); //THEN - assertThat(actual, hasProperty("name", equalTo(actual.getName()))); - assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); + assertThat(actual, hasProperty(NAME_FIELD_NAME, equalTo(actual.getName()))); + assertThat(actual, hasProperty(IDENTIFIER_FIELD_NAME, equalTo(fromFoo.getId()))); assertEquals(actual.getList(), fromFoo.getList()); IntStream.range(0, actual.getNestedObjectList().size()) .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); @@ -118,15 +118,15 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTra * Function idTransformer = value -> value.negate(); * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", idTransformer); */ - FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); + FieldTransformer fieldTransformer = new FieldTransformer<>(IDENTIFIER_FIELD_NAME, BigInteger::negate); //WHEN - underTest.withFieldMapping(new FieldMapping("id", "identifier")).withFieldTransformer(fieldTransformer); + underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)).withFieldTransformer(fieldTransformer); MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); //THEN - assertThat(actual, hasProperty("name", equalTo(actual.getName()))); - assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId().negate()))); + assertThat(actual, hasProperty(NAME_FIELD_NAME, equalTo(actual.getName()))); + assertThat(actual, hasProperty(IDENTIFIER_FIELD_NAME, equalTo(fromFoo.getId().negate()))); assertEquals(actual.getList(), fromFoo.getList()); IntStream.range(0, actual.getNestedObjectList().size()) .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); @@ -183,7 +183,7 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor @Test public void testFieldTransformationSkipWorksProperly() { //GIVEN - underTest.skipTransformationForField("name", "nestedObject.phoneNumbers"); + underTest.skipTransformationForField(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); //WHEN MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index ab8f1f2f1..f5008da5d 100644 --- a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -82,6 +82,21 @@ public void testMutableBeanIsCorrectlyCopied() { assertThat(actual, sameBeanAs(fromFoo)); } + /** + * Test transformation on an existing bean is correctly copied. + */ + @Test + public void testTransformationOnAnExistingDestinationWorksProperly() { + //GIVEN + MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); + + //WHEN + underTest.transform(fromFooSubClass, mutableToFoo); + + //THEN + assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); + } + /** * Test that a given field transformer function is applied only to a specific field even if there are other ones with same name. */ @@ -109,7 +124,7 @@ public void testFieldTransformationIsAppliedOnlyToASpecificField() { public void testFieldTransformationIsAppliedToAllMatchingFields() { //GIVEN String namePrefix = "prefix-"; - FieldTransformer nameTransformer = new FieldTransformer<>("name", val -> namePrefix + val); + FieldTransformer nameTransformer = new FieldTransformer<>(NAME_FIELD_NAME, val -> namePrefix + val); //WHEN MutableToFoo actual = underTest @@ -162,7 +177,7 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor @Test public void testFieldTransformationSkipWorksProperly() { //GIVEN - underTest.skipTransformationForField("name", "nestedObject.phoneNumbers"); + underTest.skipTransformationForField(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); //WHEN MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); @@ -173,19 +188,4 @@ public void testFieldTransformationSkipWorksProperly() { assertNull(actual.getNestedObject().getPhoneNumbers()); underTest.resetFieldsTransformationSkip(); } - - /** - * Test transformation on an existing bean is correctly copied. - */ - @Test - public void testTransformationOnAnExistingDestinationWorksProperly() { - //GIVEN - MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); - - //WHEN - underTest.transform(fromFooSubClass, mutableToFoo); - - //THEN - assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); - } } diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index e442aac74..3ca8694ae 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -17,6 +17,7 @@ package com.hotels.beans.utils; import static java.lang.reflect.Modifier.isFinal; +import static java.util.Objects.nonNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -288,11 +289,11 @@ private Object[][] dataGetTotalFieldsTesting() { * @param expectedResult the expected result */ @Test(dataProvider = "dataGetPrivateFieldsTesting") - public void testGetPrivateFieldsWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean skipFinal, final int expectedResult) { + public void testGetPrivateFieldsWorksAsExpected(final String testCaseDescription, final Class testClass, final Boolean skipFinal, final int expectedResult) { // GIVEN // WHEN - List actual = underTest.getPrivateFields(testClass, skipFinal); + List actual = nonNull(skipFinal) ? underTest.getPrivateFields(testClass, skipFinal) : underTest.getPrivateFields(testClass); // THEN assertEquals(expectedResult, actual.size()); @@ -307,10 +308,16 @@ private Object[][] dataGetPrivateFieldsTesting() { return new Object[][] { {"Tests that the method returns the expected value if the class has private and public fields", CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, false, EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS}, + {"Tests that the method returns the expected value if the class has private and public fields and skipFinal is not passed as param", + CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, null, EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS}, {"Tests that the method returns the expected value if the class has private final fields only", CLASS_WITH_PRIVATE_FINAL_FIELDS, false, EXPECTED_PRIVATE_FINAL_FIELDS}, + {"Tests that the method returns the expected value if the class has private final fields only and skipFinal is not passed as param", + CLASS_WITH_PRIVATE_FINAL_FIELDS, null, EXPECTED_PRIVATE_FINAL_FIELDS}, {"Tests that the method returns the expected value if the class extends another class", ImmutableToFooSubClass.class, false, EXPECTED_SUB_CLASS_PRIVATE_FIELDS}, + {"Tests that the method returns the expected value if the class extends another class and skipFinal is not passed as param", + ImmutableToFooSubClass.class, null, EXPECTED_SUB_CLASS_PRIVATE_FIELDS}, {"Tests that the method returns the expected value if the skipFinal is enabled", CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, true, EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_NOT_FINAL_FIELDS} }; diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index dce395c15..3c222c077 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -18,6 +18,8 @@ import static java.math.BigInteger.ZERO; +import static java.util.Objects.isNull; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -39,6 +41,7 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; @@ -59,6 +62,7 @@ public class ReflectionUtilsTest { private static final String GETTER_METHOD_PREFIX_METHOD_NAME = "getGetterMethodPrefix"; private static final String CHECK_FIELD_NAME = "check"; private static final String EXPECTED_SETTER_METHOD_NAME = "setId"; + private static final String DECLARING_CLASS_NAME = "declaringClassName"; /** * The class to be tested. @@ -170,42 +174,67 @@ public void testGetMapGenericTypeThrowsIllegalArgumentExceptionWhenTheGivenTypeI /** * Tests that the method {@code getGetterMethodPrefix} returns the expected value. - * - * @throws Exception if the method does not exists or the invoke fails. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result */ - @Test - public void testGetGetterMethodPrefixWorksAsExpected() throws Exception { + @Test(dataProvider = "dataGetGetterMethodPrefixTesting") + public void testGetGetterMethodPrefixWorksAsExpected(final String testCaseDescription, final Class testClass, final String expectedResult) throws Exception { // GIVEN Method method = underTest.getClass().getDeclaredMethod(GETTER_METHOD_PREFIX_METHOD_NAME, Class.class); method.setAccessible(true); - Field booleanField = FromFooSubClass.class.getDeclaredField(CHECK_FIELD_NAME); // WHEN - String stringGetterMethodPrefix = (String) method.invoke(underTest, String.class); - String booleanGetterMethodPrefix = (String) method.invoke(underTest, Boolean.class); - String primitiveBooleanGetterMethodPrefix = (String) method.invoke(underTest, booleanField.getType()); + String actual = (String) method.invoke(underTest, testClass); // THEN - assertEquals(GET.getPrefix(), stringGetterMethodPrefix); - assertEquals(IS.getPrefix(), booleanGetterMethodPrefix); - assertEquals(IS.getPrefix(), primitiveBooleanGetterMethodPrefix); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code getGetterMethodPrefix}. + * @return parameters to be used for testing the the method {@code getGetterMethodPrefix}. + * @throws Exception if the method does not exists or the invoke fails. + */ + @DataProvider + private Object[][] dataGetGetterMethodPrefixTesting() throws Exception { + return new Object[][] { + {"Tests that the method returns the prefix: 'get' in case the returned class is a String ", String.class, GET.getPrefix()}, + {"Tests that the method returns the prefix: 'is' in case the returned class is a Boolean", Boolean.class, IS.getPrefix()}, + {"Tests that the method returns the prefix: 'is' in case the returned class is a primitive boolean", + FromFooSubClass.class.getDeclaredField(CHECK_FIELD_NAME).getType(), IS.getPrefix()} + }; } /** * Tests that the method {@code getFieldAnnotation} returns the proper annotation. + * @param testCaseDescription the test case description + * @param annotationToGet the annotation to retrieve + * @param expectNull true if it's expected to find it null, false otherwise */ - @Test - public void testGetFieldAnnotationWorksProperly() throws NoSuchFieldException { + @Test(dataProvider = "dataGetFieldAnnotationTesting") + public void testGetFieldAnnotationWorksProperly(final String testCaseDescription, final Class annotationToGet, + final boolean expectNull) throws NoSuchFieldException { // GIVEN Field nameField = ImmutableToFoo.class.getDeclaredField(ID_FIELD_NAME); // WHEN - final NotNull notNullFieldAnnotation = underTest.getFieldAnnotation(nameField, NotNull.class); - final NotBlank notBlankFieldAnnotation = underTest.getFieldAnnotation(nameField, NotBlank.class); + final Annotation actual = underTest.getFieldAnnotation(nameField, annotationToGet); // THEN - assertNotNull(notNullFieldAnnotation); - assertNull(notBlankFieldAnnotation); + assertEquals(expectNull, isNull(actual)); + } + + /** + * Creates the parameters to be used for testing the method {@code getFieldAnnotation}. + * @return parameters to be used for testing the the method {@code getFieldAnnotation}. + */ + @DataProvider + private Object[][] dataGetFieldAnnotationTesting() { + return new Object[][] { + {"Tests that the method returns the field's annotation: 'NotNull' for the given field", NotNull.class, false}, + {"Tests that the method returns: null in case the searched annotation does not exists on the given field", NotBlank.class, true} + }; } /** @@ -246,7 +275,7 @@ public void testGetParameterAnnotationReturnsTheAnnotationIfExists() { when(parameter.getAnnotation(NotNull.class)).thenReturn(notNullAnnotation); // WHEN - final Annotation actual = underTest.getParameterAnnotation(parameter, NotNull.class, "declaringClassName"); + final Annotation actual = underTest.getParameterAnnotation(parameter, NotNull.class, DECLARING_CLASS_NAME); // THEN assertNotNull(actual); @@ -263,7 +292,7 @@ public void testGetParameterAnnotationReturnsNullIfTheAnnotationDoesNotExists() when(parameter.isAnnotationPresent(NotNull.class)).thenReturn(false); // WHEN - final Annotation actual = underTest.getParameterAnnotation(parameter, NotNull.class, "declaringClassName"); + final Annotation actual = underTest.getParameterAnnotation(parameter, NotNull.class, DECLARING_CLASS_NAME); // THEN assertNull(actual); diff --git a/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java index ddb0a551d..460512340 100644 --- a/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java @@ -16,10 +16,13 @@ package com.hotels.beans.utils; +import static java.util.Objects.nonNull; + import static org.mockito.MockitoAnnotations.initMocks; import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** @@ -52,45 +55,62 @@ public void beforeMethod() { /** * Test that an exception is thrown when the given parameter is null. + * @param testCaseDescription the test case description + * @param elemToCheck the element to check + * @param exceptionMessage the exception message */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testNotNullRaisesAnExceptionWhenTheGivenObjectIsNull() { + @Test(dataProvider = "dataIllegalArgumentExceptionTesting", expectedExceptions = IllegalArgumentException.class) + public void testNotNullRaisesAnExceptionWhenTheGivenObjectIsNull(final String testCaseDescription, final Object elemToCheck, final String exceptionMessage) { //GIVEN //WHEN - underTest.notNull(null, EXCEPTION_MESSAGE); + if (nonNull(exceptionMessage)) { + underTest.notNull(elemToCheck, exceptionMessage); + } else { + underTest.notNull(elemToCheck); + } } /** - * Test that no exception are throw when the given parameter is not null. + * Creates the parameters to be used for testing tat the method {@code notNull} raises an {@link IllegalArgumentException}. + * @return parameters to be used for testing tat the method {@code notNull} raises an {@link IllegalArgumentException}. */ - @Test - public void testThatNoExceptionAreThrownWhenTheGivenObjectIsNotNull() { - //GIVEN - - //WHEN - underTest.notNull(VALUE, EXCEPTION_MESSAGE); + @DataProvider + private Object[][] dataIllegalArgumentExceptionTesting() { + return new Object[][] { + {"Tests that the method raise an exception if the given parameter is null and a description message is defined", null, EXCEPTION_MESSAGE}, + {"Tests that the method raise an exception if the given parameter is null and a description message is not defined", null, null} + }; } /** - * Test that an exception is thrown when the given parameter is null. + * Test that no exception are throw when the given parameter is not null. + * @param testCaseDescription the test case description + * @param elemToCheck the element to check + * @param exceptionMessage the exception message */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testNotNullRaisesAnExceptionWhenTheGivenObjectIsNullEvenWithoutACustomMessage() { + @Test(dataProvider = "dataNoExceptionAreRaisedTesting") + public void testThatNoExceptionAreThrownWhenTheGivenObjectIsNotNullEvenWithoutACustomMessage(final String testCaseDescription, final Object elemToCheck, + final String exceptionMessage) { //GIVEN //WHEN - underTest.notNull(null); + if (nonNull(exceptionMessage)) { + underTest.notNull(elemToCheck, exceptionMessage); + } else { + underTest.notNull(elemToCheck); + } } /** - * Test that no exception are throw when the given parameter is not null. + * Creates the parameters to be used for testing tat the method {@code notNull} raises an {@link IllegalArgumentException}. + * @return parameters to be used for testing tat the method {@code notNull} raises an {@link IllegalArgumentException}. */ - @Test - public void testThatNoExceptionAreThrownWhenTheGivenObjectIsNotNullEvenWithoutACustomMessage() { - //GIVEN - - //WHEN - underTest.notNull(VALUE); + @DataProvider + private Object[][] dataNoExceptionAreRaisedTesting() { + return new Object[][] { + {"Tests that the method does not raise an exception if the given parameter is not null and a description message is defined", VALUE, EXCEPTION_MESSAGE}, + {"Tests that the method does not raise an exception if the given parameter is not null and a description message is not defined", VALUE, null} + }; } } From cb1e6b471fe53402f27ec55e846c7a32f9e646f5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 17 Mar 2019 17:33:07 +0100 Subject: [PATCH 0316/1786] Used data provider for other immutable object test cases --- .../java/com/hotels/beans/sample/FromFoo.java | 6 +- .../hotels/beans/sample/FromFooAdvFields.java | 10 ++- .../ImmutableObjectTransformationTest.java | 78 ++++++++++++------- 3 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/test/java/com/hotels/beans/sample/FromFoo.java b/src/test/java/com/hotels/beans/sample/FromFoo.java index d6387a10f..38f693fe3 100644 --- a/src/test/java/com/hotels/beans/sample/FromFoo.java +++ b/src/test/java/com/hotels/beans/sample/FromFoo.java @@ -29,13 +29,17 @@ @AllArgsConstructor @Getter @Setter -public class FromFoo { +public class FromFoo implements Cloneable { private final String name; private BigInteger id; private final List nestedObjectList; private final List list; private final FromSubFoo nestedObject; + public FromFoo clone() throws CloneNotSupportedException { + return (FromFoo) super.clone(); + } + @Override public String toString() { return "FromFoo"; diff --git a/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java index b5bcb5d0c..18a8674f2 100644 --- a/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java +++ b/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java @@ -22,6 +22,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.Setter; import lombok.ToString; /** @@ -29,11 +30,16 @@ */ @AllArgsConstructor @Getter +@Setter @ToString -public class FromFooAdvFields { - private final Optional name; +public class FromFooAdvFields implements Cloneable { + private Optional name; private final Optional age; private final String indexNumber; private final ClassType classType; private final String locale; + + public FromFooAdvFields clone() throws CloneNotSupportedException { + return (FromFooAdvFields) super.clone(); + } } diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 2de7cde54..b9dd971a1 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -24,7 +24,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -36,6 +35,7 @@ import java.lang.reflect.Parameter; import java.math.BigInteger; import java.util.Locale; +import java.util.Optional; import java.util.stream.IntStream; import org.mockito.InjectMocks; @@ -50,6 +50,7 @@ import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFoo; +import com.hotels.beans.sample.FromFooAdvFields; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.immutable.ImmutableFlatToFoo; import com.hotels.beans.sample.immutable.ImmutableToFoo; @@ -207,29 +208,34 @@ private Object[][] dataConstructorErrorTesting() { } /** - * Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object. + * Test that an {@link InvalidBeanException} is thrown if the bean is not valid. + * @param testCaseDescription the test case description + * @param sourceObject the object to transform + * @param targetObjectClass the target object class */ - @Test(expectedExceptions = InvalidBeanException.class) - public void testTransformThrowsExceptionWhenImmutableBeanHasAWrongConstructor() { + @Test(dataProvider = "dataInvalidBeanExceptionTesting", expectedExceptions = InvalidBeanException.class) + public void testTransformThrowsExceptionWhenImmutableIsInvalid(final String testCaseDescription, final FromFoo sourceObject, + final Class targetObjectClass) { //GIVEN //WHEN - underTest.transform(fromFoo, ImmutableToFooInvalid.class); + underTest.transform(sourceObject, targetObjectClass); } /** - * Test that an exception is thrown if the destination object don't met the constraints. + * Creates the parameters to be used for testing the exception raised in case of error during the constructor invocation. + * @return parameters to be used for testing the exception raised in case of error during the constructor invocation. + * @throws CloneNotSupportedException if the clone fails */ - @Test(expectedExceptions = InvalidBeanException.class) - public void testTransformThrowsExceptionIfTheDestinationObjectValuesAreNotValid() { - //GIVEN - fromFoo.setId(null); - - //WHEN - underTest.transform(fromFoo, ImmutableToFoo.class); - - // THEN - fromFoo.setId(ID); + @DataProvider + private Object[][] dataInvalidBeanExceptionTesting() throws CloneNotSupportedException { + FromFoo fromFooNullId = AbstractTransformerTest.fromFoo.clone(); + fromFooNullId.setId(null); + return new Object[][] { + {"Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object.", + fromFoo, ImmutableToFooInvalid.class}, + {"Test that an exception is thrown if the destination object don't met the constraints.", fromFooNullId, ImmutableToFoo.class}, + }; } /** @@ -262,8 +268,8 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); //THEN - assertThat(actual, hasProperty("name", equalTo(actual.getName()))); - assertThat(actual, hasProperty("identifier", equalTo(fromFoo.getId()))); + assertThat(actual, hasProperty(NAME_FIELD_NAME, equalTo(actual.getName()))); + assertThat(actual, hasProperty(IDENTIFIER_FIELD_NAME, equalTo(fromFoo.getId()))); assertEquals(actual.getList(), fromFoo.getList()); IntStream.range(0, actual.getNestedObjectList().size()) .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); @@ -272,24 +278,44 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { /** * Test that bean containing advanced final fields are correctly copied. + * @param testCaseDescription the test case description + * @param sourceObject the object to transform + * @param targetObjectClass the target object class + * @param isNameFieldEmpty true if the name field should contain a value, false otherwise */ - @Test - public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied() { + @Test(dataProvider = "dataCAdvancedFieldsCopyTesting") + public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String testCaseDescription, final FromFooAdvFields sourceObject, + final Class targetObjectClass, final boolean isNameFieldEmpty) { //GIVEN //WHEN final Transformer beanTransformer = underTest .withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)) .withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); - ImmutableToFooAdvFields actual = beanTransformer.transform(fromFooAdvFields, ImmutableToFooAdvFields.class); + ImmutableToFooAdvFields actual = (ImmutableToFooAdvFields) beanTransformer.transform(sourceObject, targetObjectClass); //THEN assertNotNull(actual.getName()); - assertTrue(actual.getName().isPresent()); - assertEquals(fromFooAdvFields.getName().get(), actual.getName().get()); - assertEquals(fromFooAdvFields.getAge().get(), actual.getAge()); - assertEquals(fromFooAdvFields.getClassType(), actual.getClassType()); - assertEquals(fromFooAdvFields.getLocale(), actual.getLocale().getLanguage()); + assertEquals(isNameFieldEmpty, actual.getName().isPresent()); + sourceObject.getName().ifPresent(name -> assertEquals(name, actual.getName().get())); + assertEquals(sourceObject.getAge().get(), actual.getAge()); + assertEquals(sourceObject.getClassType(), actual.getClassType()); + assertEquals(sourceObject.getLocale(), actual.getLocale().getLanguage()); + } + + /** + * Creates the parameters to be used for testing the transformation of advanced type fields. + * @return parameters to be used for testing the transformation of advanced type fields. + * @throws CloneNotSupportedException if the clone fails + */ + @DataProvider + private Object[][] dataCAdvancedFieldsCopyTesting() throws CloneNotSupportedException { + FromFooAdvFields emptyOptionalSourceObject = fromFooAdvFields.clone(); + emptyOptionalSourceObject.setName(Optional.empty()); + return new Object[][] { + {"Test that bean containing advanced final fields are correctly copied", fromFooAdvFields, ImmutableToFooAdvFields.class, true}, + {"Test that bean containing advanced final fields (with empty optional) are correctly copied", emptyOptionalSourceObject, ImmutableToFooAdvFields.class, false} + }; } /** From 1af67c0e50dfdafd6a096c20e5e1df362b2ffa6a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 17 Mar 2019 18:20:34 +0100 Subject: [PATCH 0317/1786] Added test case for extremely complex maps --- .../beans/transformer/TransformerImpl.java | 4 +- .../com/hotels/beans/sample/FromFooMap.java | 37 +++++++++++++++++++ .../sample/immutable/ImmutableToFooMap.java | 37 +++++++++++++++++++ .../transformer/AbstractTransformerTest.java | 19 ++++++---- .../ImmutableObjectTransformationTest.java | 3 ++ 5 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 src/test/java/com/hotels/beans/sample/FromFooMap.java create mode 100644 src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 11f02f0db..bd76ef193 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -23,6 +23,8 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; +import static org.apache.commons.lang3.StringUtils.EMPTY; + import static com.hotels.beans.constant.Punctuation.DOT; import static com.hotels.beans.constant.Punctuation.COMMA; import static com.hotels.beans.constant.Punctuation.LPAREN; @@ -334,7 +336,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN * @return the updated breadcrumb */ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { - return (nonNull(breadcrumb) ? breadcrumb + DOT.getSymbol() : "") + fieldName; + return (nonNull(breadcrumb) ? breadcrumb + DOT.getSymbol() : EMPTY) + fieldName; } /** diff --git a/src/test/java/com/hotels/beans/sample/FromFooMap.java b/src/test/java/com/hotels/beans/sample/FromFooMap.java new file mode 100644 index 000000000..86c33e7d7 --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/FromFooMap.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.util.List; +import java.util.Map; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object containing extremely complex map. + */ +@AllArgsConstructor +@Getter +@ToString +public class FromFooMap { + private final Map sampleMap; + private final Map> complexMap; + private final Map> veryComplexMap; + private final Map> extremeComplexMap; +} diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java new file mode 100644 index 000000000..3b0f6451d --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.util.List; +import java.util.Map; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object containing extremely complex map. + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableToFooMap { + private final Map sampleMap; + private final Map> complexMap; + private final Map> veryComplexMap; + private final Map> extremeComplexMap; +} diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index 25695b384..782178e0d 100644 --- a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -33,6 +33,7 @@ import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooAdvFields; +import com.hotels.beans.sample.FromFooMap; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.FromFooWithPrimitiveFields; @@ -50,6 +51,7 @@ public abstract class AbstractTransformerTest { static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; static FromFooSubClass fromFooSubClass; static FromFooAdvFields fromFooAdvFields; + static FromFooMap fromFooMap; static final int AGE = 34; static final String AGE_FIELD_NAME = "age"; static final String DEST_FIELD_NAME = "destFieldName"; @@ -71,9 +73,10 @@ public abstract class AbstractTransformerTest { private static final BigDecimal AMOUNT = new BigDecimal(10); private static final String SUB_FOO_NAME = "Smith"; private static final int[] SUB_FOO_PHONE_NUMBERS = {12345, 6892, 10873}; - private static final Map SUB_FOO_SAMPLE_MAP = new HashMap<>(); - private static final Map> SUB_FOO_COMPLEX_MAP = new HashMap<>(); - private static final Map> SUB_FOO_VERY_COMPLEX_MAP = new HashMap<>(); + private static final Map SAMPLE_MAP = new HashMap<>(); + private static final Map> COMPLEX_MAP = new HashMap<>(); + private static final Map> VERY_COMPLEX_MAP = new HashMap<>(); + private static final Map> EXTREME_COMPLEX_MAP = new HashMap<>(); private static List fromSubFooList; private static List sourceFooSimpleList; private static FromSubFoo fromSubFoo; @@ -90,10 +93,10 @@ public void beforeClass() { * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. */ private void initObjects() { - SUB_FOO_SAMPLE_MAP.put(ITEM_1, ITEM_2); - SUB_FOO_COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); - SUB_FOO_VERY_COMPLEX_MAP.put(ITEM_1, SUB_FOO_SAMPLE_MAP); - fromSubFoo = new FromSubFoo(SUB_FOO_NAME, SUB_FOO_PHONE_NUMBERS, SUB_FOO_SAMPLE_MAP, SUB_FOO_COMPLEX_MAP, SUB_FOO_VERY_COMPLEX_MAP); + SAMPLE_MAP.put(ITEM_1, ITEM_2); + COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); + VERY_COMPLEX_MAP.put(ITEM_1, SAMPLE_MAP); + fromSubFoo = new FromSubFoo(SUB_FOO_NAME, SUB_FOO_PHONE_NUMBERS, SAMPLE_MAP, COMPLEX_MAP, VERY_COMPLEX_MAP); fromSubFooList = singletonList(fromSubFoo); sourceFooSimpleList = asList(ITEM_1, ITEM_2); fromFoo = createFromFoo(fromSubFoo); @@ -102,6 +105,8 @@ private void initObjects() { fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); fromFooSubClass = createFromFooSubClass(); fromFooAdvFields = createFromFooAdvFields(); + EXTREME_COMPLEX_MAP.put(fromFooSimple, SAMPLE_MAP); + fromFooMap = new FromFooMap(SAMPLE_MAP, COMPLEX_MAP, VERY_COMPLEX_MAP, EXTREME_COMPLEX_MAP); } /** diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index b9dd971a1..7cde99247 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -58,6 +58,7 @@ import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooDiffFields; import com.hotels.beans.sample.immutable.ImmutableToFooInvalid; +import com.hotels.beans.sample.immutable.ImmutableToFooMap; import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooNoConstructors; import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; @@ -122,6 +123,8 @@ private Object[][] dataDefaultTransformationTesting() { {"Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg are correctly copied.", beanUtils.getTransformer(), fromFoo, ImmutableToFooCustomAnnotation.class}, {"Test that bean that extends another class are correctly copied", beanUtils.getTransformer(), fromFooSubClass, ImmutableToFooSubClass.class}, + {"Test that immutable beans with extremely complex map are correctly transformed.", + beanUtils.getTransformer(), fromFooMap, ImmutableToFooMap.class}, }; } From 63a2b22a006decb4761271377a1683572012d125 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Mar 2019 08:54:31 +0100 Subject: [PATCH 0318/1786] Replaced junit with testng --- CHANGELOG.md | 5 ++-- pom.xml | 2 +- .../transformer/AbstractTransformer.java | 16 ---------- .../hotels/beans/transformer/Transformer.java | 12 -------- .../beans/transformer/TransformerImpl.java | 12 -------- .../transformer/TransformerSettings.java | 7 ----- .../ImmutableObjectTransformationTest.java | 29 ++++--------------- .../MixedObjectTransformationTest.java | 18 ------------ .../MutableObjectTransformationTest.java | 19 ------------ 9 files changed, 9 insertions(+), 111 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 479781539..694245f94 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ All notable changes to this project will be documented in this file. -### [1.2.2] TBD -* Implemented possibility to skip properties transformation +### [1.2.2] 2019.03.20 +#### Changed +* Replaced `junit` test with `testng` ### [1.2.1] 2019.03.05 #### Added diff --git a/pom.xml b/pom.xml index d9bc3a7b6..bfa4c173b 100644 --- a/pom.xml +++ b/pom.xml @@ -280,7 +280,7 @@ maven-surefire-plugin ${maven.surefire.plugin.version} - false + true diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 6d2dd619c..177e1daae 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -16,8 +16,6 @@ package com.hotels.beans.transformer; -import static java.util.Arrays.asList; - import static com.hotels.beans.utils.ValidationUtils.notNull; import java.util.Map; @@ -189,20 +187,6 @@ public final void transform(final T sourceObj, final K targetObject) { transform(sourceObj, targetObject, null); } - /** - * {@inheritDoc} - */ - @Override - public Transformer skipTransformationForField(final String... fieldName) { - settings.getFieldsToSkip().addAll(asList(fieldName)); - return this; - } - - @Override - public void resetFieldsTransformationSkip() { - settings.getFieldsToSkip().clear(); - } - /** * Copies all properties from an object to a new one. * @param sourceObj the source object diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index 77b0761f2..986a607e4 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -105,16 +105,4 @@ public interface Transformer { * @return the {@link Transformer} instance */ Transformer setValidationDisabled(boolean validationDisabled); - - /** - * Allows to specify all the fields for which the transformation have to be skipped. - * @param fieldName the destination object's fields names - * @return the {@link Transformer} instance - */ - Transformer skipTransformationForField(String... fieldName); - - /** - * Removes all the configured fields to skip. - */ - void resetFieldsTransformationSkip(); } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index bd76ef193..987773f6e 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -179,15 +179,6 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< return constructorArgsValues; } - /** - * Checks if a field has to be transformed or not. - * @param breadcrumb the field path - * @return true if the transformation has to be applied on this field, false in it has to be skipped. - */ - private boolean doSkipTransformation(final String breadcrumb) { - return settings.getFieldsToSkip().contains(breadcrumb); - } - /** * Returns the field name in the source object. * @param field the field that has to be valorized. @@ -309,9 +300,6 @@ private Object getFieldValue(final T sourceObj, final Class targetClas */ private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); - if (doSkipTransformation(fieldBreadcrumb)) { - return defaultValue(field.getType()); - } boolean primitiveType = classUtils.isPrimitiveType(field.getType()); boolean isFieldTransformerDefined = settings.getFieldsTransformers().containsKey(field.getName()); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 6aaf7c82d..22d4b4433 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -16,9 +16,7 @@ package com.hotels.beans.transformer; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; @@ -49,11 +47,6 @@ final class TransformerSettings { */ private final Map> fieldsTransformers = new ConcurrentHashMap<>(); - /** - * Contains the list of fields that don't need to be transformed. - */ - private final Set fieldsToSkip = new HashSet<>(); - /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 7cde99247..08688f7cb 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -22,7 +22,6 @@ import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -112,7 +111,7 @@ public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, * Creates the parameters to be used for testing the default transformation operations. * @return parameters to be used for testing the default transformation operations. */ - @DataProvider + @DataProvider(parallel = true) private Object[][] dataDefaultTransformationTesting() { BeanUtils beanUtils = new BeanUtils(); return new Object[][] { @@ -171,7 +170,7 @@ public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(f * Creates the parameters to be used for testing the transformation with composite field name mapping. * @return parameters to be used for testing the transformation with composite field name mapping. */ - @DataProvider + @DataProvider(parallel = true) private Object[][] dataCompositeFieldNameTesting() { return new Object[][] { {"Test that, in case a destination object field is contained into a nested object of the source field, defining a composite FieldMapping" @@ -201,7 +200,7 @@ public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsExceptio * Creates the parameters to be used for testing the exception raised in case of error during the constructor invocation. * @return parameters to be used for testing the transformation with composite field name mapping. */ - @DataProvider + @DataProvider(parallel = true) private Object[][] dataConstructorErrorTesting() { FromFoo actual = new FromFoo(NAME, ID, null, null, null); return new Object[][] { @@ -230,7 +229,7 @@ public void testTransformThrowsExceptionWhenImmutableIsInvalid(final String test * @return parameters to be used for testing the exception raised in case of error during the constructor invocation. * @throws CloneNotSupportedException if the clone fails */ - @DataProvider + @DataProvider(parallel = true) private Object[][] dataInvalidBeanExceptionTesting() throws CloneNotSupportedException { FromFoo fromFooNullId = AbstractTransformerTest.fromFoo.clone(); fromFooNullId.setId(null); @@ -311,7 +310,7 @@ public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String te * @return parameters to be used for testing the transformation of advanced type fields. * @throws CloneNotSupportedException if the clone fails */ - @DataProvider + @DataProvider(parallel = true) private Object[][] dataCAdvancedFieldsCopyTesting() throws CloneNotSupportedException { FromFooAdvFields emptyOptionalSourceObject = fromFooAdvFields.clone(); emptyOptionalSourceObject.setName(Optional.empty()); @@ -460,24 +459,6 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor assertThat(immutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } - /** - * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. - */ - @Test - public void testFieldTransformationSkipWorksProperly() { - //GIVEN - underTest.skipTransformationForField("name", "nestedObject.phoneNumbers"); - - //WHEN - ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); - - //THEN - assertEquals(fromFoo.getId(), actual.getId()); - assertNull(actual.getName()); - assertNull(actual.getNestedObject().getPhoneNumbers()); - underTest.resetFieldsTransformationSkip(); - } - /** * Initializes the mocks required for testing method: {@code getDestFieldName}. * @param declaringClassName the declaring class name diff --git a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 03b8f0da4..5c1a49837 100644 --- a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -177,24 +177,6 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor assertThat(mixedObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } - /** - * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. - */ - @Test - public void testFieldTransformationSkipWorksProperly() { - //GIVEN - underTest.skipTransformationForField(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); - - //WHEN - MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); - - //THEN - assertEquals(fromFoo.getId(), actual.getId()); - assertNull(actual.getName()); - assertNull(actual.getNestedObject().getPhoneNumbers()); - underTest.resetFieldsTransformationSkip(); - } - /** * Test transformation on an existing bean is correctly copied. */ diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index f5008da5d..0653480f4 100644 --- a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -19,7 +19,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; @@ -170,22 +169,4 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor //THEN assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } - - /** - * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. - */ - @Test - public void testFieldTransformationSkipWorksProperly() { - //GIVEN - underTest.skipTransformationForField(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); - - //WHEN - MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); - - //THEN - assertEquals(fromFoo.getId(), actual.getId()); - assertNull(actual.getName()); - assertNull(actual.getNestedObject().getPhoneNumbers()); - underTest.resetFieldsTransformationSkip(); - } } From ebfd48bd84b6247452c4cfac22c46a87e6f57b28 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Mar 2019 08:59:56 +0100 Subject: [PATCH 0319/1786] Removed not used exception --- .../hotels/beans/error/MissingMethodException.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/java/com/hotels/beans/error/MissingMethodException.java b/src/main/java/com/hotels/beans/error/MissingMethodException.java index 1323a2070..ce84a8252 100644 --- a/src/main/java/com/hotels/beans/error/MissingMethodException.java +++ b/src/main/java/com/hotels/beans/error/MissingMethodException.java @@ -30,16 +30,4 @@ public class MissingMethodException extends RuntimeException { public MissingMethodException(final String message) { super(message); } - - /** - * Constructs a new invalid bean exception with the specified detail message. - * The cause is not initialized, and may subsequently be initialized by a - * call to {@link #initCause}. - * @param message the detail message. The detail message is saved for later - * retrieval by the {@link #getMessage()} method. - * @param cause the given bean is not valid and caused an exception while copying the properties. - */ - public MissingMethodException(final String message, final Throwable cause) { - super(message, cause); - } } From ebc489e6e91a9d8409b55f81a335e26252bf7ed8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Mar 2019 09:03:39 +0100 Subject: [PATCH 0320/1786] Restored isAccessible method --- src/main/java/com/hotels/beans/utils/ReflectionUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 50d7e9499..f27136f6c 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -314,7 +314,7 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f * @return true id is accessible, false otherwise */ private boolean isFieldAccessible(final Field field, final Object target) { - return field.canAccess(target); + return field.isAccessible(); } /** From 737c27cc9d62aef9c8ce1cf86bf30520cbdf9b91 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Mar 2019 09:27:58 +0100 Subject: [PATCH 0321/1786] Updated changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 694245f94..d3cbf46e7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,10 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.7] 2019.03.20 +#### Changed +* Replaced `junit` test with `testng` + ### [1.1.6] 2019.03.05 #### Added * Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) for project compiled with `jdk` 8. From 4d7facbba201eaf81586104e13c082846ba0179d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Mar 2019 09:30:37 +0100 Subject: [PATCH 0322/1786] [maven-release-plugin] prepare release 1.2.2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index bfa4c173b..85d35c820 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.2-SNAPSHOT + 1.2.2 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.2 From 71c9e2c43df698b3a6e0aa32cbfb0355cdb0fc79 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Mar 2019 09:30:46 +0100 Subject: [PATCH 0323/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 85d35c820..81b737ca2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.2 + 1.2.3-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.2 + HEAD From 66474ce29c3fb9e95f35f5dac988d184a5ff8f5e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 20 Mar 2019 09:55:18 +0100 Subject: [PATCH 0324/1786] Restored skip validation function --- .../transformer/AbstractTransformer.java | 16 ++++++++++++++++ .../hotels/beans/transformer/Transformer.java | 12 ++++++++++++ .../beans/transformer/TransformerImpl.java | 12 ++++++++++++ .../transformer/TransformerSettings.java | 7 +++++++ .../ImmutableObjectTransformationTest.java | 19 +++++++++++++++++++ .../MixedObjectTransformationTest.java | 18 ++++++++++++++++++ .../MutableObjectTransformationTest.java | 19 +++++++++++++++++++ 7 files changed, 103 insertions(+) diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 177e1daae..6d2dd619c 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -16,6 +16,8 @@ package com.hotels.beans.transformer; +import static java.util.Arrays.asList; + import static com.hotels.beans.utils.ValidationUtils.notNull; import java.util.Map; @@ -187,6 +189,20 @@ public final void transform(final T sourceObj, final K targetObject) { transform(sourceObj, targetObject, null); } + /** + * {@inheritDoc} + */ + @Override + public Transformer skipTransformationForField(final String... fieldName) { + settings.getFieldsToSkip().addAll(asList(fieldName)); + return this; + } + + @Override + public void resetFieldsTransformationSkip() { + settings.getFieldsToSkip().clear(); + } + /** * Copies all properties from an object to a new one. * @param sourceObj the source object diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index 986a607e4..77b0761f2 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -105,4 +105,16 @@ public interface Transformer { * @return the {@link Transformer} instance */ Transformer setValidationDisabled(boolean validationDisabled); + + /** + * Allows to specify all the fields for which the transformation have to be skipped. + * @param fieldName the destination object's fields names + * @return the {@link Transformer} instance + */ + Transformer skipTransformationForField(String... fieldName); + + /** + * Removes all the configured fields to skip. + */ + void resetFieldsTransformationSkip(); } diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 987773f6e..bd76ef193 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -179,6 +179,15 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< return constructorArgsValues; } + /** + * Checks if a field has to be transformed or not. + * @param breadcrumb the field path + * @return true if the transformation has to be applied on this field, false in it has to be skipped. + */ + private boolean doSkipTransformation(final String breadcrumb) { + return settings.getFieldsToSkip().contains(breadcrumb); + } + /** * Returns the field name in the source object. * @param field the field that has to be valorized. @@ -300,6 +309,9 @@ private Object getFieldValue(final T sourceObj, final Class targetClas */ private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); + if (doSkipTransformation(fieldBreadcrumb)) { + return defaultValue(field.getType()); + } boolean primitiveType = classUtils.isPrimitiveType(field.getType()); boolean isFieldTransformerDefined = settings.getFieldsTransformers().containsKey(field.getName()); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 22d4b4433..6aaf7c82d 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -16,7 +16,9 @@ package com.hotels.beans.transformer; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; @@ -47,6 +49,11 @@ final class TransformerSettings { */ private final Map> fieldsTransformers = new ConcurrentHashMap<>(); + /** + * Contains the list of fields that don't need to be transformed. + */ + private final Set fieldsToSkip = new HashSet<>(); + /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 08688f7cb..baef9fb19 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -22,6 +22,7 @@ import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -459,6 +460,24 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor assertThat(immutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } + /** + * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. + */ + @Test + public void testFieldTransformationSkipWorksProperly() { + //GIVEN + underTest.skipTransformationForField("name", "nestedObject.phoneNumbers"); + + //WHEN + ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); + + //THEN + assertEquals(fromFoo.getId(), actual.getId()); + assertNull(actual.getName()); + assertNull(actual.getNestedObject().getPhoneNumbers()); + underTest.resetFieldsTransformationSkip(); + } + /** * Initializes the mocks required for testing method: {@code getDestFieldName}. * @param declaringClassName the declaring class name diff --git a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 5c1a49837..03b8f0da4 100644 --- a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -177,6 +177,24 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor assertThat(mixedObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } + /** + * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. + */ + @Test + public void testFieldTransformationSkipWorksProperly() { + //GIVEN + underTest.skipTransformationForField(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); + + //WHEN + MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); + + //THEN + assertEquals(fromFoo.getId(), actual.getId()); + assertNull(actual.getName()); + assertNull(actual.getNestedObject().getPhoneNumbers()); + underTest.resetFieldsTransformationSkip(); + } + /** * Test transformation on an existing bean is correctly copied. */ diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 0653480f4..f5008da5d 100644 --- a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -19,6 +19,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; @@ -169,4 +170,22 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor //THEN assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } + + /** + * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. + */ + @Test + public void testFieldTransformationSkipWorksProperly() { + //GIVEN + underTest.skipTransformationForField(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); + + //WHEN + MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); + + //THEN + assertEquals(fromFoo.getId(), actual.getId()); + assertNull(actual.getName()); + assertNull(actual.getNestedObject().getPhoneNumbers()); + underTest.resetFieldsTransformationSkip(); + } } From 01dd6b69275ebf594185112f386f1aae01b78f69 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 11:12:19 +0100 Subject: [PATCH 0325/1786] minor updates --- .../com/hotels/beans/error/InvalidBeanException.java | 9 --------- .../hotels/beans/transformer/AbstractTransformer.java | 4 +++- .../java/com/hotels/beans/transformer/Transformer.java | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/hotels/beans/error/InvalidBeanException.java b/src/main/java/com/hotels/beans/error/InvalidBeanException.java index aa9a38dbf..ceae328d5 100644 --- a/src/main/java/com/hotels/beans/error/InvalidBeanException.java +++ b/src/main/java/com/hotels/beans/error/InvalidBeanException.java @@ -20,15 +20,6 @@ * Invalid Bean exception class. */ public class InvalidBeanException extends RuntimeException { - /** - * Constructs a new runtime exception with the specified detail message and - * cause. - * @param cause the given bean is not valid and caused an exception while copying the properties. - */ - public InvalidBeanException(final Throwable cause) { - super(cause); - } - /** * Constructs a new invalid bean exception with the specified detail message. * The cause is not initialized, and may subsequently be initialized by a diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 6d2dd619c..59f01d89c 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -194,7 +194,9 @@ public final void transform(final T sourceObj, final K targetObject) { */ @Override public Transformer skipTransformationForField(final String... fieldName) { - settings.getFieldsToSkip().addAll(asList(fieldName)); + if (fieldName.length != 0) { + settings.getFieldsToSkip().addAll(asList(fieldName)); + } return this; } diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index 77b0761f2..f70896227 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -108,7 +108,7 @@ public interface Transformer { /** * Allows to specify all the fields for which the transformation have to be skipped. - * @param fieldName the destination object's fields names + * @param fieldName the destination object's field(s) name that have to be skipped * @return the {@link Transformer} instance */ Transformer skipTransformationForField(String... fieldName); From 925da2160d6f32d219abd24aa82bda6454253feb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 13:01:05 +0100 Subject: [PATCH 0326/1786] Modified method getDeclaredField in order to speed-up the performances --- .../hotels/beans/utils/ReflectionUtils.java | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index f27136f6c..c5cffe81e 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -230,7 +230,7 @@ private Object getFieldValue(final Object target, final String fieldName) { } return field.get(target); } catch (MissingFieldException e) { - throw new MissingFieldException(target.getClass().getCanonicalName() + " does not contain field: " + fieldName); + throw e; } catch (final Exception e) { handleReflectionException(e); throw new IllegalStateException(e); @@ -244,27 +244,25 @@ private Object getFieldValue(final Object target, final String fieldName) { /** * Return the field of the given class. * @param fieldName the name of the filed to retrieve. - * @param target the field's class + * @param target the field's class * @return the field corresponding to the given name. */ private Field getDeclaredField(final String fieldName, final Object target) { - final AtomicReference> targetClass = new AtomicReference<>(target.getClass()); - final String cacheKey = "DeclaredField-" + targetClass.get().getCanonicalName() + "-fieldName-" + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { - Field field = null; - while (isNull(field) && !targetClass.get().equals(Object.class)) { - try { - field = targetClass.get().getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - targetClass.set(targetClass.get().getSuperclass()); - } - } - if (isNull(field)) { - throw new MissingFieldException(targetClass.get().getCanonicalName() + " does not contain field: " + fieldName); + Field field; + Class targetClass = target instanceof Class ? (Class) target : target.getClass(); + try { + field = targetClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + if (!targetClass.getSuperclass().equals(Object.class)) { + field = getDeclaredField(fieldName, targetClass.getSuperclass()); + } else { + throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); } - cacheManager.cacheObject(cacheKey, field); - return field; - }); + } catch (final Exception e) { + handleReflectionException(e); + throw new IllegalStateException(e); + } + return field; } /** From 3871495013d67d6dc54853b98e417dc3469e7d47 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 13:27:42 +0100 Subject: [PATCH 0327/1786] - Added documentation for the new feature - Improved performances - Prepared changelog for the release --- CHANGELOG.md | 10 ++++ README.md | 62 +++++++++++++++++++++-- docs/site/markdown/index.md | 10 ++-- docs/site/markdown/transformer/samples.md | 53 +++++++++++++++++++ 4 files changed, 127 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3cbf46e7..139f2d45a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.2.3] 2019.03.22 +#### Added +* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/HotelsDotCom/bull/issues/38)) +* Performance improvement + ### [1.2.2] 2019.03.20 #### Changed * Replaced `junit` test with `testng` @@ -20,6 +25,11 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.8] 2019.03.22 +#### Added +* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/HotelsDotCom/bull/issues/38)) +* Performance improvement + ### [1.1.7] 2019.03.20 #### Changed * Replaced `junit` test with `testng` diff --git a/README.md b/README.md index d1200577e..b07a4e062 100644 --- a/README.md +++ b/README.md @@ -51,12 +51,13 @@ mvn clean install -P relaxed * support copy with array containing primitive types. e.g. `String[]` => `String[]` * support copy with array type. e.g. `BeanA[]` => `BeanB[]` * support copy with property name mapping. e.g. `int id => int userId` -* support copy with recursion copy -* support validation through annotations -* support copy of beans with different field's name -* support lambda function field transformation +* support copy with recursion copy. +* support validation through annotations. +* support copy of beans with different field's name. +* support lambda function field transformation. * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. +* allows to skip transformation for a given set of fields. # Transformation samples @@ -376,6 +377,59 @@ ToBean toBean = new ToBean(); beanUtils.getTransformer().transform(fromBean, toBean); ~~~ +### Skip transformation on a given set of fields: + +Given: + +~~~Java +public class FromBean { public class ToBean { + private final String name; private String name; + private final FromSubBean nestedObject; private ToSubBean nestedObject; + + // all args constructor // constructor + // getters... // getters and setters... +} } + +public class FromBean2 { + private final int index; + private final FromSubBean nestedObject; + + // all args constructor + // getters... +} +~~~ +if you need to skip the transformation for a given field, just do: +~~~Java +ToBean toBean = new ToBean(); +beanUtils.getTransformer() + .skipTransformationForField("nestedObject") + .transform(fromBean, toBean); +~~~ + +where `nestedObject` is the name of the field in the destination object. + +This feature allows to **transform an object keeping the data from different sources**. + +To better explain this function let's assume that the `ToBean` (defined above) should be transformed as follow: +- `name` field value has be taken from the `FromBean` object +- `nestedObject` field value has be taken from the `FromBean2` object + +the objective can be reached by doing: +~~~Java +// create the destination object +ToBean toBean = new ToBean(); + +// execute the first transformation skipping the copy of: 'nestedObject' field that should come from the other source object +beanUtils.getTransformer() + .skipTransformationForField("nestedObject") + .transform(fromBean, toBean); + +// then execute the transformation skipping the copy of: 'name' field that should come from the other source object +beanUtils.getTransformer() + .skipTransformationForField("name") + .transform(fromBean2, toBean); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` ## Third party library comparison diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 5775211a8..2f50ab8f7 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -24,9 +24,11 @@ This BeanUtils library is a utility library for managing Bean objects. The libra * support copy with array containing primitive types. e.g. `String[]` => `String[]` * support copy with array type. e.g. `BeanA[]` => `BeanB[]` * support copy with property name mapping. e.g. `int id => int userId` - * support copy with recursion copy - * support validation through annotations - * support copy of beans with different field's name - * support lambda function field transformation + * support copy with recursion copy. + * support validation through annotations. + * support copy of beans with different field's name. + * support lambda function field transformation. * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. + * allows to skip transformation for a given set of fields. + diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index a18752a19..46cb6c95c 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -320,4 +320,57 @@ ToBean toBean = new ToBean(); beanUtils.getTransformer().transform(fromBean, toBean); ~~~ +### Skip transformation on a given set of fields: + +Given: + +~~~Java +public class FromBean { public class ToBean { + private final String name; private String name; + private final FromSubBean nestedObject; private ToSubBean nestedObject; + + // all args constructor // constructor + // getters... // getters and setters... +} } + +public class FromBean2 { + private final int index; + private final FromSubBean nestedObject; + + // all args constructor + // getters... +} +~~~ +if you need to skip the transformation for a given field, just do: +~~~Java +ToBean toBean = new ToBean(); +beanUtils.getTransformer() + .skipTransformationForField("nestedObject") + .transform(fromBean, toBean); +~~~ + +where `nestedObject` is the name of the field in the destination object. + +This feature allows to **transform an object keeping the data from different sources**. + +To better explain this function let's assume that the `ToBean` (defined above) should be transformed as follow: +- `name` field value has be taken from the `FromBean` object +- `nestedObject` field value has be taken from the `FromBean2` object + +the objective can be reached by doing: +~~~Java +// create the destination object +ToBean toBean = new ToBean(); + +// execute the first transformation skipping the copy of: 'nestedObject' field that should come from the other source object +beanUtils.getTransformer() + .skipTransformationForField("nestedObject") + .transform(fromBean, toBean); + +// then execute the transformation skipping the copy of: 'name' field that should come from the other source object +beanUtils.getTransformer() + .skipTransformationForField("name") + .transform(fromBean2, toBean); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` \ No newline at end of file From 6c62e2925c1c4e3e6b8dadf173e112fe4534caf4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 15:47:41 +0100 Subject: [PATCH 0328/1786] Centralized method `getDeclaredField` --- .../com/hotels/beans/populator/Populator.java | 2 +- .../beans/transformer/TransformerImpl.java | 2 +- .../com/hotels/beans/utils/ClassUtils.java | 30 ------------------- .../hotels/beans/utils/ReflectionUtils.java | 7 ++--- .../hotels/beans/utils/ClassUtilsTest.java | 15 ---------- 5 files changed, 5 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/hotels/beans/populator/Populator.java b/src/main/java/com/hotels/beans/populator/Populator.java index ab5006c3d..a0eee190b 100644 --- a/src/main/java/com/hotels/beans/populator/Populator.java +++ b/src/main/java/com/hotels/beans/populator/Populator.java @@ -72,7 +72,7 @@ public abstract class Populator { * @return a populated list of elements */ public final O getPopulatedObject(final Class targetClass, final String fieldName, final O fieldValue) { - return getPopulatedObject(classUtils.getDeclaredField(targetClass, fieldName), fieldValue); + return getPopulatedObject(reflectionUtils.getDeclaredField(fieldName, targetClass), fieldValue); } /** diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index bd76ef193..7d3dc57b8 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -172,7 +172,7 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< } else { String sourceFieldName = getSourceFieldName(destFieldName); constructorArgsValues[i] = - ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, classUtils.getDeclaredField(targetClass, destFieldName), breadcrumb)) + ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, reflectionUtils.getDeclaredField(destFieldName, targetClass), breadcrumb)) .orElse(classUtils.getDefaultTypeValue(constructorParameters[i].getType())); } }); diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index b1ac4ff42..f973b8cbe 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -58,7 +58,6 @@ import com.hotels.beans.cache.CacheManager; import com.hotels.beans.constant.ClassType; import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.error.MissingFieldException; /** * Reflection utils for Class objects. @@ -338,35 +337,6 @@ private Field[] getDeclaredFields(final Class clazz) { }); } - /** - * Returns the class field. - * @param targetClass the class containing the field. - * @param fieldName the field name - * @param the object type - * @return the class or superclass field - * @throws IllegalArgumentException {@link IllegalArgumentException} if the target class doesn't have such field - */ - public Field getDeclaredField(final Class targetClass, final String fieldName) { - final String cacheKey = "ClassDeclaredField-" + targetClass.getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { - Field field; - try { - field = targetClass.getDeclaredField(fieldName); - } catch (final NoSuchFieldException e) { - if (nonNull(targetClass.getSuperclass()) && !targetClass.getSuperclass().equals(Object.class)) { - field = getDeclaredField(targetClass.getSuperclass(), fieldName); - } else { - throw new MissingFieldException( - "The field " + fieldName + " not exists in class: + " + targetClass.getCanonicalName() - + ". If the field in the source object has a different name please specify the " - + "transformation mapping."); - } - } - cacheManager.cacheObject(cacheKey, field); - return field; - }); - } - /** * Checks if the destination class has accessible constructor. * @param targetClass the destination object class diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index c5cffe81e..708be698c 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -223,7 +223,7 @@ private Object getFieldValue(final Object target, final String fieldName) { boolean isAccessible = true; Field field = null; try { - field = getDeclaredField(fieldName, target); + field = getDeclaredField(fieldName, target.getClass()); isAccessible = isFieldAccessible(field, target); if (!isAccessible) { field.setAccessible(true); @@ -244,12 +244,11 @@ private Object getFieldValue(final Object target, final String fieldName) { /** * Return the field of the given class. * @param fieldName the name of the filed to retrieve. - * @param target the field's class + * @param targetClass the field's class * @return the field corresponding to the given name. */ - private Field getDeclaredField(final String fieldName, final Object target) { + public Field getDeclaredField(final String fieldName, final Class targetClass) { Field field; - Class targetClass = target instanceof Class ? (Class) target : target.getClass(); try { field = targetClass.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 3ca8694ae..dae9f31e3 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -355,21 +355,6 @@ private Object[][] dataGetDeclaredFieldsTesting() { }; } - /** - * Tests that the method {@code getDeclaredFields} returns the expected field. - */ - @Test - public void testGetDeclaredFieldReturnsTheExpectedField() { - // GIVEN - - // WHEN - Field actual = underTest.getDeclaredField(CLASS_WITH_STATIC_FIELDS, NORMAL_FIELD); - - // THEN - assertNotNull(actual); - assertEquals(NORMAL_FIELD, actual.getName()); - } - /** * Tests that the method {@code getAllArgsConstructor} returns the class constructor. */ From 290d1caacc6a59add8e0e0d0ba627b7196e45c5d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 17:04:04 +0100 Subject: [PATCH 0329/1786] Commented out declaredFieldCaching --- src/main/java/com/hotels/beans/utils/ReflectionUtils.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 708be698c..60f290b0e 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -248,6 +248,8 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { +// final String cacheKey = "ClassDeclaredField-" + targetClass.getCanonicalName() + '-' + fieldName; +// return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { Field field; try { field = targetClass.getDeclaredField(fieldName); @@ -261,7 +263,9 @@ public Field getDeclaredField(final String fieldName, final Class targetClass handleReflectionException(e); throw new IllegalStateException(e); } +// cacheManager.cacheObject(cacheKey, field); return field; +// }); } /** From e5a10f0dd268f4c8dfdb920146812f28a8f5819d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 17:05:04 +0100 Subject: [PATCH 0330/1786] minor: removed commented code --- src/main/java/com/hotels/beans/utils/ReflectionUtils.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 60f290b0e..708be698c 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -248,8 +248,6 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { -// final String cacheKey = "ClassDeclaredField-" + targetClass.getCanonicalName() + '-' + fieldName; -// return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { Field field; try { field = targetClass.getDeclaredField(fieldName); @@ -263,9 +261,7 @@ public Field getDeclaredField(final String fieldName, final Class targetClass handleReflectionException(e); throw new IllegalStateException(e); } -// cacheManager.cacheObject(cacheKey, field); return field; -// }); } /** From d6b7f0bd02eb9b123a02784be7d55dbfd7ed6164 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:03:15 +0100 Subject: [PATCH 0331/1786] releasing new features for java 1.8 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 81b737ca2..2232463fd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.3-SNAPSHOT + 1.1.8-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 From 9495efdb5f3757be0047dceee1d4482ea839d441 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:04:43 +0100 Subject: [PATCH 0332/1786] [maven-release-plugin] prepare release 1.1.8 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2232463fd..1fd1d69e0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.8-SNAPSHOT + 1.1.8 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.8 From 0a1e5f3ad1be4cb7912d7ea90b667f4526a91483 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:04:51 +0100 Subject: [PATCH 0333/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1fd1d69e0..94af39c28 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.8 + 1.1.9-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.8 + HEAD From 5c31048f7e1d26c983f64db9de3e4c21fd58194d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:09:08 +0100 Subject: [PATCH 0334/1786] prepared java 11 release --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 94af39c28..81b737ca2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.9-SNAPSHOT + 1.2.3-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 From 67a2a0ee2578ab479c7b65fd4223e968a3ebb7b2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:13:54 +0100 Subject: [PATCH 0335/1786] removed parallel test execution --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 81b737ca2..3f28ed12c 100644 --- a/pom.xml +++ b/pom.xml @@ -280,7 +280,7 @@ maven-surefire-plugin ${maven.surefire.plugin.version} - true + false From df45409b417e68b057217031a280487fea6ac907 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:17:12 +0100 Subject: [PATCH 0336/1786] used openjdk for build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bc67ca831..4af06089a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -jdk: oraclejdk11 +jdk: openjdk11 env: global: # Sonatype jira info From 52730ffe236d020c4a930f2c60697e54c091f39d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:20:52 +0100 Subject: [PATCH 0337/1786] added field caching --- .travis.yml | 2 +- .../hotels/beans/utils/ReflectionUtils.java | 28 +++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4af06089a..bc67ca831 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -jdk: openjdk11 +jdk: oraclejdk11 env: global: # Sonatype jira info diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 708be698c..59ec0c797 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -248,20 +248,24 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { + final String cacheKey = "ClassDeclaredField-" + targetClass.getCanonicalName() + '-' + fieldName; + return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { Field field; - try { - field = targetClass.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - if (!targetClass.getSuperclass().equals(Object.class)) { - field = getDeclaredField(fieldName, targetClass.getSuperclass()); - } else { - throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); + try { + field = targetClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + if (!targetClass.getSuperclass().equals(Object.class)) { + field = getDeclaredField(fieldName, targetClass.getSuperclass()); + } else { + throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); + } + } catch (final Exception e) { + handleReflectionException(e); + throw new IllegalStateException(e); } - } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); - } - return field; + cacheManager.cacheObject(cacheKey, field); + return field; + }); } /** From 1db9ce0389c052f1a03693fbb5b47a0912f98544 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:27:12 +0100 Subject: [PATCH 0338/1786] [maven-release-plugin] prepare release 1.2.3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3f28ed12c..55ed15c7e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.3-SNAPSHOT + 1.2.3 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.3 From 2f9f26db1ec3f0745dd1b783dce33693495d8016 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:27:21 +0100 Subject: [PATCH 0339/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 55ed15c7e..149a9b5c7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.3 + 1.2.4-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.3 + HEAD From 51dbe524c8bdafe689bb699b90e4797e251c85e2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:40:29 +0100 Subject: [PATCH 0340/1786] removed cache on declaredField mathod --- pom.xml | 2 +- .../hotels/beans/utils/ReflectionUtils.java | 28 ++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 149a9b5c7..3f28ed12c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.4-SNAPSHOT + 1.2.3-SNAPSHOT jar 2019 diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 59ec0c797..708be698c 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -248,24 +248,20 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { - final String cacheKey = "ClassDeclaredField-" + targetClass.getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { Field field; - try { - field = targetClass.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - if (!targetClass.getSuperclass().equals(Object.class)) { - field = getDeclaredField(fieldName, targetClass.getSuperclass()); - } else { - throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); - } - } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); + try { + field = targetClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + if (!targetClass.getSuperclass().equals(Object.class)) { + field = getDeclaredField(fieldName, targetClass.getSuperclass()); + } else { + throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); } - cacheManager.cacheObject(cacheKey, field); - return field; - }); + } catch (final Exception e) { + handleReflectionException(e); + throw new IllegalStateException(e); + } + return field; } /** From 35a542b6c5d657119c360264e8fa950336819155 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:42:04 +0100 Subject: [PATCH 0341/1786] [maven-release-plugin] prepare release 1.2.3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3f28ed12c..55ed15c7e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.3-SNAPSHOT + 1.2.3 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.3 From eb6737e7962697f9e1291357472a61bdbd8c4775 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:42:15 +0100 Subject: [PATCH 0342/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 55ed15c7e..149a9b5c7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.3 + 1.2.4-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.3 + HEAD From 99f69dd57d5d5489edaed7056e46bf6d75573d66 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:46:11 +0100 Subject: [PATCH 0343/1786] revert adding cache --- pom.xml | 2 +- .../hotels/beans/utils/ReflectionUtils.java | 28 +++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 149a9b5c7..3f28ed12c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.4-SNAPSHOT + 1.2.3-SNAPSHOT jar 2019 diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 708be698c..59ec0c797 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -248,20 +248,24 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { + final String cacheKey = "ClassDeclaredField-" + targetClass.getCanonicalName() + '-' + fieldName; + return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { Field field; - try { - field = targetClass.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - if (!targetClass.getSuperclass().equals(Object.class)) { - field = getDeclaredField(fieldName, targetClass.getSuperclass()); - } else { - throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); + try { + field = targetClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + if (!targetClass.getSuperclass().equals(Object.class)) { + field = getDeclaredField(fieldName, targetClass.getSuperclass()); + } else { + throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); + } + } catch (final Exception e) { + handleReflectionException(e); + throw new IllegalStateException(e); } - } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); - } - return field; + cacheManager.cacheObject(cacheKey, field); + return field; + }); } /** From afe2de032f195cfd497d0c25de3721687934392e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:48:05 +0100 Subject: [PATCH 0344/1786] [maven-release-plugin] prepare release 1.2.3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3f28ed12c..55ed15c7e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.3-SNAPSHOT + 1.2.3 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.3 From 77e1167f17fad8caffeff24839acc7f9ad7caf8d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:48:14 +0100 Subject: [PATCH 0345/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 55ed15c7e..149a9b5c7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.3 + 1.2.4-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.3 + HEAD From 1b247fe5f2ebe831c2d4f0536f63734966087ba5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:53:46 +0100 Subject: [PATCH 0346/1786] remove caching as not needed on a specific method --- pom.xml | 2 +- .../hotels/beans/utils/ReflectionUtils.java | 28 ++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 149a9b5c7..3f28ed12c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.4-SNAPSHOT + 1.2.3-SNAPSHOT jar 2019 diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 59ec0c797..708be698c 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -248,24 +248,20 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { - final String cacheKey = "ClassDeclaredField-" + targetClass.getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { Field field; - try { - field = targetClass.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - if (!targetClass.getSuperclass().equals(Object.class)) { - field = getDeclaredField(fieldName, targetClass.getSuperclass()); - } else { - throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); - } - } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); + try { + field = targetClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + if (!targetClass.getSuperclass().equals(Object.class)) { + field = getDeclaredField(fieldName, targetClass.getSuperclass()); + } else { + throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); } - cacheManager.cacheObject(cacheKey, field); - return field; - }); + } catch (final Exception e) { + handleReflectionException(e); + throw new IllegalStateException(e); + } + return field; } /** From 998beeac54a94eb215cc652c76da8ffa69f3586c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:54:47 +0100 Subject: [PATCH 0347/1786] [maven-release-plugin] prepare release 1.2.3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3f28ed12c..55ed15c7e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.3-SNAPSHOT + 1.2.3 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.3 From b412a78e6e3cdfd875ad470326e1f83d16d45546 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 21 Mar 2019 21:54:55 +0100 Subject: [PATCH 0348/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 55ed15c7e..149a9b5c7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.3 + 1.2.4-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.3 + HEAD From fa98f31863d03c68e6900f5ccdeb35edbfe37b74 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Mar 2019 07:56:00 +0100 Subject: [PATCH 0349/1786] Cached declared field method --- .../hotels/beans/utils/ReflectionUtils.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 708be698c..5ff5ab6a2 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -248,20 +248,24 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { - Field field; - try { - field = targetClass.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - if (!targetClass.getSuperclass().equals(Object.class)) { - field = getDeclaredField(fieldName, targetClass.getSuperclass()); - } else { - throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); + final String cacheKey = "getDeclaredField-" + targetClass.getName() + "-" + fieldName; + return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { + Field field; + try { + field = targetClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + if (!targetClass.getSuperclass().equals(Object.class)) { + field = getDeclaredField(fieldName, targetClass.getSuperclass()); + } else { + throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); + } + } catch (final Exception e) { + handleReflectionException(e); + throw new IllegalStateException(e); } - } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); - } - return field; + cacheManager.cacheObject(cacheKey, field); + return field; + }); } /** From 428b7b0ec36ecaab1c5a4f1e0728844d009eb6da Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Mar 2019 15:26:23 +0100 Subject: [PATCH 0350/1786] updated change log with the latest updates --- CHANGELOG.md | 10 ++++++++++ pom.xml | 4 ++-- .../java/com/hotels/beans/utils/ReflectionUtils.java | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 139f2d45a..416dba408 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.2.4] 2019.03.23 +#### Changed +* Updated `spring-boot-starter-test` version to `2.1.3.RELEASE` (was `2.1.2.RELEASE`). +* Added caching for method: `getDeclaredField` + ### [1.2.3] 2019.03.22 #### Added * Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/HotelsDotCom/bull/issues/38)) @@ -25,6 +30,11 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.9] 2019.03.23 +#### Changed +* Updated `spring-boot-starter-test` version to `2.1.3.RELEASE` (was `2.1.2.RELEASE`). +* Added caching for method: `getDeclaredField` + ### [1.1.8] 2019.03.22 #### Added * Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/HotelsDotCom/bull/issues/38)) diff --git a/pom.xml b/pom.xml index 149a9b5c7..9244612a8 100644 --- a/pom.xml +++ b/pom.xml @@ -22,11 +22,11 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 - 2.1.2.RELEASE + 2.1.3.RELEASE 1.18.4 3.8.1 0.11 diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 5ff5ab6a2..63ca3a47d 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -248,7 +248,7 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { - final String cacheKey = "getDeclaredField-" + targetClass.getName() + "-" + fieldName; + final String cacheKey = "ClassDeclaredField-" + targetClass.getName() + "-" + fieldName; return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { Field field; try { From fedd2283a77e038825d9c89b8942aa74554eb992 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Mar 2019 15:27:01 +0100 Subject: [PATCH 0351/1786] updated version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9244612a8..026db5662 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.4-SNAPSHOT + 1.1.9-SNAPSHOT jar 2019 From 4885310de7416e69b3f3f957fb9839c4c593f1f3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Mar 2019 15:28:39 +0100 Subject: [PATCH 0352/1786] [maven-release-plugin] prepare release 1.1.9 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 026db5662..f05426f05 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.9-SNAPSHOT + 1.1.9 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.9 From 311479633cf05a1a0862097c5e9e09a146ab91ef Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Mar 2019 15:28:47 +0100 Subject: [PATCH 0353/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f05426f05..c05f8b89f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.9 + 1.1.10-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.9 + HEAD From aac90040bbd20248f00694cfc54a04754aea378c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Mar 2019 15:32:25 +0100 Subject: [PATCH 0354/1786] preparing release for java 11 version --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c05f8b89f..3e7b74785 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.10-SNAPSHOT + 1.2.4-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 From a503085f3ce1e0e0bbeab028d777c083f7104a17 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Mar 2019 15:44:44 +0100 Subject: [PATCH 0355/1786] [maven-release-plugin] prepare release 1.2.4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3e7b74785..21ce199c8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.4-SNAPSHOT + 1.2.4 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.4 From 5aa0d52e66cbde112de5d777cf504ca1976a55e1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Mar 2019 15:44:52 +0100 Subject: [PATCH 0356/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 21ce199c8..3263a1cdc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.4 + 1.2.5-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.4 + HEAD From ff6b70f7a6d24ab60f245544aa1e1cfb342dc5d8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 31 Mar 2019 15:18:23 +0200 Subject: [PATCH 0357/1786] Improved field value retrieval function in order to avoid execution of not needed functions. --- CHANGELOG.md | 8 +++++++ .../beans/transformer/TransformerImpl.java | 22 +++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 416dba408..e32befb21 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.2.5] 2019.03.31 +#### Added +* Improved field value retrieval function. + ### [1.2.4] 2019.03.23 #### Changed * Updated `spring-boot-starter-test` version to `2.1.3.RELEASE` (was `2.1.2.RELEASE`). @@ -30,6 +34,10 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.2.10] 2019.03.31 +#### Added +* Improved field value retrieval function. + ### [1.1.9] 2019.03.23 #### Changed * Updated `spring-boot-starter-test` version to `2.1.3.RELEASE` (was `2.1.2.RELEASE`). diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 7d3dc57b8..39527b49d 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -350,15 +350,19 @@ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { */ private Object getSourceFieldValue(final T sourceObj, final String sourceFieldName, final Field field, final boolean isFieldTransformerDefined) { Object fieldValue = null; - try { - fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); - } catch (MissingFieldException e) { - if (!isFieldTransformerDefined && !settings.isSetDefaultValue()) { - throw e; - } - } catch (Exception e) { - if (!isFieldTransformerDefined) { - throw e; + if (classUtils.isPrimitiveType(sourceObj.getClass())) { + fieldValue = sourceObj; + } else { + try { + fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); + } catch (MissingFieldException e) { + if (!isFieldTransformerDefined && !settings.isSetDefaultValue()) { + throw e; + } + } catch (Exception e) { + if (!isFieldTransformerDefined) { + throw e; + } } } return fieldValue; From dfccbbf36b5ade040156cd46a0c91948c6873485 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 31 Mar 2019 15:22:28 +0200 Subject: [PATCH 0358/1786] prepared bull release for jdk 1.8 --- CHANGELOG.md | 2 +- pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e32befb21..da9344ff3 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,7 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created -### [1.2.10] 2019.03.31 +### [1.1.10] 2019.03.31 #### Added * Improved field value retrieval function. diff --git a/pom.xml b/pom.xml index 3263a1cdc..c05f8b89f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.5-SNAPSHOT + 1.1.10-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 From e2f8c8f1f3dbe8ac38bacfd031c05574bf859c0c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 31 Mar 2019 15:23:16 +0200 Subject: [PATCH 0359/1786] [maven-release-plugin] prepare release 1.1.10 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c05f8b89f..da7bdc5dc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.10-SNAPSHOT + 1.1.10 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.10 From 985aba9e4a6937f531b9bab73280d930ca3277c4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 31 Mar 2019 15:23:24 +0200 Subject: [PATCH 0360/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index da7bdc5dc..fb326eac2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.10 + 1.1.11-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.10 + HEAD From f96c876c88a70f954095c1514912c3998ecf36e4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 31 Mar 2019 15:26:17 +0200 Subject: [PATCH 0361/1786] preparing release for jdk 11 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index fb326eac2..3263a1cdc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.11-SNAPSHOT + 1.2.5-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 From a008eec04cebc27756b0ff8a6c356245587819af Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 31 Mar 2019 15:34:13 +0200 Subject: [PATCH 0362/1786] [maven-release-plugin] prepare release 1.2.5 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3263a1cdc..5ced80e6a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.5-SNAPSHOT + 1.2.5 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.5 From 70258dc651d753a5bc6fd78cc2d4186ffbc6ad94 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 31 Mar 2019 15:34:20 +0200 Subject: [PATCH 0363/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5ced80e6a..dfca7519c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.5 + 1.2.6-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.5 + HEAD From 3b701ce6b03d46e27e5eb244ff415c1f40f8f466 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 1 Apr 2019 12:01:02 +0200 Subject: [PATCH 0364/1786] - Implemented possibility to use static transformation with a given transformer. - Added new service documentation - Added additional test cases - updated changelog with the new feature --- CHANGELOG.md | 8 +++++++ README.md | 9 +++++++- docs/site/markdown/transformer/samples.md | 9 +++++++- src/main/java/com/hotels/beans/BeanUtils.java | 14 +++++++++++ .../java/com/hotels/beans/BeanUtilsTest.java | 23 ++++++++++++++++--- 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da9344ff3..5c4adc536 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.2.6] TBD +#### Added +* Implemented possibility to use static transformation with a given transformer. + ### [1.2.5] 2019.03.31 #### Added * Improved field value retrieval function. @@ -34,6 +38,10 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.11] TBD +#### Added +* Implemented possibility to use static transformation with a given transformer. + ### [1.1.10] 2019.03.31 #### Added * Improved field value retrieval function. diff --git a/README.md b/README.md index b07a4e062..f4c991cb0 100644 --- a/README.md +++ b/README.md @@ -333,7 +333,14 @@ List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimp can be transformed as follow: ~~~Java Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); - List actual = fromFooSimpleList.stream() +List actual = fromFooSimpleList.stream() + .map(transformerFunction) + .collect(Collectors.toList()); +~~~ +or if you have a pre-configured transformer: +~~~Java +Function transformerFunction = BeanUtils.getTransformer(, ImmutableToFooSimple.class); +List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); ~~~ diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 46cb6c95c..ce045ba15 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -276,7 +276,14 @@ List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimp can be transformed as follow: ~~~Java Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); - List actual = fromFooSimpleList.stream() +List actual = fromFooSimpleList.stream() + .map(transformerFunction) + .collect(Collectors.toList()); +~~~ +or if you have a pre-configured transformer: +~~~Java +Function transformerFunction = BeanUtils.getTransformer(, ImmutableToFooSimple.class); +List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); ~~~ diff --git a/src/main/java/com/hotels/beans/BeanUtils.java b/src/main/java/com/hotels/beans/BeanUtils.java index b7aaadeae..10d075f09 100644 --- a/src/main/java/com/hotels/beans/BeanUtils.java +++ b/src/main/java/com/hotels/beans/BeanUtils.java @@ -38,6 +38,20 @@ public static Function getTransformer(final Class targetClass) { return fromBean -> new TransformerImpl().transform(fromBean, targetClass); } + /** + * Returns a function that transforms an object T in an object K. + * @param beanTransformer the transformer to be used. + * @param targetClass the destination object class + * @param the Source object type + * @param the target object type + * @return a function that copies of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + public static Function getTransformer(final Transformer beanTransformer, final Class targetClass) { + return fromBean -> beanTransformer.transform(fromBean, targetClass); + } + + /** * Returns a Bean Transformer. * @return a Bean Transformer instance. diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/src/test/java/com/hotels/beans/BeanUtilsTest.java index 020c80ea2..fcb75162b 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -31,6 +31,7 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.hotels.beans.sample.FromFooSimple; @@ -74,15 +75,16 @@ public void testGetTransformerWorksProperly() { /** * Test that the transformer function returned is able to transform the given object. + * @param testCaseDescription the test case description + * @param transformerFunction the transform function to use */ - @Test - public void testGetTransformerFunctionWorksProperly() { + @Test(dataProvider = "dataStaticTransformationTesting") + public void testGetTransformerFunctionWorksProperly(final String testCaseDescription, final Function transformerFunction) { //GIVEN FromFooSimple fromFooSimple = createFromFooSimple(); List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimple); //WHEN - Function transformerFunction = underTest.getTransformer(ImmutableToFooSimple.class); List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); @@ -93,6 +95,21 @@ public void testGetTransformerFunctionWorksProperly() { .forEach(i -> assertThat(actual.get(i), sameBeanAs(fromFooSimpleList.get(i)))); } + /** + * Creates the parameters to be used for testing the default transformation operations. + * @return parameters to be used for testing the default transformation operations. + */ + @DataProvider(parallel = true) + private Object[][] dataStaticTransformationTesting() { + BeanUtils beanUtils = new BeanUtils(); + return new Object[][] { + {"Test that the transformer function returned is able to transform the given object.", + beanUtils.getTransformer(ImmutableToFooSimple.class)}, + {"Test that the transformer function returned is able to transform the given object with the given transformer.", + beanUtils.getTransformer(beanUtils.getTransformer(), ImmutableToFooSimple.class)} + }; + } + /** * Creates a {@link FromFooSimple} instance. * @return the {@link FromFooSimple} instance. From 2a90ab8fd43d17d0d95dfd29588b9ab2442c2a78 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 1 Apr 2019 12:05:59 +0200 Subject: [PATCH 0365/1786] updated travis configuration in order to skip the test execution after the deploy --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index bc67ca831..035c570d3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ jobs: name: "Releasing artifacts" if: type NOT IN (pull_request) AND tag IS present install: skip + after_deploy: false before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} From 9d788cbec5e8b05b991ee4df3acf379f0ea7fa21 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 1 Apr 2019 17:30:04 +0200 Subject: [PATCH 0366/1786] - Linked change log to the related issue --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c4adc536..7d1f10de8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.2.6] TBD #### Added -* Implemented possibility to use static transformation with a given transformer. +* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). ### [1.2.5] 2019.03.31 #### Added @@ -40,7 +40,7 @@ All notable changes to this project will be documented in this file. ### [1.1.11] TBD #### Added -* Implemented possibility to use static transformation with a given transformer. +* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). ### [1.1.10] 2019.03.31 #### Added From ad9e332b4cf33875ac9d1cc49b3789f55fdf2e27 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 2 Apr 2019 23:50:01 +0200 Subject: [PATCH 0367/1786] - Removed not needed exception catch - Added test case --- pom.xml | 2 +- src/main/java/com/hotels/beans/utils/ReflectionUtils.java | 2 +- .../com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index dfca7519c..06eec6729 100644 --- a/pom.xml +++ b/pom.xml @@ -147,7 +147,7 @@ false true false - false + true false diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 63ca3a47d..0ecfb75b6 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -92,7 +92,7 @@ private Object invokeMethod(final Method method, final Object target, final Obje notNull(target, "target cannot be null!"); try { return method.invoke(target, args); - } catch (MissingFieldException | MissingMethodException e) { + } catch (MissingMethodException e) { throw e; } catch (final Exception e) { handleReflectionException(e); diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java index 3e0e87a8d..97716c4b5 100644 --- a/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java @@ -32,7 +32,7 @@ @Getter @ToString public class ImmutableFlatToFoo { - private final String name; + public final String name; private final BigInteger id; private final int[] phoneNumbers; From ca39eb300026b88f4f79e32c0782c4e3ed92e568 Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Thu, 4 Apr 2019 08:49:50 +0000 Subject: [PATCH 0368/1786] Add Gitter badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b07a4e062..20f24dc06 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) -[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) [![Join the chat at https://gitter.im/bean-utils-light-library/community](https://badges.gitter.im/bean-utils-light-library/community.svg)](https://gitter.im/bean-utils-light-library/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) You can obtain BULL from Maven Central: From a775937f4c4c1e61b7fef4890df488bf0e915087 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 4 Apr 2019 17:19:39 +0200 Subject: [PATCH 0369/1786] Integrated Gitter notification and link into readme file --- .travis.yml | 14 +++++++++++--- README.md | 3 ++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 035c570d3..4f94805da 100755 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ jobs: - stage: "Build" name: "Build and Test" if: NOT branch = master - install: travis_retry mvn clean install -DskipTests -Dmaven.javadoc.skip=true -B + install: travis_retry mvn clean install -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -B # If the branch is master it sends the quality report to SonarCloud - stage: "Build and Quality Check" name: "Building, testing and performing quality check" @@ -30,7 +30,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install site:site -DskipTests=true -B + - travis_retry mvn install site:site -Dmaven.test.skip=true -B deploy: provider: pages local-dir: target/site @@ -52,4 +52,12 @@ jobs: script: config/travis/deploy.sh skip_cleanup: true on: - tags: true \ No newline at end of file + tags: true +# Gitter notification +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/${gitter_webhook_id} + on_success: change # options: [always|never|change] default: always + on_failure: never # options: [always|never|change] default: always + on_start: never # options: [always|never|change] default: always diff --git a/README.md b/README.md index f4c991cb0..bf938265d 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,12 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bean-utils-library.svg)](http://www.javadoc.io/doc/com.hotels.beans/bean-utils-library) -[![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) +[![Gitter](https://badges.gitter.im/bean-utils-light-library/community.svg)](https://gitter.im/bean-utils-light-library/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) +[![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) You can obtain BULL from Maven Central: From 86aceca8edc7e4cdbf2340758abcf44c40d3e709 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 4 Apr 2019 17:22:20 +0200 Subject: [PATCH 0370/1786] Testing after_success skip --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4f94805da..1ca3b43b4 100755 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ jobs: name: "Build and Test" if: NOT branch = master install: travis_retry mvn clean install -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -B + after_success: false # If the branch is master it sends the quality report to SonarCloud - stage: "Build and Quality Check" name: "Building, testing and performing quality check" From da6a91de7c1bd360d95ec50a4f6980b2e43be302 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 4 Apr 2019 17:47:06 +0200 Subject: [PATCH 0371/1786] testing travis test skip --- .travis.yml | 6 ++--- CHANGELOG.md | 12 ++++------ README.md | 9 +------- docs/site/markdown/transformer/samples.md | 9 +------- pom.xml | 2 +- src/main/java/com/hotels/beans/BeanUtils.java | 14 ----------- .../hotels/beans/utils/ReflectionUtils.java | 2 +- .../java/com/hotels/beans/BeanUtilsTest.java | 23 +++---------------- .../sample/immutable/ImmutableFlatToFoo.java | 2 +- 9 files changed, 15 insertions(+), 64 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1ca3b43b4..a93f95e57 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -install: skip +install: ignore jobs: include: # If the branch is not master it just builds the application @@ -20,7 +20,6 @@ jobs: name: "Build and Test" if: NOT branch = master install: travis_retry mvn clean install -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -B - after_success: false # If the branch is master it sends the quality report to SonarCloud - stage: "Build and Quality Check" name: "Building, testing and performing quality check" @@ -59,6 +58,7 @@ notifications: webhooks: urls: - https://webhooks.gitter.im/e/${gitter_webhook_id} - on_success: change # options: [always|never|change] default: always + on_success: always # options: [always|never|change] default: always on_failure: never # options: [always|never|change] default: always on_start: never # options: [always|never|change] default: always + diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d1f10de8..ff8e1f5e1 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,11 @@ All notable changes to this project will be documented in this file. -### [1.2.6] TBD -#### Added -* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). - ### [1.2.5] 2019.03.31 #### Added * Improved field value retrieval function. +* Added ling to Gitter channel for BULL. +* Integrated Gitter notification in order to keep up to date BULL community ### [1.2.4] 2019.03.23 #### Changed @@ -38,13 +36,11 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created -### [1.1.11] TBD -#### Added -* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). - ### [1.1.10] 2019.03.31 #### Added * Improved field value retrieval function. +* Added ling to Gitter channel for BULL. +* Integrated Gitter notification in order to keep up to date BULL community ### [1.1.9] 2019.03.23 #### Changed diff --git a/README.md b/README.md index bf938265d..8685e32aa 100644 --- a/README.md +++ b/README.md @@ -334,14 +334,7 @@ List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimp can be transformed as follow: ~~~Java Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); -List actual = fromFooSimpleList.stream() - .map(transformerFunction) - .collect(Collectors.toList()); -~~~ -or if you have a pre-configured transformer: -~~~Java -Function transformerFunction = BeanUtils.getTransformer(, ImmutableToFooSimple.class); -List actual = fromFooSimpleList.stream() + List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); ~~~ diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index ce045ba15..46cb6c95c 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -276,14 +276,7 @@ List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimp can be transformed as follow: ~~~Java Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); -List actual = fromFooSimpleList.stream() - .map(transformerFunction) - .collect(Collectors.toList()); -~~~ -or if you have a pre-configured transformer: -~~~Java -Function transformerFunction = BeanUtils.getTransformer(, ImmutableToFooSimple.class); -List actual = fromFooSimpleList.stream() + List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); ~~~ diff --git a/pom.xml b/pom.xml index 06eec6729..dfca7519c 100644 --- a/pom.xml +++ b/pom.xml @@ -147,7 +147,7 @@ false true false - true + false false diff --git a/src/main/java/com/hotels/beans/BeanUtils.java b/src/main/java/com/hotels/beans/BeanUtils.java index 10d075f09..b7aaadeae 100644 --- a/src/main/java/com/hotels/beans/BeanUtils.java +++ b/src/main/java/com/hotels/beans/BeanUtils.java @@ -38,20 +38,6 @@ public static Function getTransformer(final Class targetClass) { return fromBean -> new TransformerImpl().transform(fromBean, targetClass); } - /** - * Returns a function that transforms an object T in an object K. - * @param beanTransformer the transformer to be used. - * @param targetClass the destination object class - * @param the Source object type - * @param the target object type - * @return a function that copies of the source object into the destination object - * @throws IllegalArgumentException if any parameter is invalid - */ - public static Function getTransformer(final Transformer beanTransformer, final Class targetClass) { - return fromBean -> beanTransformer.transform(fromBean, targetClass); - } - - /** * Returns a Bean Transformer. * @return a Bean Transformer instance. diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 0ecfb75b6..63ca3a47d 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -92,7 +92,7 @@ private Object invokeMethod(final Method method, final Object target, final Obje notNull(target, "target cannot be null!"); try { return method.invoke(target, args); - } catch (MissingMethodException e) { + } catch (MissingFieldException | MissingMethodException e) { throw e; } catch (final Exception e) { handleReflectionException(e); diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/src/test/java/com/hotels/beans/BeanUtilsTest.java index fcb75162b..020c80ea2 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -31,7 +31,6 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; -import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.hotels.beans.sample.FromFooSimple; @@ -75,16 +74,15 @@ public void testGetTransformerWorksProperly() { /** * Test that the transformer function returned is able to transform the given object. - * @param testCaseDescription the test case description - * @param transformerFunction the transform function to use */ - @Test(dataProvider = "dataStaticTransformationTesting") - public void testGetTransformerFunctionWorksProperly(final String testCaseDescription, final Function transformerFunction) { + @Test + public void testGetTransformerFunctionWorksProperly() { //GIVEN FromFooSimple fromFooSimple = createFromFooSimple(); List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimple); //WHEN + Function transformerFunction = underTest.getTransformer(ImmutableToFooSimple.class); List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); @@ -95,21 +93,6 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip .forEach(i -> assertThat(actual.get(i), sameBeanAs(fromFooSimpleList.get(i)))); } - /** - * Creates the parameters to be used for testing the default transformation operations. - * @return parameters to be used for testing the default transformation operations. - */ - @DataProvider(parallel = true) - private Object[][] dataStaticTransformationTesting() { - BeanUtils beanUtils = new BeanUtils(); - return new Object[][] { - {"Test that the transformer function returned is able to transform the given object.", - beanUtils.getTransformer(ImmutableToFooSimple.class)}, - {"Test that the transformer function returned is able to transform the given object with the given transformer.", - beanUtils.getTransformer(beanUtils.getTransformer(), ImmutableToFooSimple.class)} - }; - } - /** * Creates a {@link FromFooSimple} instance. * @return the {@link FromFooSimple} instance. diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java index 97716c4b5..3e0e87a8d 100644 --- a/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java @@ -32,7 +32,7 @@ @Getter @ToString public class ImmutableFlatToFoo { - public final String name; + private final String name; private final BigInteger id; private final int[] phoneNumbers; From aa55ce3d160f6632a2619cd992252157624df180 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 4 Apr 2019 17:50:31 +0200 Subject: [PATCH 0372/1786] Removed not needed travis settings --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a93f95e57..b55f76bd0 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -install: ignore +install: skip jobs: include: # If the branch is not master it just builds the application @@ -43,7 +43,7 @@ jobs: name: "Releasing artifacts" if: type NOT IN (pull_request) AND tag IS present install: skip - after_deploy: false + after_deploy: skip before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} From 7941d331b33442a25daf44f9cd61f7cc0a66b63e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 4 Apr 2019 17:59:34 +0200 Subject: [PATCH 0373/1786] moved gitter link up in the readme file --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8685e32aa..a75fda4aa 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bean-utils-library.svg)](http://www.javadoc.io/doc/com.hotels.beans/bean-utils-library) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) -[![Gitter](https://badges.gitter.im/bean-utils-light-library/community.svg)](https://gitter.im/bean-utils-light-library/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +[![Join the chat at https://gitter.im/bean-utils-light-library/community](https://badges.gitter.im/bean-utils-light-library/community.svg)](https://gitter.im/bean-utils-light-library/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) -[![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) You can obtain BULL from Maven Central: From 9422fe212ce36fa11fb41738bdf7daee3cf9ff5d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 4 Apr 2019 18:12:04 +0200 Subject: [PATCH 0374/1786] Testing build with jdk 12 --- .travis.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b55f76bd0..46af25ea1 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -jdk: oraclejdk11 +jdk: oraclejdk12 env: global: # Sonatype jira info diff --git a/README.md b/README.md index 8c31fb3c2..a75fda4aa 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) -[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) [![Join the chat at https://gitter.im/bean-utils-light-library/community](https://badges.gitter.im/bean-utils-light-library/community.svg)](https://gitter.im/bean-utils-light-library/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) You can obtain BULL from Maven Central: From d7236c9054a81c9421be6757d8ed78aa3eaabd8f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 4 Apr 2019 18:14:26 +0200 Subject: [PATCH 0375/1786] Restored jdk 11 as Travis does not support jdk 12 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 46af25ea1..b55f76bd0 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -jdk: oraclejdk12 +jdk: oraclejdk11 env: global: # Sonatype jira info From 360118ed74eebe345e98f6540ab68eaeabfa5305 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Apr 2019 08:47:07 +0200 Subject: [PATCH 0376/1786] Removed unneeded comment on travis config --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b55f76bd0..4ec112e6e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -53,7 +53,6 @@ jobs: skip_cleanup: true on: tags: true -# Gitter notification notifications: webhooks: urls: From bc687f284556367e7a2699313530764d469dde12 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:20:17 +0200 Subject: [PATCH 0377/1786] Prepared changelog for release --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff8e1f5e1..c6b1ba62e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.2.6] 2019.04.06 +#### Added +* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). + ### [1.2.5] 2019.03.31 #### Added * Improved field value retrieval function. @@ -36,6 +40,10 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.11] 2019.04.06 +#### Added +* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). + ### [1.1.10] 2019.03.31 #### Added * Improved field value retrieval function. From 6605293151b2c8cb34cd27d642e1de1778e998b8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:23:51 +0200 Subject: [PATCH 0378/1786] Removed pmd check --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dfca7519c..06eec6729 100644 --- a/pom.xml +++ b/pom.xml @@ -147,7 +147,7 @@ false true false - false + true false From b304332d6dd50eacf44a621d9d6194225560b268 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:25:11 +0200 Subject: [PATCH 0379/1786] Preparing release for jdk 1.8 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 06eec6729..5f23c5172 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.6-SNAPSHOT + 1.1.11-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 From d2f24d947304d95efd45480f4bcab5e10af38934 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:26:54 +0200 Subject: [PATCH 0380/1786] [maven-release-plugin] prepare release 1.1.11 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5f23c5172..2b7667322 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.11-SNAPSHOT + 1.1.11 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.11 From 51c2e56aafe3edea4fc0705de2a35cd16cf6a97f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:27:02 +0200 Subject: [PATCH 0381/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2b7667322..7aa37d556 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.11 + 1.1.12-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.11 + HEAD From 12de21f9b988f53541c4f9a277927e5d7b780599 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:28:23 +0200 Subject: [PATCH 0382/1786] restored jdk 11 release version --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7aa37d556..06eec6729 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.12-SNAPSHOT + 1.2.6-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 From 54c4f876abd24a9b170143e95ef0d84d3fbbe1cf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:31:20 +0200 Subject: [PATCH 0383/1786] Implemented changes for the new feature --- src/main/java/com/hotels/beans/BeanUtils.java | 13 +++++++++++ .../java/com/hotels/beans/BeanUtilsTest.java | 23 ++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/hotels/beans/BeanUtils.java b/src/main/java/com/hotels/beans/BeanUtils.java index b7aaadeae..3ce8bd22d 100644 --- a/src/main/java/com/hotels/beans/BeanUtils.java +++ b/src/main/java/com/hotels/beans/BeanUtils.java @@ -38,6 +38,19 @@ public static Function getTransformer(final Class targetClass) { return fromBean -> new TransformerImpl().transform(fromBean, targetClass); } + /** + * Returns a function that transforms an object T in an object K. + * @param beanTransformer the transformer to be used. + * @param targetClass the destination object class + * @param the Source object type + * @param the target object type + * @return a function that copies of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + public static Function getTransformer(final Transformer beanTransformer, final Class targetClass) { + return fromBean -> beanTransformer.transform(fromBean, targetClass); + } + /** * Returns a Bean Transformer. * @return a Bean Transformer instance. diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/src/test/java/com/hotels/beans/BeanUtilsTest.java index 020c80ea2..fcb75162b 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -31,6 +31,7 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.hotels.beans.sample.FromFooSimple; @@ -74,15 +75,16 @@ public void testGetTransformerWorksProperly() { /** * Test that the transformer function returned is able to transform the given object. + * @param testCaseDescription the test case description + * @param transformerFunction the transform function to use */ - @Test - public void testGetTransformerFunctionWorksProperly() { + @Test(dataProvider = "dataStaticTransformationTesting") + public void testGetTransformerFunctionWorksProperly(final String testCaseDescription, final Function transformerFunction) { //GIVEN FromFooSimple fromFooSimple = createFromFooSimple(); List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimple); //WHEN - Function transformerFunction = underTest.getTransformer(ImmutableToFooSimple.class); List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); @@ -93,6 +95,21 @@ public void testGetTransformerFunctionWorksProperly() { .forEach(i -> assertThat(actual.get(i), sameBeanAs(fromFooSimpleList.get(i)))); } + /** + * Creates the parameters to be used for testing the default transformation operations. + * @return parameters to be used for testing the default transformation operations. + */ + @DataProvider(parallel = true) + private Object[][] dataStaticTransformationTesting() { + BeanUtils beanUtils = new BeanUtils(); + return new Object[][] { + {"Test that the transformer function returned is able to transform the given object.", + beanUtils.getTransformer(ImmutableToFooSimple.class)}, + {"Test that the transformer function returned is able to transform the given object with the given transformer.", + beanUtils.getTransformer(beanUtils.getTransformer(), ImmutableToFooSimple.class)} + }; + } + /** * Creates a {@link FromFooSimple} instance. * @return the {@link FromFooSimple} instance. From 811bb43cea622629a2a061bdd25675ebc72ee5c0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:36:59 +0200 Subject: [PATCH 0384/1786] Added check on the transformer function and a related test --- src/main/java/com/hotels/beans/BeanUtils.java | 3 +++ src/test/java/com/hotels/beans/BeanUtilsTest.java | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/com/hotels/beans/BeanUtils.java b/src/main/java/com/hotels/beans/BeanUtils.java index 3ce8bd22d..cf939b654 100644 --- a/src/main/java/com/hotels/beans/BeanUtils.java +++ b/src/main/java/com/hotels/beans/BeanUtils.java @@ -16,6 +16,8 @@ package com.hotels.beans; +import static com.hotels.beans.utils.ValidationUtils.notNull; + import java.util.function.Function; import com.hotels.beans.transformer.TransformerImpl; @@ -48,6 +50,7 @@ public static Function getTransformer(final Class targetClass) { * @throws IllegalArgumentException if any parameter is invalid */ public static Function getTransformer(final Transformer beanTransformer, final Class targetClass) { + notNull(beanTransformer, "beanTransformer cannot be null!"); return fromBean -> beanTransformer.transform(fromBean, targetClass); } diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/src/test/java/com/hotels/beans/BeanUtilsTest.java index fcb75162b..f20efca00 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -73,6 +73,17 @@ public void testGetTransformerWorksProperly() { assertNotNull(transformer); } + /** + * Test that an exception is returned if the given transformer is null. + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testGetTransformerThrowsExceptionIfTheBeanTransformerIsNull() { + //GIVEN + + //WHEN + new BeanUtils().getTransformer(null, ImmutableToFooSimple.class); + } + /** * Test that the transformer function returned is able to transform the given object. * @param testCaseDescription the test case description From e3411c0b968bb23483a2d4c3bd8a83d1350f005b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:43:32 +0200 Subject: [PATCH 0385/1786] preparing release for jdk 1.8 --- CHANGELOG.md | 2 +- pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6b1ba62e..ccd8a7f90 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created -### [1.1.11] 2019.04.06 +### [1.1.12] 2019.04.06 #### Added * Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). diff --git a/pom.xml b/pom.xml index 06eec6729..7aa37d556 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.6-SNAPSHOT + 1.1.12-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 From fbe08f5cdd5d5e72c2fa1d9a6a97beb294a7a6e7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:44:18 +0200 Subject: [PATCH 0386/1786] [maven-release-plugin] prepare release 1.1.12 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7aa37d556..6a867a31f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.12-SNAPSHOT + 1.1.12 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.12 From 406bfedbb457b7dca7e32ef849ccc48045a1b607 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:44:25 +0200 Subject: [PATCH 0387/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6a867a31f..1f035067e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.12 + 1.1.13-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.12 + HEAD From 418ac503dad99f0d64f2f1cef2aaf4f208aec583 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:46:03 +0200 Subject: [PATCH 0388/1786] Preparing jdk 11 release --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1f035067e..06eec6729 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.13-SNAPSHOT + 1.2.6-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 From 6c2cd15ad65bd76783590e9817fff8f760825468 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Apr 2019 08:59:36 +0200 Subject: [PATCH 0389/1786] minor: used under test object rather than a new instance --- src/test/java/com/hotels/beans/BeanUtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/src/test/java/com/hotels/beans/BeanUtilsTest.java index f20efca00..7c6532754 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -81,7 +81,7 @@ public void testGetTransformerThrowsExceptionIfTheBeanTransformerIsNull() { //GIVEN //WHEN - new BeanUtils().getTransformer(null, ImmutableToFooSimple.class); + underTest.getTransformer(null, ImmutableToFooSimple.class); } /** From 6853219700376096c1d744fded799a5852017409 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 7 Apr 2019 09:28:02 +0200 Subject: [PATCH 0390/1786] Added static transformation documentation --- README.md | 9 ++++++++- docs/site/markdown/transformer/samples.md | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a75fda4aa..e9cea1a80 100644 --- a/README.md +++ b/README.md @@ -334,7 +334,14 @@ List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimp can be transformed as follow: ~~~Java Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); - List actual = fromFooSimpleList.stream() +List actual = fromFooSimpleList.stream() + .map(transformerFunction) + .collect(Collectors.toList()); +~~~ +or if you have a pre-configured transformer: +~~~Java +Function transformerFunction = BeanUtils.getTransformer(, ImmutableToFooSimple.class); +List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); ~~~ diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 46cb6c95c..ce045ba15 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -276,7 +276,14 @@ List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimp can be transformed as follow: ~~~Java Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); - List actual = fromFooSimpleList.stream() +List actual = fromFooSimpleList.stream() + .map(transformerFunction) + .collect(Collectors.toList()); +~~~ +or if you have a pre-configured transformer: +~~~Java +Function transformerFunction = BeanUtils.getTransformer(, ImmutableToFooSimple.class); +List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); ~~~ From 40885f763a9dd57ac7d30aaf116bf9e39da08eed Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 7 Apr 2019 09:52:07 +0200 Subject: [PATCH 0391/1786] As per issue: https://github.com/HotelsDotCom/bull/issues/49, the cache operation have been replaced with computeIfPresent and computeIfAbsent --- .../com/hotels/beans/cache/CacheManager.java | 10 +++------ .../beans/cache/CacheManagerFactory.java | 9 +------- .../hotels/beans/cache/CacheManagerTest.java | 22 ------------------- 3 files changed, 4 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/src/main/java/com/hotels/beans/cache/CacheManager.java index 90e0af73b..20eeed227 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -17,9 +17,6 @@ package com.hotels.beans.cache; import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; - -import static com.hotels.beans.utils.ValidationUtils.notNull; import static lombok.AccessLevel.PRIVATE; import static lombok.AccessLevel.PROTECTED; @@ -72,10 +69,9 @@ public void cacheObject(final String cacheKey, final T object, final Object * @param the class object type. * @return the cached object. */ + @SuppressWarnings("unchecked") public T getFromCache(final String cacheKey, final Class objectClass) { - notNull(cacheKey, "cacheKey cannot be null!"); - notNull(objectClass, "objectClass cannot be null!"); - return ofNullable(cacheMap.get(cacheKey)).map(objectClass::cast).orElse(null); + return (T) cacheMap.computeIfPresent(cacheKey, (k, v) -> objectClass.cast(v)); } /** @@ -83,6 +79,6 @@ public T getFromCache(final String cacheKey, final Class object * @param cacheKey the cache key. */ public void removeFromCache(final String cacheKey) { - ofNullable(cacheKey).ifPresent(cacheMap::remove); + cacheMap.computeIfPresent(cacheKey, (k, v) -> cacheMap.remove(k)); } } diff --git a/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java b/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java index b12f9d25d..6e511723b 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java +++ b/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java @@ -16,8 +16,6 @@ package com.hotels.beans.cache; -import static java.util.Objects.isNull; - import static com.hotels.beans.utils.ValidationUtils.notNull; import static lombok.AccessLevel.PRIVATE; @@ -44,11 +42,6 @@ public final class CacheManagerFactory { */ public static CacheManager getCacheManager(final String cacheName) { notNull(cacheName, "cacheName cannot be null!"); - Map cacheMap = CACHE_MAP.get(cacheName); - if (isNull(cacheMap)) { - cacheMap = new ConcurrentHashMap<>(); - CACHE_MAP.put(cacheName, cacheMap); - } - return new CacheManager(cacheMap); + return new CacheManager(CACHE_MAP.computeIfAbsent(cacheName, k -> new ConcurrentHashMap<>())); } } diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index 193536d37..798200333 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -63,28 +63,6 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { assertSame(CACHED_VALUE, actual); } - /** - * Tests that the method {@code getFromCache} throw exception when the cache key. - */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testGetFromCacheThrowsExceptionWhenTheCacheKeyIsNull() { - // GIVEN - - // WHEN - underTest.getFromCache(null, CACHED_OBJECT_CLASS); - } - - /** - * Tests that the method {@code getFromCache} throw exception when the cached value class is null. - */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testGetFromCacheThrowsExceptionWhenTheCachedValueClassIsNull() { - // GIVEN - - // WHEN - underTest.getFromCache(CACHE_KEY, null); - } - /** * Tests that the method {@code removeFromCache} really removes the object from the cache. */ From d4f2aabe04c6bfe1b8cea636e2fdcaa33b986fd1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Apr 2019 08:32:14 +0200 Subject: [PATCH 0392/1786] Reverted CacheManager as the old behaviour was wrong --- .../com/hotels/beans/cache/CacheManager.java | 10 ++++++--- .../hotels/beans/cache/CacheManagerTest.java | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/src/main/java/com/hotels/beans/cache/CacheManager.java index 20eeed227..90e0af73b 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -17,6 +17,9 @@ package com.hotels.beans.cache; import static java.util.Objects.nonNull; +import static java.util.Optional.ofNullable; + +import static com.hotels.beans.utils.ValidationUtils.notNull; import static lombok.AccessLevel.PRIVATE; import static lombok.AccessLevel.PROTECTED; @@ -69,9 +72,10 @@ public void cacheObject(final String cacheKey, final T object, final Object * @param the class object type. * @return the cached object. */ - @SuppressWarnings("unchecked") public T getFromCache(final String cacheKey, final Class objectClass) { - return (T) cacheMap.computeIfPresent(cacheKey, (k, v) -> objectClass.cast(v)); + notNull(cacheKey, "cacheKey cannot be null!"); + notNull(objectClass, "objectClass cannot be null!"); + return ofNullable(cacheMap.get(cacheKey)).map(objectClass::cast).orElse(null); } /** @@ -79,6 +83,6 @@ public T getFromCache(final String cacheKey, final Class object * @param cacheKey the cache key. */ public void removeFromCache(final String cacheKey) { - cacheMap.computeIfPresent(cacheKey, (k, v) -> cacheMap.remove(k)); + ofNullable(cacheKey).ifPresent(cacheMap::remove); } } diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index 798200333..193536d37 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -63,6 +63,28 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { assertSame(CACHED_VALUE, actual); } + /** + * Tests that the method {@code getFromCache} throw exception when the cache key. + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testGetFromCacheThrowsExceptionWhenTheCacheKeyIsNull() { + // GIVEN + + // WHEN + underTest.getFromCache(null, CACHED_OBJECT_CLASS); + } + + /** + * Tests that the method {@code getFromCache} throw exception when the cached value class is null. + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testGetFromCacheThrowsExceptionWhenTheCachedValueClassIsNull() { + // GIVEN + + // WHEN + underTest.getFromCache(CACHE_KEY, null); + } + /** * Tests that the method {@code removeFromCache} really removes the object from the cache. */ From 460e4dc86cc7017e11db412efc9620fd97f1d6df Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Apr 2019 11:38:39 +0200 Subject: [PATCH 0393/1786] Added support for transforming Temporal instance object --- src/main/java/com/hotels/beans/utils/ClassUtils.java | 4 +++- src/test/java/com/hotels/beans/utils/ClassUtilsTest.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index f973b8cbe..437de4127 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -47,6 +47,8 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; +import java.time.Instant; +import java.time.temporal.Temporal; import java.util.ArrayList; import java.util.Currency; import java.util.LinkedList; @@ -142,7 +144,7 @@ public boolean isSpecialType(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isSpecial-" + clazz.getCanonicalName(); return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { - final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || clazz.isSynthetic() || clazz.isAnonymousClass(); + final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || clazz.isInstance(Temporal.class) || clazz.isSynthetic() || clazz.isAnonymousClass(); cacheManager.cacheObject(cacheKey, res); return res; }); diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index dae9f31e3..756a4db1d 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -29,6 +29,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.math.BigDecimal; +import java.time.Instant; import java.util.List; import java.util.Locale; import java.util.function.Predicate; @@ -152,7 +153,8 @@ public void testIsSpecialTypeWorksAsExpected(final String testCaseDescription, f private Object[][] dataSpecialTypeObjectTesting() { return new Object[][] { {"Tests that the method returns true if the class is a special type object", Locale.class, true}, - {"Tests that the method returns false if the class is not a special type object", BigDecimal.class, false} + {"Tests that the method returns false if the class is not a special type object", BigDecimal.class, false}, + {"Tests that the method returns true if the class is an instance of Temporal interface", Instant.class, false} }; } From c72472db4ae1336d32a37364670216fc83c72f19 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Apr 2019 11:39:41 +0200 Subject: [PATCH 0394/1786] Checkstyle fix --- src/main/java/com/hotels/beans/utils/ClassUtils.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 437de4127..b542b8fdb 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -47,7 +47,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; -import java.time.Instant; import java.time.temporal.Temporal; import java.util.ArrayList; import java.util.Currency; From 4962f0c5da6edf766b53590589649005bf390fd2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Apr 2019 11:47:15 +0200 Subject: [PATCH 0395/1786] Fixed not working condition --- src/main/java/com/hotels/beans/utils/ClassUtils.java | 3 ++- src/test/java/com/hotels/beans/utils/ClassUtilsTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index b542b8fdb..0177103fe 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -143,7 +143,8 @@ public boolean isSpecialType(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isSpecial-" + clazz.getCanonicalName(); return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { - final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || clazz.isInstance(Temporal.class) || clazz.isSynthetic() || clazz.isAnonymousClass(); + final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || Temporal.class.isAssignableFrom(clazz) + || clazz.isSynthetic() || clazz.isAnonymousClass(); cacheManager.cacheObject(cacheKey, res); return res; }); diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 756a4db1d..7552ded66 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -154,7 +154,7 @@ private Object[][] dataSpecialTypeObjectTesting() { return new Object[][] { {"Tests that the method returns true if the class is a special type object", Locale.class, true}, {"Tests that the method returns false if the class is not a special type object", BigDecimal.class, false}, - {"Tests that the method returns true if the class is an instance of Temporal interface", Instant.class, false} + {"Tests that the method returns true if the class is an instance of Temporal interface", Instant.class, true} }; } From 0c6d7db2017b167627af3cc820d6dbc61f284fd6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Apr 2019 14:41:35 +0200 Subject: [PATCH 0396/1786] [maven-release-plugin] prepare release 1.2.6 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 06eec6729..4ace9b567 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.6-SNAPSHOT + 1.2.6 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.6 From e0e53331808c7f374f48a33a81af39cbe67923a1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Apr 2019 14:41:43 +0200 Subject: [PATCH 0397/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4ace9b567..8a1383a43 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.6 + 1.2.7-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.6 + HEAD From 92a720189ddc3f953e318df5634805a76818c0a1 Mon Sep 17 00:00:00 2001 From: antimo Date: Tue, 9 Apr 2019 00:16:40 +0200 Subject: [PATCH 0398/1786] Create test to verify if we can get instance of a (static) Builder in a class. TODO Verify builder with non static inner class --- .../beans/sample/builder/BuilderTest.java | 58 +++++++++++++++++++ .../hotels/beans/sample/builder/ToFoo.java | 39 +++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 src/test/java/com/hotels/beans/sample/builder/BuilderTest.java create mode 100644 src/test/java/com/hotels/beans/sample/builder/ToFoo.java diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java new file mode 100644 index 000000000..93c85f9c6 --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java @@ -0,0 +1,58 @@ +package com.hotels.beans.sample.builder; + +import com.hotels.beans.sample.FromFooWithBuilder; +import org.apache.commons.lang3.NotImplementedException; +import org.junit.Test; + +import static org.testng.AssertJUnit.assertSame; + +public class BuilderTest { + + + /** + * Test that we can get the Builder from a class (with a builder) created manually + */ + + @Test + public void checkDeclaredClassInManualBuilder(){ + // WHEN + Class[] declaredClasses = ToFoo.class.getDeclaredClasses(); + Class clazz = declaredClasses[0]; + + // THEN + assertSame(clazz,ToFoo.Builder.class); + } + + + /** + * Test that we can get the Builder from a class created with Lombok + * Expected name for the Builder is "OriginalClassName" + "Builder + * see https://projectlombok.org/features/Builder + */ + + @Test + public void checkDeclaredClassInBuilderFromLombok(){ + // WHEN + Class[] declaredClasses = FromFooWithBuilder.class.getDeclaredClasses(); + Class clazz = declaredClasses[0]; + + // THEN + assertSame(clazz,FromFooWithBuilder.FromFooWithBuilderBuilder.class); + } + + + /* + NONJAVADOC!!! TODO : check if useful!!! + Here some chat about builder constructed WITHOUT STATIC CLASS + https://softwareengineering.stackexchange.com/questions/225207/why-should-a-builder-be-an-inner-class-instead-of-in-its-own-class-file + + + Anyway buinder constructed with lombok use static class + https://projectlombok.org/features/Builder + */ + @Test + public void checkInnerClass(){ + throw new NotImplementedException("Check builder with Inner (non static) class"); + } + + } diff --git a/src/test/java/com/hotels/beans/sample/builder/ToFoo.java b/src/test/java/com/hotels/beans/sample/builder/ToFoo.java new file mode 100644 index 000000000..f71d60b0e --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/builder/ToFoo.java @@ -0,0 +1,39 @@ +package com.hotels.beans.sample.builder; + +import lombok.Getter; +import lombok.Setter; + +import java.math.BigInteger; + +@Getter +@Setter +public class ToFoo { + private String name; + private BigInteger id; + + private ToFoo() {} + + // getters + + public static class Builder { + private String name; + private BigInteger id; + + public Builder withName(String name) { + this.name = name; + return this; + } + + public Builder withId(BigInteger id) { + this.id = id; + return this; + } + + public ToFoo build() { + ToFoo toFoo = new ToFoo(); + toFoo.id = this.id; + toFoo.name = this.name; + return toFoo; + } + } +} \ No newline at end of file From d58bde301a890c87ec4b0e06b875f1e75707fc68 Mon Sep 17 00:00:00 2001 From: antimo Date: Tue, 9 Apr 2019 00:26:36 +0200 Subject: [PATCH 0399/1786] Create test to verify if we can get instance of a (static) Builder in a class. TODO Verify builder with non static inner class --- src/test/java/com/hotels/beans/sample/builder/BuilderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java index 93c85f9c6..a2c767e13 100644 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java @@ -26,7 +26,7 @@ public void checkDeclaredClassInManualBuilder(){ /** * Test that we can get the Builder from a class created with Lombok - * Expected name for the Builder is "OriginalClassName" + "Builder + * Expected name for the Builder created from Lombok is "OriginalClassName" + "Builder" without any character in between * see https://projectlombok.org/features/Builder */ From f856035916ae5e3b05e1ae7b5f89be7732912f61 Mon Sep 17 00:00:00 2001 From: antimo Date: Wed, 10 Apr 2019 18:59:20 +0200 Subject: [PATCH 0400/1786] Added usesBuilderPattern for Object based on Builder Pattern. TODO: Verify checkTypeClass (too many if?) --- .../com/hotels/beans/constant/ClassType.java | 6 ++- .../com/hotels/beans/utils/ClassUtils.java | 47 ++++++++++++++++- .../beans/sample/builder/BuilderTest.java | 8 +-- .../hotels/beans/utils/ClassUtilsTest.java | 52 +++++++++---------- 4 files changed, 79 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/hotels/beans/constant/ClassType.java b/src/main/java/com/hotels/beans/constant/ClassType.java index 6c5af701f..ec4c0d3ff 100644 --- a/src/main/java/com/hotels/beans/constant/ClassType.java +++ b/src/main/java/com/hotels/beans/constant/ClassType.java @@ -31,7 +31,11 @@ public enum ClassType { /** * The class contains both final and not final fields. */ - MIXED; + MIXED, + /** + * The class could be instantiated with a Builder + */ + BUILDER; /** * Checks if a the class type instance is equal to the given one. diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 0177103fe..6e7ff2ef9 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -38,6 +38,7 @@ import static com.hotels.beans.constant.ClassType.IMMUTABLE; import static com.hotels.beans.constant.ClassType.MIXED; import static com.hotels.beans.constant.ClassType.MUTABLE; +import static com.hotels.beans.constant.ClassType.BUILDER; import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_FIELD; import static com.hotels.beans.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; @@ -49,6 +50,7 @@ import java.lang.reflect.Parameter; import java.time.temporal.Temporal; import java.util.ArrayList; +import java.util.Arrays; import java.util.Currency; import java.util.LinkedList; import java.util.List; @@ -364,12 +366,49 @@ public boolean hasAccessibleConstructors(final Class targetClass) { public boolean usesBuilderPattern(final Constructor constructor, final Class targetClass) { final String cacheKey = "UsesBuilderPattern-" + constructor.getDeclaringClass().getCanonicalName(); return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { - final boolean res = !isPublic(constructor.getModifiers()) && isNotEmpty(targetClass.getDeclaredClasses()); + final boolean res = !isPublic(constructor.getModifiers()) && !getNestedClass(targetClass).isEmpty() + && isValidBuildMethod(targetClass); cacheManager.cacheObject(cacheKey, res); return res; }); } + /** + * Check if in nested class of @superclass is present a valid build method + * @param superclass + * @return true if in the nested class is present a valid build method + */ + private boolean isValidBuildMethod(final Class superclass) { + final String build = "build"; + String cacheKey = "build-method-" + superclass.getCanonicalName(); + Method[] declaredMethods = getDeclaredMethods(getNestedClass(superclass).get(0)); + return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + Method buildMethod = (stream(declaredMethods) + .filter(method -> method.getName().equals(build)) + .filter(method -> method.getReturnType().equals(superclass)) + .findFirst()) + .orElse(null); + cacheManager.cacheObject(cacheKey, buildMethod); + boolean res = buildMethod != null ? true : false; + return res; + }); + } + + /** + * Get Nested Class defined inside the clazz parameter + * @param clazz + * @return Nested class if present or an empty List + */ + public List getNestedClass(Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); + String cacheKey = "nested-classes-" + clazz.getCanonicalName(); + return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + List> declaredClasses = Arrays.asList(clazz.getDeclaredClasses()); + cacheManager.cacheObject(cacheKey, declaredClasses); + return declaredClasses; + }); + } + /** * Retrieves the all args constructor. * @param clazz the class from which gets the all arg constructor. @@ -570,8 +609,11 @@ public ClassType getClassType(final Class clazz) { final String cacheKey = "ClassType-" + clazz.getCanonicalName(); return ofNullable(cacheManager.getFromCache(cacheKey, ClassType.class)).orElseGet(() -> { final ClassType classType; + boolean hasFinalFields = hasFinalFields(clazz); - if (!hasFinalFields) { + if (usesBuilderPattern(getAllArgsConstructor(clazz), clazz)) { + classType = BUILDER; + } else if (!hasFinalFields) { classType = MUTABLE; } else { boolean hasNotFinalFields = hasNotFinalFields(clazz); @@ -586,6 +628,7 @@ public ClassType getClassType(final Class clazz) { }); } + /** * Retrieves all the setters method for the given class. * @param clazz the clazz containing the methods. diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java index a2c767e13..eb6d39390 100644 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java @@ -1,7 +1,6 @@ package com.hotels.beans.sample.builder; import com.hotels.beans.sample.FromFooWithBuilder; -import org.apache.commons.lang3.NotImplementedException; import org.junit.Test; import static org.testng.AssertJUnit.assertSame; @@ -17,6 +16,7 @@ public class BuilderTest { public void checkDeclaredClassInManualBuilder(){ // WHEN Class[] declaredClasses = ToFoo.class.getDeclaredClasses(); + // TODO check for null value... Class clazz = declaredClasses[0]; // THEN @@ -50,9 +50,9 @@ public void checkDeclaredClassInBuilderFromLombok(){ Anyway buinder constructed with lombok use static class https://projectlombok.org/features/Builder */ - @Test +/* @Test public void checkInnerClass(){ - throw new NotImplementedException("Check builder with Inner (non static) class"); - } + //throw new NotImplementedException("Check builder with Inner (non static) class"); + }*/ } diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 7552ded66..377b8c897 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -16,31 +16,6 @@ package com.hotels.beans.utils; -import static java.lang.reflect.Modifier.isFinal; -import static java.util.Objects.nonNull; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.MockitoAnnotations.initMocks; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.math.BigDecimal; -import java.time.Instant; -import java.util.List; -import java.util.Locale; -import java.util.function.Predicate; - -import javax.validation.constraints.NotNull; - -import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.constant.ClassType; import com.hotels.beans.error.InvalidBeanException; @@ -53,6 +28,28 @@ import com.hotels.beans.sample.mixed.MixedToFooMissingConstructor; import com.hotels.beans.sample.mixed.MixedToFooStaticField; import com.hotels.beans.sample.mutable.MutableToFoo; +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import javax.validation.constraints.NotNull; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.math.BigDecimal; +import java.time.Instant; +import java.util.List; +import java.util.Locale; +import java.util.function.Predicate; + +import static java.lang.reflect.Modifier.isFinal; +import static java.util.Objects.nonNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.MockitoAnnotations.initMocks; /** * Unit test for {@link ClassUtils}. @@ -568,14 +565,15 @@ public void testGetClassTypeWorksAsExpected(final String testCaseDescription, fi /** * Creates the parameters to be used for testing the method {@code getClassType}. - * @return parameters to be used for testing the the method {@code getClassType}. + * @return parameters to be used for testing the the method {@code getClassType}. FromFooWithBuilder */ @DataProvider private Object[][] dataGetClassTypeTesting() { return new Object[][] { {"Tests that the method returns immutable if the given class is immutable", ImmutableToFoo.class, ClassType.IMMUTABLE}, {"Tests that the method returns mutable if the given class is mutable", MutableToFoo.class, ClassType.MUTABLE}, - {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED} + {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED}, + {"Test that the method returns builder if the given class is a Builder",FromFooWithBuilder.class, ClassType.BUILDER } }; } From 11e0152f5e45de6b0659bbe68c1fd791091679d7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 10 Apr 2019 22:50:12 +0200 Subject: [PATCH 0401/1786] Modified getFromCache method in order to return an Optional rather than a null in case the object does not exists in the cache --- .../com/hotels/beans/cache/CacheManager.java | 7 +-- .../beans/transformer/TransformerImpl.java | 4 +- .../com/hotels/beans/utils/ClassUtils.java | 50 ++++++++--------- .../hotels/beans/utils/ReflectionUtils.java | 53 +++++++++---------- .../hotels/beans/utils/ValidationUtils.java | 3 +- .../hotels/beans/cache/CacheManagerTest.java | 17 +++--- 6 files changed, 66 insertions(+), 68 deletions(-) diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/src/main/java/com/hotels/beans/cache/CacheManager.java index 90e0af73b..0c59a91e6 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -25,6 +25,7 @@ import static lombok.AccessLevel.PROTECTED; import java.util.Map; +import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Getter; @@ -70,12 +71,12 @@ public void cacheObject(final String cacheKey, final T object, final Object * @param cacheKey the cache key. * @param objectClass the class of the object to return. * @param the class object type. - * @return the cached object. + * @return the cached object or {@code Optional.empty()} if not existing. */ - public T getFromCache(final String cacheKey, final Class objectClass) { + public Optional getFromCache(final String cacheKey, final Class objectClass) { notNull(cacheKey, "cacheKey cannot be null!"); notNull(objectClass, "objectClass cannot be null!"); - return ofNullable(cacheMap.get(cacheKey)).map(objectClass::cast).orElse(null); + return ofNullable(cacheMap.get(cacheKey)).map(objectClass::cast); } /** diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 39527b49d..c269f4499 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -140,7 +140,7 @@ private String getFormattedConstructorArgs(final Class targetClass, final */ private boolean canBeInjectedByConstructorParams(final Constructor constructor, final Class targetClass) { final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() && (classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class)); cacheManager.cacheObject(cacheKey, res); @@ -214,7 +214,7 @@ private String getSourceFieldName(final String fieldName) { */ private String getDestFieldName(final Parameter constructorParameter, final String declaringClassName) { String cacheKey = "DestFieldName-" + declaringClassName + "-" + constructorParameter.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, String.class)) + return cacheManager.getFromCache(cacheKey, String.class) .orElseGet(() -> { String destFieldName; if (constructorParameter.isNamePresent()) { diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 0177103fe..3066e9bde 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -95,7 +95,7 @@ public ClassUtils() { public boolean isPrimitiveOrSpecialType(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isPrimitiveOrSpecial-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = isPrimitiveType(clazz) || isSpecialType(clazz); cacheManager.cacheObject(cacheKey, res); return res; @@ -110,7 +110,7 @@ public boolean isPrimitiveOrSpecialType(final Class clazz) { public boolean isPrimitiveType(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isPrimitive-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = clazz.isPrimitive() || clazz.equals(String.class) || Number.class.isAssignableFrom(clazz) || clazz.equals(Byte.class) || clazz.isEnum(); cacheManager.cacheObject(cacheKey, res); return res; @@ -125,7 +125,7 @@ public boolean isPrimitiveType(final Class clazz) { public boolean isPrimitiveTypeArray(final Object object) { notNull(object, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = object instanceof int[] || object instanceof char[] || object instanceof short[] || object instanceof long[] || object instanceof byte[] || object instanceof float[] || object instanceof double[]; cacheManager.cacheObject(cacheKey, res); @@ -142,7 +142,7 @@ public boolean isPrimitiveTypeArray(final Object object) { public boolean isSpecialType(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isSpecial-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || Temporal.class.isAssignableFrom(clazz) || clazz.isSynthetic() || clazz.isAnonymousClass(); cacheManager.cacheObject(cacheKey, res); @@ -231,7 +231,7 @@ public static boolean isBoolean(final Class type) { public List getPrivateFinalFields(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "PrivateFinalFields-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { res.addAll(getPrivateFinalFields(clazz.getSuperclass())); @@ -254,7 +254,7 @@ public List getPrivateFinalFields(final Class clazz) { public int getTotalFields(final Class clazz, final Predicate predicate) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "TotalFields-" + clazz.getCanonicalName() + '-' + predicate; - return ofNullable(cacheManager.getFromCache(cacheKey, Integer.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Integer.class).orElseGet(() -> { List declaredFields = getDeclaredFields(clazz, true); int res = ofNullable(predicate) .map(filter -> (int) declaredFields.stream().filter(filter).count()) @@ -283,7 +283,7 @@ public List getPrivateFields(final Class clazz) { public List getPrivateFields(final Class clazz, final boolean skipFinal) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "PrivateFields-" + clazz.getCanonicalName() + "-skipFinal-" + skipFinal; - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { res.addAll(getPrivateFields(clazz.getSuperclass(), skipFinal)); @@ -309,7 +309,7 @@ public List getPrivateFields(final Class clazz, final boolean skipFina public List getDeclaredFields(final Class clazz, final boolean skipStatic) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "DeclaredFields-" + clazz.getCanonicalName() + "-skipStatic-" + skipStatic; - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new LinkedList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { res.addAll(getDeclaredFields(clazz.getSuperclass(), skipStatic)); @@ -332,7 +332,7 @@ public List getDeclaredFields(final Class clazz, final boolean skipSta */ private Field[] getDeclaredFields(final Class clazz) { final String cacheKey = "ClassDeclaredFields-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Field[].class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Field[].class).orElseGet(() -> { Field[] res = clazz.getDeclaredFields(); cacheManager.cacheObject(cacheKey, res); return res; @@ -347,7 +347,7 @@ private Field[] getDeclaredFields(final Class clazz) { */ public boolean hasAccessibleConstructors(final Class targetClass) { final String cacheKey = "HasAccessibleConstructors-" + targetClass.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = stream(targetClass.getDeclaredConstructors()).anyMatch(constructor -> isPublic(constructor.getModifiers())); cacheManager.cacheObject(cacheKey, res); return res; @@ -363,7 +363,7 @@ public boolean hasAccessibleConstructors(final Class targetClass) { */ public boolean usesBuilderPattern(final Constructor constructor, final Class targetClass) { final String cacheKey = "UsesBuilderPattern-" + constructor.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = !isPublic(constructor.getModifiers()) && isNotEmpty(targetClass.getDeclaredClasses()); cacheManager.cacheObject(cacheKey, res); return res; @@ -379,7 +379,7 @@ public boolean usesBuilderPattern(final Constructor constructor, final Class public Constructor getAllArgsConstructor(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "AllArgsConstructor-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Constructor.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { Constructor constructor = getAllArgsConstructor(clazz.getDeclaredConstructors()); cacheManager.cacheObject(cacheKey, constructor); return constructor; @@ -396,7 +396,7 @@ public Constructor getAllArgsConstructor(final Constructor[] constructors) { throw new InvalidBeanException("No constructors available"); } final String cacheKey = "AllArgsConstructor-" + constructors[0].getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Constructor.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { final Constructor constructor = max(asList(constructors), comparing(Constructor::getParameterCount)); cacheManager.cacheObject(cacheKey, constructor); return constructor; @@ -410,7 +410,7 @@ public Constructor getAllArgsConstructor(final Constructor[] constructors) { */ public Parameter[] getConstructorParameters(final Constructor constructor) { final String cacheKey = "ConstructorParams-" + constructor.getDeclaringClass().getCanonicalName() + '-' + constructor.getParameterCount(); - return ofNullable(cacheManager.getFromCache(cacheKey, Parameter[].class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Parameter[].class).orElseGet(() -> { final Parameter[] parameters = constructor.getParameters(); cacheManager.cacheObject(cacheKey, parameters); return parameters; @@ -425,7 +425,7 @@ public Parameter[] getConstructorParameters(final Constructor constructor) { */ public boolean hasField(final Object target, final String fieldName) { final String cacheKey = "ClassHasField-" + target.getClass().getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { boolean hasField; try { hasField = nonNull(target.getClass().getDeclaredField(fieldName)); @@ -449,7 +449,7 @@ public boolean hasField(final Object target, final String fieldName) { public boolean hasSetterMethods(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "HasSetterMethods-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)) + return cacheManager.getFromCache(cacheKey, Boolean.class) .orElseGet(() -> { final Boolean res = stream(getDeclaredMethods(clazz)).anyMatch(reflectionUtils::isSetter); cacheManager.cacheObject(cacheKey, res); @@ -465,7 +465,7 @@ public boolean hasSetterMethods(final Class clazz) { private Method[] getDeclaredMethods(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "DeclaredMethods-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Method[].class)) + return cacheManager.getFromCache(cacheKey, Method[].class) .orElseGet(() -> { final Method[] res = clazz.getDeclaredMethods(); cacheManager.cacheObject(cacheKey, res); @@ -501,7 +501,7 @@ private boolean hasNotFinalFields(final Class clazz) { * @return true if it has private final field, false otherwise. */ private boolean hasFieldsMatchingCondition(final Class clazz, final Predicate filterPredicate, final String cacheKey) { - return ofNullable(cacheManager.getFromCache(cacheKey + clazz.getCanonicalName(), Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey + clazz.getCanonicalName(), Boolean.class).orElseGet(() -> { boolean res = stream(getDeclaredFields(clazz)) //.parallel() .anyMatch(filterPredicate); @@ -522,7 +522,7 @@ private boolean hasFieldsMatchingCondition(final Class clazz, final Predicate */ public boolean containsAnnotation(final Constructor constructor, final Class annotationClass) { final String cacheKey = "ConstructorHasAnnotation-" + constructor.getDeclaringClass().getCanonicalName() + '-' + annotationClass.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean containsAnnotation = stream(constructor.getParameters()) .noneMatch(parameter -> isNull(parameter.getAnnotation(annotationClass))); cacheManager.cacheObject(cacheKey, containsAnnotation); @@ -538,7 +538,7 @@ public boolean containsAnnotation(final Constructor constructor, final Class annotationClass) { final String cacheKey = "AllParameterAnnotatedWith-" + constructor.getDeclaringClass().getCanonicalName() + '-' + annotationClass.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean notAllAnnotatedWith = stream(constructor.getParameters()) .allMatch(parameter -> nonNull(parameter.getAnnotation(annotationClass))); cacheManager.cacheObject(cacheKey, notAllAnnotatedWith); @@ -553,7 +553,7 @@ public boolean allParameterAnnotatedWith(final Constructor constructor, final Cl */ public boolean areParameterNamesAvailable(final Constructor constructor) { final String cacheKey = "AreParameterNamesAvailable-" + constructor.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = stream(getConstructorParameters(constructor)) .anyMatch(Parameter::isNamePresent); cacheManager.cacheObject(cacheKey, res); @@ -568,7 +568,7 @@ public boolean areParameterNamesAvailable(final Constructor constructor) { */ public ClassType getClassType(final Class clazz) { final String cacheKey = "ClassType-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, ClassType.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, ClassType.class).orElseGet(() -> { final ClassType classType; boolean hasFinalFields = hasFinalFields(clazz); if (!hasFinalFields) { @@ -595,7 +595,7 @@ public ClassType getClassType(final Class clazz) { public List getSetterMethods(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "SetterMethods-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List setterMethods = new LinkedList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { setterMethods.addAll(getSetterMethods(clazz.getSuperclass())); @@ -615,7 +615,7 @@ public List getSetterMethods(final Class clazz) { */ public Object getDefaultTypeValue(final Class objectType) { final String cacheKey = "DefaultTypeValue-" + objectType.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Object.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Object.class).orElseGet(() -> { final Object defaultValue = isPrimitiveType(objectType) ? defaultValue(objectType) : null; cacheManager.cacheObject(cacheKey, defaultValue); return defaultValue; @@ -631,7 +631,7 @@ public Object getDefaultTypeValue(final Class objectType) { @SuppressWarnings("unchecked") public List getNotFinalFields(final Class clazz, final Boolean skipStatic) { final String cacheKey = "NotFinalFields-" + clazz.getCanonicalName() + "-" + skipStatic; - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { List notFinalFields = getDeclaredFields(clazz, skipStatic) .stream() .filter(IS_NOT_FINAL_FIELD).collect(toList()); diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 63ca3a47d..bddd5f337 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -19,7 +19,6 @@ import static java.lang.reflect.Modifier.isPublic; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; import static org.apache.commons.lang3.StringUtils.capitalize; @@ -107,7 +106,7 @@ private Object invokeMethod(final Method method, final Object target, final Obje */ public boolean isSetter(final Method method) { final String cacheKey = "IsSetter-" + method.getDeclaringClass().getCanonicalName() + '-' + method.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { boolean res = isPublic(method.getModifiers()) && method.getName().matches(SETTER_METHOD_NAME_REGEX) && method.getParameterTypes().length == 1 @@ -158,7 +157,7 @@ public Object getFieldValue(final Object target, final String fieldName, final C */ private Method getGetterMethod(final Class fieldClass, final String fieldName, final Class fieldType) { final String cacheKey = "GetterMethod-" + fieldClass.getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Method.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { Method method = fieldClass.getMethod(getGetterMethodPrefix(fieldType) + capitalize(fieldName)); cacheManager.cacheObject(cacheKey, method); @@ -183,7 +182,7 @@ private Method getGetterMethod(final Class fieldClass, final String fieldName */ public A getFieldAnnotation(final Field field, final Class annotationClazz) { final String cacheKey = "FieldAnnotation-" + field.getDeclaringClass().getCanonicalName() + "-" + field.getName() + "-" + annotationClazz.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, annotationClazz)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, annotationClazz).orElseGet(() -> { A annotation = null; if (field.isAnnotationPresent(annotationClazz)) { annotation = field.getAnnotation(annotationClazz); @@ -203,7 +202,7 @@ public A getFieldAnnotation(final Field field, final Clas */ public A getParameterAnnotation(final Parameter parameter, final Class annotationClazz, final String declaringClassName) { final String cacheKey = "ParameterAnnotation-" + declaringClassName + "-" + parameter.getName() + "-" + annotationClazz.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, annotationClazz)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, annotationClazz).orElseGet(() -> { A annotation = null; if (parameter.isAnnotationPresent(annotationClazz)) { annotation = parameter.getAnnotation(annotationClazz); @@ -249,7 +248,7 @@ private Object getFieldValue(final Object target, final String fieldName) { */ public Field getDeclaredField(final String fieldName, final Class targetClass) { final String cacheKey = "ClassDeclaredField-" + targetClass.getName() + "-" + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Field.class).orElseGet(() -> { Field field; try { field = targetClass.getDeclaredField(fieldName); @@ -347,7 +346,7 @@ private boolean isOptionalType(final Object object) { */ private String getGetterMethodPrefix(final Class fieldType) { final String cacheKey = "GetterMethodPrefix-" + fieldType.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, String.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, String.class).orElseGet(() -> { String res = Boolean.class.equals(fieldType) || fieldType.getCanonicalName().equals(BOOLEAN) ? IS.getPrefix() : GET.getPrefix(); cacheManager.cacheObject(cacheKey, res); return res; @@ -364,7 +363,7 @@ private String getGetterMethodPrefix(final Class fieldType) { */ public Method getSetterMethodForField(final Class fieldClass, final String fieldName, final Class fieldType) { final String cacheKey = "SetterMethod-" + fieldClass.getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Method.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { Method method = fieldClass.getMethod(SET.getPrefix() + capitalize(fieldName), fieldType); cacheManager.cacheObject(cacheKey, method); @@ -382,7 +381,7 @@ public Method getSetterMethodForField(final Class fieldClass, final String fi */ public Class getGenericFieldType(final Field field) { final String cacheKey = "GenericFieldType-" + field.getDeclaringClass().getCanonicalName() + '-' + field.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Class.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Class.class).orElseGet(() -> { Class res = null; if (ParameterizedType.class.isAssignableFrom(field.getGenericType().getClass())) { final Type[] fieldArgTypes = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); @@ -412,7 +411,7 @@ public MapType getMapGenericType(final Type fieldType, final String declaringCla + "It cannot be assigned from: " + Map.class.getCanonicalName() + "."); } final String cacheKey = "MapGenericFieldType-" + fieldClass.getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, MapType.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, MapType.class).orElseGet(() -> { final ParameterizedType genericType = (ParameterizedType) fieldType; final MapElemType keyType = getMapElemType(genericType.getActualTypeArguments()[0], declaringClass, fieldName); final MapElemType elemType = getMapElemType(genericType.getActualTypeArguments()[1], declaringClass, fieldName); @@ -433,7 +432,7 @@ public MapType getMapGenericType(final Type fieldType, final String declaringCla */ private MapElemType getMapElemType(final Type fieldType, final String declaringClass, final String fieldName) { final String cacheKey = "MapElemType-" + declaringClass + "-" + fieldType.getTypeName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, MapElemType.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, MapElemType.class).orElseGet(() -> { final Class argumentTypeClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); final MapElemType res; if (Map.class.isAssignableFrom(argumentTypeClass)) { @@ -473,22 +472,20 @@ public Class getArgumentTypeClass(final Object argument, final String declari final boolean argumentIsTypeClass = argument instanceof Class; final String cacheKey = "ArgumentTypeClass-" + declaringClass + "-" + fieldName + "-" + getNestedGenericClass + "-" + "-" + (argumentIsTypeClass || !List.class.isAssignableFrom(argument.getClass()) ? argument : argument.getClass()); - Class argumentTypeClass = cacheManager.getFromCache(cacheKey, Class.class); - if (nonNull(argumentTypeClass)) { - if (argumentTypeClass == EmptyValue.class) { - argumentTypeClass = null; - } - } else { - if (argumentIsTypeClass) { - argumentTypeClass = getNestedGenericClass ? null : (Class) argument; - } else if (ParameterizedType.class.isAssignableFrom(argument.getClass())) { - argumentTypeClass = getNestedGenericClass - ? getArgumentTypeClass(((ParameterizedType) argument).getActualTypeArguments()[0], declaringClass, fieldName, false) - : (Class) ((ParameterizedType) argument).getRawType(); - } - cacheManager.cacheObject(cacheKey, argumentTypeClass, EmptyValue.class); - } - return argumentTypeClass; + return cacheManager.getFromCache(cacheKey, Class.class) + .map(atc -> atc == EmptyValue.class ? null : atc) + .orElseGet(() -> { + Class res = null; + if (argumentIsTypeClass) { + res = getNestedGenericClass ? null : (Class) argument; + } else if (ParameterizedType.class.isAssignableFrom(argument.getClass())) { + res = getNestedGenericClass + ? getArgumentTypeClass(((ParameterizedType) argument).getActualTypeArguments()[0], declaringClass, fieldName, false) + : (Class) ((ParameterizedType) argument).getRawType(); + } + cacheManager.cacheObject(cacheKey, res, EmptyValue.class); + return res; + }); } /** @@ -498,7 +495,7 @@ public Class getArgumentTypeClass(final Object argument, final String declari */ public Class getArrayType(final Field arrayField) { final String cacheKey = "ArrayType-" + arrayField.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Class.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Class.class).orElseGet(() -> { final Class arrayType = arrayField.getType().getComponentType(); cacheManager.cacheObject(cacheKey, arrayType); return arrayType; diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java index f1a1d4b36..8ed0265ef 100644 --- a/src/main/java/com/hotels/beans/utils/ValidationUtils.java +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -17,7 +17,6 @@ package com.hotels.beans.utils; import static java.util.Objects.isNull; -import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.joining; import static javax.validation.Validation.buildDefaultValidatorFactory; @@ -105,7 +104,7 @@ public final void validate(final K k) { */ private Validator getValidator() { String cacheKey = "BeanValidator"; - return ofNullable(cacheManager.getFromCache(cacheKey, Validator.class)) + return cacheManager.getFromCache(cacheKey, Validator.class) .orElseGet(() -> { Validator validator = buildDefaultValidatorFactory().getValidator(); cacheManager.cacheObject(cacheKey, validator); diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index 193536d37..493ab2f52 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -17,10 +17,11 @@ package com.hotels.beans.cache; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import org.testng.annotations.BeforeMethod; @@ -55,12 +56,12 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { underTest.cacheObject(CACHE_KEY, CACHED_VALUE); // WHEN - Object actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); + Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertNotNull(actual); - assertEquals(CACHED_OBJECT_CLASS, actual.getClass()); - assertSame(CACHED_VALUE, actual); + assertFalse(actual.isEmpty()); + assertEquals(CACHED_OBJECT_CLASS, actual.get().getClass()); + assertSame(CACHED_VALUE, actual.get()); } /** @@ -95,9 +96,9 @@ public void testRemoveFromCacheRemovesTheObject() { // WHEN underTest.removeFromCache(CACHE_KEY); - Object actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); + Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertNull(actual); + assertTrue(actual.isEmpty()); } } From 6ba00583063a0511d267518affa8849939c841ea Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 10 Apr 2019 23:03:46 +0200 Subject: [PATCH 0402/1786] extra space cleanup --- src/main/java/com/hotels/beans/transformer/TransformerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index c269f4499..d0a1d8320 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -168,7 +168,7 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< .forEach(i -> { String destFieldName = getDestFieldName(constructorParameters[i], targetClass.getCanonicalName()); if (isNull(destFieldName)) { - constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); + constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); } else { String sourceFieldName = getSourceFieldName(destFieldName); constructorArgsValues[i] = From b67c068ee0f0925d0e2c06c70c819fbd093bb5cf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 10 Apr 2019 23:47:55 +0200 Subject: [PATCH 0403/1786] Replaced method getCanonicalName with getName --- .../beans/transformer/TransformerImpl.java | 14 ++--- .../com/hotels/beans/utils/ClassUtils.java | 52 ++++++++--------- .../hotels/beans/utils/ReflectionUtils.java | 58 +++++++++---------- .../hotels/beans/utils/ValidationUtils.java | 2 +- .../java/com/hotels/beans/BeanUtilsTest.java | 6 +- .../beans/cache/CacheManagerFactoryTest.java | 6 +- .../hotels/beans/cache/CacheManagerTest.java | 6 +- .../beans/performance/PerformanceTest.java | 8 --- .../beans/populator/ArrayPopulatorTest.java | 8 +-- .../beans/populator/PopulatorFactoryTest.java | 8 +-- .../ImmutableObjectTransformationTest.java | 8 +-- .../hotels/beans/utils/ClassUtilsTest.java | 6 +- .../beans/utils/ReflectionUtilsTest.java | 6 +- .../beans/utils/ValidationUtilsTest.java | 6 +- 14 files changed, 93 insertions(+), 101 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index d0a1d8320..4245c3639 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -114,7 +114,7 @@ private K injectValues(final T sourceObj, final Class targetClass, fin throw new InvalidBeanException("Constructor invoked with arguments. Expected: " + constructor + "; Found: " + getFormattedConstructorArgs(targetClass, constructorArgs) + ". Double check that each " + targetClass.getSimpleName() + "'s field have the same type and name than the source object: " - + sourceObj.getClass().getCanonicalName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(), e); + + sourceObj.getClass().getName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(), e); } } @@ -127,8 +127,8 @@ private K injectValues(final T sourceObj, final Class targetClass, fin */ private String getFormattedConstructorArgs(final Class targetClass, final Object[] constructorArgs) { return stream(constructorArgs) - .map(arg -> isNull(arg) ? "null" : arg.getClass().getCanonicalName()) - .collect(joining(COMMA.getSymbol(), targetClass.getCanonicalName() + LPAREN.getSymbol(), RPAREN.getSymbol())); + .map(arg -> isNull(arg) ? "null" : arg.getClass().getName()) + .collect(joining(COMMA.getSymbol(), targetClass.getName() + LPAREN.getSymbol(), RPAREN.getSymbol())); } /** @@ -139,7 +139,7 @@ private String getFormattedConstructorArgs(final Class targetClass, final * @return true if the parameter names are defined or the parameters are annotated with: {@link ConstructorArg} */ private boolean canBeInjectedByConstructorParams(final Constructor constructor, final Class targetClass) { - final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getCanonicalName(); + final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() && (classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class)); @@ -166,7 +166,7 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< range(0, constructorParameters.length) //.parallel() .forEach(i -> { - String destFieldName = getDestFieldName(constructorParameters[i], targetClass.getCanonicalName()); + String destFieldName = getDestFieldName(constructorParameters[i], targetClass.getName()); if (isNull(destFieldName)) { constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); } else { @@ -190,7 +190,7 @@ private boolean doSkipTransformation(final String breadcrumb) { /** * Returns the field name in the source object. - * @param field the field that has to be valorized. + * @param field the field that has to be set. * @return the source field name. */ private String getSourceFieldName(final Field field) { @@ -199,7 +199,7 @@ private String getSourceFieldName(final Field field) { /** * Returns the field name in the source object. - * @param fieldName the field name that has to be valorized. + * @param fieldName the field name that has to be set. * @return the source field name. */ private String getSourceFieldName(final String fieldName) { diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 3066e9bde..a94f46e9e 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -94,7 +94,7 @@ public ClassUtils() { */ public boolean isPrimitiveOrSpecialType(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "isPrimitiveOrSpecial-" + clazz.getCanonicalName(); + final String cacheKey = "isPrimitiveOrSpecial-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = isPrimitiveType(clazz) || isSpecialType(clazz); cacheManager.cacheObject(cacheKey, res); @@ -109,7 +109,7 @@ public boolean isPrimitiveOrSpecialType(final Class clazz) { */ public boolean isPrimitiveType(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "isPrimitive-" + clazz.getCanonicalName(); + final String cacheKey = "isPrimitive-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = clazz.isPrimitive() || clazz.equals(String.class) || Number.class.isAssignableFrom(clazz) || clazz.equals(Byte.class) || clazz.isEnum(); cacheManager.cacheObject(cacheKey, res); @@ -124,7 +124,7 @@ public boolean isPrimitiveType(final Class clazz) { */ public boolean isPrimitiveTypeArray(final Object object) { notNull(object, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getCanonicalName(); + final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = object instanceof int[] || object instanceof char[] || object instanceof short[] || object instanceof long[] || object instanceof byte[] || object instanceof float[] || object instanceof double[]; @@ -141,7 +141,7 @@ public boolean isPrimitiveTypeArray(final Object object) { */ public boolean isSpecialType(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "isSpecial-" + clazz.getCanonicalName(); + final String cacheKey = "isSpecial-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || Temporal.class.isAssignableFrom(clazz) || clazz.isSynthetic() || clazz.isAnonymousClass(); @@ -230,7 +230,7 @@ public static boolean isBoolean(final Class type) { @SuppressWarnings("unchecked") public List getPrivateFinalFields(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "PrivateFinalFields-" + clazz.getCanonicalName(); + final String cacheKey = "PrivateFinalFields-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { @@ -253,7 +253,7 @@ public List getPrivateFinalFields(final Class clazz) { */ public int getTotalFields(final Class clazz, final Predicate predicate) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "TotalFields-" + clazz.getCanonicalName() + '-' + predicate; + final String cacheKey = "TotalFields-" + clazz.getName() + '-' + predicate; return cacheManager.getFromCache(cacheKey, Integer.class).orElseGet(() -> { List declaredFields = getDeclaredFields(clazz, true); int res = ofNullable(predicate) @@ -282,7 +282,7 @@ public List getPrivateFields(final Class clazz) { @SuppressWarnings("unchecked") public List getPrivateFields(final Class clazz, final boolean skipFinal) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "PrivateFields-" + clazz.getCanonicalName() + "-skipFinal-" + skipFinal; + final String cacheKey = "PrivateFields-" + clazz.getName() + "-skipFinal-" + skipFinal; return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { @@ -308,7 +308,7 @@ public List getPrivateFields(final Class clazz, final boolean skipFina @SuppressWarnings("unchecked") public List getDeclaredFields(final Class clazz, final boolean skipStatic) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "DeclaredFields-" + clazz.getCanonicalName() + "-skipStatic-" + skipStatic; + final String cacheKey = "DeclaredFields-" + clazz.getName() + "-skipStatic-" + skipStatic; return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new LinkedList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { @@ -331,7 +331,7 @@ public List getDeclaredFields(final Class clazz, final boolean skipSta * @return a list of class fields */ private Field[] getDeclaredFields(final Class clazz) { - final String cacheKey = "ClassDeclaredFields-" + clazz.getCanonicalName(); + final String cacheKey = "ClassDeclaredFields-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Field[].class).orElseGet(() -> { Field[] res = clazz.getDeclaredFields(); cacheManager.cacheObject(cacheKey, res); @@ -346,7 +346,7 @@ private Field[] getDeclaredFields(final Class clazz) { * @return true if the target class uses the builder pattern */ public boolean hasAccessibleConstructors(final Class targetClass) { - final String cacheKey = "HasAccessibleConstructors-" + targetClass.getCanonicalName(); + final String cacheKey = "HasAccessibleConstructors-" + targetClass.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = stream(targetClass.getDeclaredConstructors()).anyMatch(constructor -> isPublic(constructor.getModifiers())); cacheManager.cacheObject(cacheKey, res); @@ -362,7 +362,7 @@ public boolean hasAccessibleConstructors(final Class targetClass) { * @return true if the target class uses the builder pattern */ public boolean usesBuilderPattern(final Constructor constructor, final Class targetClass) { - final String cacheKey = "UsesBuilderPattern-" + constructor.getDeclaringClass().getCanonicalName(); + final String cacheKey = "UsesBuilderPattern-" + constructor.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = !isPublic(constructor.getModifiers()) && isNotEmpty(targetClass.getDeclaredClasses()); cacheManager.cacheObject(cacheKey, res); @@ -378,7 +378,7 @@ public boolean usesBuilderPattern(final Constructor constructor, final Class */ public Constructor getAllArgsConstructor(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "AllArgsConstructor-" + clazz.getCanonicalName(); + final String cacheKey = "AllArgsConstructor-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { Constructor constructor = getAllArgsConstructor(clazz.getDeclaredConstructors()); cacheManager.cacheObject(cacheKey, constructor); @@ -395,7 +395,7 @@ public Constructor getAllArgsConstructor(final Constructor[] constructors) { if (isEmpty(constructors)) { throw new InvalidBeanException("No constructors available"); } - final String cacheKey = "AllArgsConstructor-" + constructors[0].getDeclaringClass().getCanonicalName(); + final String cacheKey = "AllArgsConstructor-" + constructors[0].getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { final Constructor constructor = max(asList(constructors), comparing(Constructor::getParameterCount)); cacheManager.cacheObject(cacheKey, constructor); @@ -409,7 +409,7 @@ public Constructor getAllArgsConstructor(final Constructor[] constructors) { * @return the constructor parameters */ public Parameter[] getConstructorParameters(final Constructor constructor) { - final String cacheKey = "ConstructorParams-" + constructor.getDeclaringClass().getCanonicalName() + '-' + constructor.getParameterCount(); + final String cacheKey = "ConstructorParams-" + constructor.getDeclaringClass().getName() + '-' + constructor.getParameterCount(); return cacheManager.getFromCache(cacheKey, Parameter[].class).orElseGet(() -> { final Parameter[] parameters = constructor.getParameters(); cacheManager.cacheObject(cacheKey, parameters); @@ -424,7 +424,7 @@ public Parameter[] getConstructorParameters(final Constructor constructor) { * @return true if the field is available, false otherwise */ public boolean hasField(final Object target, final String fieldName) { - final String cacheKey = "ClassHasField-" + target.getClass().getCanonicalName() + '-' + fieldName; + final String cacheKey = "ClassHasField-" + target.getClass().getName() + '-' + fieldName; return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { boolean hasField; try { @@ -448,7 +448,7 @@ public boolean hasField(final Object target, final String fieldName) { */ public boolean hasSetterMethods(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "HasSetterMethods-" + clazz.getCanonicalName(); + final String cacheKey = "HasSetterMethods-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class) .orElseGet(() -> { final Boolean res = stream(getDeclaredMethods(clazz)).anyMatch(reflectionUtils::isSetter); @@ -464,7 +464,7 @@ public boolean hasSetterMethods(final Class clazz) { */ private Method[] getDeclaredMethods(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "DeclaredMethods-" + clazz.getCanonicalName(); + final String cacheKey = "DeclaredMethods-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Method[].class) .orElseGet(() -> { final Method[] res = clazz.getDeclaredMethods(); @@ -501,7 +501,7 @@ private boolean hasNotFinalFields(final Class clazz) { * @return true if it has private final field, false otherwise. */ private boolean hasFieldsMatchingCondition(final Class clazz, final Predicate filterPredicate, final String cacheKey) { - return cacheManager.getFromCache(cacheKey + clazz.getCanonicalName(), Boolean.class).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey + clazz.getName(), Boolean.class).orElseGet(() -> { boolean res = stream(getDeclaredFields(clazz)) //.parallel() .anyMatch(filterPredicate); @@ -509,7 +509,7 @@ private boolean hasFieldsMatchingCondition(final Class clazz, final Predicate Class superclass = clazz.getSuperclass(); res = hasFieldsMatchingCondition(superclass, filterPredicate, cacheKey); } - cacheManager.cacheObject(cacheKey + clazz.getCanonicalName(), res); + cacheManager.cacheObject(cacheKey + clazz.getName(), res); return res; }); } @@ -521,7 +521,7 @@ private boolean hasFieldsMatchingCondition(final Class clazz, final Predicate * @return true if any of the parameter contains the annotation, false otherwise. */ public boolean containsAnnotation(final Constructor constructor, final Class annotationClass) { - final String cacheKey = "ConstructorHasAnnotation-" + constructor.getDeclaringClass().getCanonicalName() + '-' + annotationClass.getCanonicalName(); + final String cacheKey = "ConstructorHasAnnotation-" + constructor.getDeclaringClass().getName() + '-' + annotationClass.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean containsAnnotation = stream(constructor.getParameters()) .noneMatch(parameter -> isNull(parameter.getAnnotation(annotationClass))); @@ -537,7 +537,7 @@ public boolean containsAnnotation(final Constructor constructor, final Class annotationClass) { - final String cacheKey = "AllParameterAnnotatedWith-" + constructor.getDeclaringClass().getCanonicalName() + '-' + annotationClass.getCanonicalName(); + final String cacheKey = "AllParameterAnnotatedWith-" + constructor.getDeclaringClass().getName() + '-' + annotationClass.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean notAllAnnotatedWith = stream(constructor.getParameters()) .allMatch(parameter -> nonNull(parameter.getAnnotation(annotationClass))); @@ -552,7 +552,7 @@ public boolean allParameterAnnotatedWith(final Constructor constructor, final Cl * @return true if some parameters names are not defined, false otherwise. */ public boolean areParameterNamesAvailable(final Constructor constructor) { - final String cacheKey = "AreParameterNamesAvailable-" + constructor.getDeclaringClass().getCanonicalName(); + final String cacheKey = "AreParameterNamesAvailable-" + constructor.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = stream(getConstructorParameters(constructor)) .anyMatch(Parameter::isNamePresent); @@ -567,7 +567,7 @@ public boolean areParameterNamesAvailable(final Constructor constructor) { * @return the class type {@link ClassType} */ public ClassType getClassType(final Class clazz) { - final String cacheKey = "ClassType-" + clazz.getCanonicalName(); + final String cacheKey = "ClassType-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, ClassType.class).orElseGet(() -> { final ClassType classType; boolean hasFinalFields = hasFinalFields(clazz); @@ -594,7 +594,7 @@ public ClassType getClassType(final Class clazz) { @SuppressWarnings("unchecked") public List getSetterMethods(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "SetterMethods-" + clazz.getCanonicalName(); + final String cacheKey = "SetterMethods-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List setterMethods = new LinkedList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { @@ -614,7 +614,7 @@ public List getSetterMethods(final Class clazz) { * @return the default value of a primitive type */ public Object getDefaultTypeValue(final Class objectType) { - final String cacheKey = "DefaultTypeValue-" + objectType.getCanonicalName(); + final String cacheKey = "DefaultTypeValue-" + objectType.getName(); return cacheManager.getFromCache(cacheKey, Object.class).orElseGet(() -> { final Object defaultValue = isPrimitiveType(objectType) ? defaultValue(objectType) : null; cacheManager.cacheObject(cacheKey, defaultValue); @@ -630,7 +630,7 @@ public Object getDefaultTypeValue(final Class objectType) { */ @SuppressWarnings("unchecked") public List getNotFinalFields(final Class clazz, final Boolean skipStatic) { - final String cacheKey = "NotFinalFields-" + clazz.getCanonicalName() + "-" + skipStatic; + final String cacheKey = "NotFinalFields-" + clazz.getName() + "-" + skipStatic; return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { List notFinalFields = getDeclaredFields(clazz, skipStatic) .stream() diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index bddd5f337..ecf7ab863 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -105,7 +105,7 @@ private Object invokeMethod(final Method method, final Object target, final Obje * @return true if the method is a setter method, false otherwise */ public boolean isSetter(final Method method) { - final String cacheKey = "IsSetter-" + method.getDeclaringClass().getCanonicalName() + '-' + method.getName(); + final String cacheKey = "IsSetter-" + method.getDeclaringClass().getName() + '-' + method.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { boolean res = isPublic(method.getModifiers()) && method.getName().matches(SETTER_METHOD_NAME_REGEX) @@ -156,7 +156,7 @@ public Object getFieldValue(final Object target, final String fieldName, final C * @return the getter method */ private Method getGetterMethod(final Class fieldClass, final String fieldName, final Class fieldType) { - final String cacheKey = "GetterMethod-" + fieldClass.getCanonicalName() + '-' + fieldName; + final String cacheKey = "GetterMethod-" + fieldClass.getName() + '-' + fieldName; return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { Method method = fieldClass.getMethod(getGetterMethodPrefix(fieldType) + capitalize(fieldName)); @@ -164,10 +164,10 @@ private Method getGetterMethod(final Class fieldClass, final String fieldName return method; } catch (NoSuchMethodException e) { if (new ClassUtils().hasField(fieldClass, fieldName)) { - throw new MissingMethodException(fieldClass.getCanonicalName() + " does not allow to get value for field: " + fieldName + throw new MissingMethodException(fieldClass.getName() + " does not allow to get value for field: " + fieldName + ". Is a getter method defined?"); } else { - throw new MissingFieldException(fieldClass.getCanonicalName() + " hasn't a field called: " + fieldName + "."); + throw new MissingFieldException(fieldClass.getName() + " hasn't a field called: " + fieldName + "."); } } }); @@ -181,7 +181,7 @@ private Method getGetterMethod(final Class fieldClass, final String fieldName * @return the annotation */ public A getFieldAnnotation(final Field field, final Class annotationClazz) { - final String cacheKey = "FieldAnnotation-" + field.getDeclaringClass().getCanonicalName() + "-" + field.getName() + "-" + annotationClazz.getName(); + final String cacheKey = "FieldAnnotation-" + field.getDeclaringClass().getName() + "-" + field.getName() + "-" + annotationClazz.getName(); return cacheManager.getFromCache(cacheKey, annotationClazz).orElseGet(() -> { A annotation = null; if (field.isAnnotationPresent(annotationClazz)) { @@ -247,24 +247,24 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { - final String cacheKey = "ClassDeclaredField-" + targetClass.getName() + "-" + fieldName; - return cacheManager.getFromCache(cacheKey, Field.class).orElseGet(() -> { - Field field; - try { - field = targetClass.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - if (!targetClass.getSuperclass().equals(Object.class)) { - field = getDeclaredField(fieldName, targetClass.getSuperclass()); - } else { - throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); - } - } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); +// final String cacheKey = "ClassDeclaredField-" + targetClass.getName() + "-" + fieldName; +// return cacheManager.getFromCache(cacheKey, Field.class).orElseGet(() -> { + Field field; + try { + field = targetClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + if (!targetClass.getSuperclass().equals(Object.class)) { + field = getDeclaredField(fieldName, targetClass.getSuperclass()); + } else { + throw new MissingFieldException(targetClass.getName() + " does not contain field: " + fieldName); } - cacheManager.cacheObject(cacheKey, field); - return field; - }); + } catch (final Exception e) { + handleReflectionException(e); + throw new IllegalStateException(e); + } +// cacheManager.cacheObject(cacheKey, field); + return field; +// }); } /** @@ -345,9 +345,9 @@ private boolean isOptionalType(final Object object) { * @return the method prefix (get or is) */ private String getGetterMethodPrefix(final Class fieldType) { - final String cacheKey = "GetterMethodPrefix-" + fieldType.getCanonicalName(); + final String cacheKey = "GetterMethodPrefix-" + fieldType.getName(); return cacheManager.getFromCache(cacheKey, String.class).orElseGet(() -> { - String res = Boolean.class.equals(fieldType) || fieldType.getCanonicalName().equals(BOOLEAN) ? IS.getPrefix() : GET.getPrefix(); + String res = Boolean.class.equals(fieldType) || fieldType.getName().equals(BOOLEAN) ? IS.getPrefix() : GET.getPrefix(); cacheManager.cacheObject(cacheKey, res); return res; }); @@ -362,7 +362,7 @@ private String getGetterMethodPrefix(final Class fieldType) { * @throws MissingMethodException if the method does not exists */ public Method getSetterMethodForField(final Class fieldClass, final String fieldName, final Class fieldType) { - final String cacheKey = "SetterMethod-" + fieldClass.getCanonicalName() + '-' + fieldName; + final String cacheKey = "SetterMethod-" + fieldClass.getName() + '-' + fieldName; return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { Method method = fieldClass.getMethod(SET.getPrefix() + capitalize(fieldName), fieldType); @@ -380,7 +380,7 @@ public Method getSetterMethodForField(final Class fieldClass, final String fi * @return the generic type class */ public Class getGenericFieldType(final Field field) { - final String cacheKey = "GenericFieldType-" + field.getDeclaringClass().getCanonicalName() + '-' + field.getName(); + final String cacheKey = "GenericFieldType-" + field.getDeclaringClass().getName() + '-' + field.getName(); return cacheManager.getFromCache(cacheKey, Class.class).orElseGet(() -> { Class res = null; if (ParameterizedType.class.isAssignableFrom(field.getGenericType().getClass())) { @@ -408,9 +408,9 @@ public MapType getMapGenericType(final Type fieldType, final String declaringCla if (isNull(fieldClass) || !Map.class.isAssignableFrom(fieldClass)) { throw new IllegalArgumentException( "Type for object: " + fieldName + " is invalid. " - + "It cannot be assigned from: " + Map.class.getCanonicalName() + "."); + + "It cannot be assigned from: " + Map.class.getName() + "."); } - final String cacheKey = "MapGenericFieldType-" + fieldClass.getCanonicalName() + '-' + fieldName; + final String cacheKey = "MapGenericFieldType-" + fieldClass.getName() + '-' + fieldName; return cacheManager.getFromCache(cacheKey, MapType.class).orElseGet(() -> { final ParameterizedType genericType = (ParameterizedType) fieldType; final MapElemType keyType = getMapElemType(genericType.getActualTypeArguments()[0], declaringClass, fieldName); @@ -494,7 +494,7 @@ public Class getArgumentTypeClass(final Object argument, final String declari * @return the array class */ public Class getArrayType(final Field arrayField) { - final String cacheKey = "ArrayType-" + arrayField.getDeclaringClass().getCanonicalName(); + final String cacheKey = "ArrayType-" + arrayField.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Class.class).orElseGet(() -> { final Class arrayType = arrayField.getType().getComponentType(); cacheManager.cacheObject(cacheKey, arrayType); diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java index 8ed0265ef..e1d2cb72d 100644 --- a/src/main/java/com/hotels/beans/utils/ValidationUtils.java +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -88,7 +88,7 @@ public final void validate(final K k) { final Set> constraintViolations = getValidator().validate(k); if (!constraintViolations.isEmpty()) { final String errors = constraintViolations.stream() - .map(cv -> cv.getRootBeanClass().getCanonicalName() + .map(cv -> cv.getRootBeanClass().getName() + DOT.getSymbol() + cv.getPropertyPath() + SPACE diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/src/test/java/com/hotels/beans/BeanUtilsTest.java index 7c6532754..712827a98 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -30,7 +30,7 @@ import java.util.stream.IntStream; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -54,8 +54,8 @@ public class BeanUtilsTest { /** * Initialized mocks. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java index bd05d3217..907d1d78c 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java @@ -20,7 +20,7 @@ import static org.mockito.MockitoAnnotations.initMocks; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** @@ -41,8 +41,8 @@ public class CacheManagerFactoryTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index 493ab2f52..b7af797e1 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -24,7 +24,7 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** @@ -42,8 +42,8 @@ public class CacheManagerTest { /** * Initializes mock. */ - @BeforeMethod - public void before() { + @BeforeClass + public void beforeClass() { underTest = new CacheManager(new ConcurrentHashMap<>()); } diff --git a/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/src/test/java/com/hotels/beans/performance/PerformanceTest.java index c7087dd57..95ed20bf6 100644 --- a/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -35,7 +35,6 @@ import org.apache.commons.lang3.time.StopWatch; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -94,13 +93,6 @@ public class PerformanceTest { @BeforeClass public void beforeClass() { initObjects(); - } - - /** - * Initialized mocks. - */ - @BeforeMethod - public void beforeMethod() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index cc62631ab..812e084de 100644 --- a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -27,7 +27,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -59,10 +59,9 @@ public class ArrayPopulatorTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); - MIXED_TO_FOO_STATIC_FIELDS_OBJECTS.setNormalField(VAL_1); } /** @@ -113,6 +112,7 @@ public Object[][] dataProvider() { * @return an array containing an instance of {@link MixedToFooStaticField}. */ private static MixedToFooStaticField[] createMixedToFooArray() { + MIXED_TO_FOO_STATIC_FIELDS_OBJECTS.setNormalField(VAL_1); return new MixedToFooStaticField[] {MIXED_TO_FOO_STATIC_FIELDS_OBJECTS}; } } diff --git a/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index 5fd1ef31b..647edc6be 100644 --- a/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -27,7 +27,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -53,14 +53,14 @@ public class PopulatorFactoryTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } /** * Tests that the method: {@code defaultValue} returns the expected result for the given type. - * @param type the type for wich a populator needs to be found + * @param type the type for which a populator needs to be found * @param expectedResult the expected populator */ @Test(dataProvider = "dataProvider") diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index baef9fb19..bfc499825 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -175,9 +175,9 @@ public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(f private Object[][] dataCompositeFieldNameTesting() { return new Object[][] { {"Test that, in case a destination object field is contained into a nested object of the source field, defining a composite FieldMapping" - + "the field is correctly valorized.", fromFoo, fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObject().getPhoneNumbers()}, + + "the field is correctly set.", fromFoo, fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObject().getPhoneNumbers()}, {"Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping}" - + " the field is correctly valorized even if some of them are null.", fromFooWithNullProperties, fromFooWithNullProperties.getName(), + + " the field is correctly set even if some of them are null.", fromFooWithNullProperties, fromFooWithNullProperties.getName(), fromFooWithNullProperties.getId(), null} }; } @@ -425,9 +425,9 @@ public void testTransformationReturnsAMeaningfulException() { "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration. " + "Error message: argument type mismatch"; - String targetClassName = targetClass.getCanonicalName(); + String targetClassName = targetClass.getName(); String expectedExceptionMessage = - format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getCanonicalName()); + format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getName()); //WHEN Exception raisedException = null; diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 7552ded66..c74c0ce00 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -37,7 +37,7 @@ import javax.validation.constraints.NotNull; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -94,8 +94,8 @@ public class ClassUtilsTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index 3c222c077..2265c0eab 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -41,10 +41,10 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; import com.hotels.beans.error.MissingMethodException; import com.hotels.beans.error.MissingFieldException; @@ -73,8 +73,8 @@ public class ReflectionUtilsTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java index 460512340..7c90cd1db 100644 --- a/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java @@ -21,7 +21,7 @@ import static org.mockito.MockitoAnnotations.initMocks; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -48,8 +48,8 @@ public class ValidationUtilsTest { /** * Initialized mocks. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } From 0aebf8b8ff5f7931a3739b7ea633c49d22d2e776 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 10 Apr 2019 23:59:41 +0200 Subject: [PATCH 0404/1786] restored getDeclaredField caching --- .../hotels/beans/utils/ReflectionUtils.java | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index ecf7ab863..93d1d724b 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -247,24 +247,25 @@ private Object getFieldValue(final Object target, final String fieldName) { * @return the field corresponding to the given name. */ public Field getDeclaredField(final String fieldName, final Class targetClass) { -// final String cacheKey = "ClassDeclaredField-" + targetClass.getName() + "-" + fieldName; -// return cacheManager.getFromCache(cacheKey, Field.class).orElseGet(() -> { - Field field; - try { - field = targetClass.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - if (!targetClass.getSuperclass().equals(Object.class)) { - field = getDeclaredField(fieldName, targetClass.getSuperclass()); - } else { - throw new MissingFieldException(targetClass.getName() + " does not contain field: " + fieldName); + final String cacheKey = "ClassDeclaredField-" + targetClass.getName() + "-" + fieldName; + return cacheManager.getFromCache(cacheKey, Field.class).orElseGet(() -> { + Field field; + try { + field = targetClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + Class superclass = targetClass.getSuperclass(); + if (!superclass.equals(Object.class)) { + field = getDeclaredField(fieldName, superclass); + } else { + throw new MissingFieldException(targetClass.getName() + " does not contain field: " + fieldName); + } + } catch (final Exception e) { + handleReflectionException(e); + throw new IllegalStateException(e); } - } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); - } -// cacheManager.cacheObject(cacheKey, field); - return field; -// }); + cacheManager.cacheObject(cacheKey, field); + return field; + }); } /** From 3a610c961696d26737b9d1ecd58a2f75f573c738 Mon Sep 17 00:00:00 2001 From: antimo Date: Thu, 11 Apr 2019 12:29:54 +0200 Subject: [PATCH 0405/1786] Updated method isValidBuildMethod with a more concise code --- .../com/hotels/beans/utils/ClassUtils.java | 79 ++++++++----------- .../beans/sample/builder/BuilderTest.java | 15 ++++ .../hotels/beans/sample/builder/ToFoo.java | 15 ++++ 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 6e7ff2ef9..e04d7504d 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -16,32 +16,9 @@ package com.hotels.beans.utils; -import static java.lang.reflect.Modifier.isFinal; -import static java.lang.reflect.Modifier.isPrivate; -import static java.lang.reflect.Modifier.isPublic; -import static java.lang.reflect.Modifier.isStatic; -import static java.util.Arrays.asList; -import static java.util.Arrays.stream; -import static java.util.Collections.max; -import static java.util.Comparator.comparing; -import static java.util.Objects.isNull; -import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; -import static java.util.stream.Collectors.toList; - -import static org.apache.commons.lang3.ArrayUtils.isEmpty; -import static org.apache.commons.lang3.ArrayUtils.isNotEmpty; - -import static com.hotels.beans.utils.ValidationUtils.notNull; -import static com.hotels.beans.base.Defaults.defaultValue; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.constant.ClassType.IMMUTABLE; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.ClassType.BUILDER; -import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_FIELD; -import static com.hotels.beans.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; -import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.constant.ClassType; +import com.hotels.beans.error.InvalidBeanException; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; @@ -58,9 +35,29 @@ import java.util.function.Predicate; import java.util.stream.Stream; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.constant.ClassType; -import com.hotels.beans.error.InvalidBeanException; +import static com.hotels.beans.base.Defaults.defaultValue; +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.constant.ClassType.BUILDER; +import static com.hotels.beans.constant.ClassType.IMMUTABLE; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; +import static com.hotels.beans.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; +import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; +import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_FIELD; +import static com.hotels.beans.utils.ValidationUtils.notNull; +import static java.lang.reflect.Modifier.isFinal; +import static java.lang.reflect.Modifier.isPrivate; +import static java.lang.reflect.Modifier.isPublic; +import static java.lang.reflect.Modifier.isStatic; +import static java.util.Arrays.asList; +import static java.util.Arrays.stream; +import static java.util.Collections.max; +import static java.util.Comparator.comparing; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.toList; +import static org.apache.commons.lang3.ArrayUtils.isEmpty; /** * Reflection utils for Class objects. @@ -373,25 +370,19 @@ public boolean usesBuilderPattern(final Constructor constructor, final Class }); } - /** - * Check if in nested class of @superclass is present a valid build method - * @param superclass - * @return true if in the nested class is present a valid build method - */ + private boolean isValidBuildMethod(final Class superclass) { final String build = "build"; String cacheKey = "build-method-" + superclass.getCanonicalName(); - Method[] declaredMethods = getDeclaredMethods(getNestedClass(superclass).get(0)); return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { - Method buildMethod = (stream(declaredMethods) - .filter(method -> method.getName().equals(build)) - .filter(method -> method.getReturnType().equals(superclass)) - .findFirst()) - .orElse(null); - cacheManager.cacheObject(cacheKey, buildMethod); - boolean res = buildMethod != null ? true : false; - return res; - }); + List nestedClasses = getNestedClass(superclass); + boolean res = + !nestedClasses.isEmpty() + && stream(getDeclaredMethods(nestedClasses.get(0))) + .anyMatch(method -> method.getName().equals(build) && method.getReturnType().equals(superclass)); + cacheManager.cacheObject(cacheKey, res); + return res; + }); } /** diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java index eb6d39390..d1fbd1ea9 100644 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java @@ -1,3 +1,18 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.sample.builder; import com.hotels.beans.sample.FromFooWithBuilder; diff --git a/src/test/java/com/hotels/beans/sample/builder/ToFoo.java b/src/test/java/com/hotels/beans/sample/builder/ToFoo.java index f71d60b0e..d70889388 100644 --- a/src/test/java/com/hotels/beans/sample/builder/ToFoo.java +++ b/src/test/java/com/hotels/beans/sample/builder/ToFoo.java @@ -1,3 +1,18 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.sample.builder; import lombok.Getter; From cd0606140f4ebc27eb0d19574b792ffe910c28c2 Mon Sep 17 00:00:00 2001 From: antimo Date: Thu, 11 Apr 2019 19:22:33 +0200 Subject: [PATCH 0406/1786] Bean copy to class based on Builder Pattern working (Lombok and manual constucted class). TODO: Apply checkStyle rule, some test (multiple constructor on builder for example) and code review --- .../beans/transformer/TransformerImpl.java | 63 ++++++++++------ .../hotels/beans/utils/ReflectionUtils.java | 59 +++++++++------ .../beans/sample/builder/BuilderTest.java | 4 +- .../builder/{ToFoo.java => BuilderToFoo.java} | 37 +++++++--- .../sample/builder/LombokBuilderToFoo.java | 32 +++++++++ .../BuilderObjectTransformationTest.java | 72 +++++++++++++++++++ 6 files changed, 214 insertions(+), 53 deletions(-) rename src/test/java/com/hotels/beans/sample/builder/{ToFoo.java => BuilderToFoo.java} (53%) create mode 100644 src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java create mode 100644 src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 39527b49d..17232edf3 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -16,40 +16,42 @@ package com.hotels.beans.transformer; -import static java.util.Arrays.stream; -import static java.util.Objects.isNull; -import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; -import static java.util.stream.Collectors.joining; -import static java.util.stream.IntStream.range; - -import static org.apache.commons.lang3.StringUtils.EMPTY; - -import static com.hotels.beans.constant.Punctuation.DOT; -import static com.hotels.beans.constant.Punctuation.COMMA; -import static com.hotels.beans.constant.Punctuation.LPAREN; -import static com.hotels.beans.constant.Punctuation.RPAREN; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.base.Defaults.defaultValue; -import static com.hotels.beans.populator.PopulatorFactory.getPopulator; +import com.hotels.beans.annotation.ConstructorArg; +import com.hotels.beans.constant.ClassType; +import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.error.MissingFieldException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.List; import java.util.Optional; -import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.constant.ClassType; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.error.MissingFieldException; +import static com.hotels.beans.base.Defaults.defaultValue; +import static com.hotels.beans.constant.ClassType.BUILDER; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; +import static com.hotels.beans.constant.Punctuation.COMMA; +import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.constant.Punctuation.LPAREN; +import static com.hotels.beans.constant.Punctuation.RPAREN; +import static com.hotels.beans.populator.PopulatorFactory.getPopulator; +import static java.util.Arrays.stream; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.joining; +import static java.util.stream.IntStream.range; +import static org.apache.commons.lang3.StringUtils.EMPTY; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * The implementations are provided by BeanUtils. */ public class TransformerImpl extends AbstractTransformer { + /** * {@inheritDoc} */ @@ -66,6 +68,25 @@ protected final K transform(final T sourceObj, final Class t } catch (Exception e) { throw new InvalidBeanException(e.getMessage(), e); } + } else if (classType.is(BUILDER)){ + Object builder = null; + Class builderClass = targetClass.getDeclaredClasses()[0]; + Constructor declaredConstructor = builderClass.getDeclaredConstructors()[0]; + declaredConstructor.setAccessible(true); + try { + builder = declaredConstructor.newInstance(); + } catch (InstantiationException e) { + throw new InvalidBeanException("Cannot instantiate class: " + builderClass.getName(), e); + } catch (IllegalAccessException e) { + throw new InvalidBeanException("Illegal access exception to default constructor defined for class: " + builderClass.getName(), e); + } catch (InvocationTargetException e) { + throw new InvalidBeanException(String.format("Error while invoking default constructor defined for class: $1. Are you sure that only default constructor is defined in the builder ?" , builderClass.getName()), e); + } + injectAllFields(sourceObj, builder, breadcrumb); + Method method; + method = reflectionUtils.getBuildMethod(builderClass); + method.setAccessible(true); + k = (K)reflectionUtils.invokeMethod(method, builder); } else { k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); if (classType.is(MIXED)) { diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 63ca3a47d..ecf9b1af5 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -16,18 +16,13 @@ package com.hotels.beans.utils; -import static java.lang.reflect.Modifier.isPublic; -import static java.util.Objects.isNull; -import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; - -import static org.apache.commons.lang3.StringUtils.capitalize; - -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.constant.MethodPrefix.GET; -import static com.hotels.beans.constant.MethodPrefix.IS; -import static com.hotels.beans.constant.MethodPrefix.SET; -import static com.hotels.beans.utils.ValidationUtils.notNull; +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.error.MissingFieldException; +import com.hotels.beans.error.MissingMethodException; +import com.hotels.beans.model.EmptyValue; +import com.hotels.beans.model.ItemType; +import com.hotels.beans.model.MapElemType; +import com.hotels.beans.model.MapType; import java.lang.annotation.Annotation; import java.lang.reflect.Field; @@ -41,13 +36,16 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.error.MissingFieldException; -import com.hotels.beans.error.MissingMethodException; -import com.hotels.beans.model.EmptyValue; -import com.hotels.beans.model.ItemType; -import com.hotels.beans.model.MapElemType; -import com.hotels.beans.model.MapType; +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.constant.MethodPrefix.GET; +import static com.hotels.beans.constant.MethodPrefix.IS; +import static com.hotels.beans.constant.MethodPrefix.SET; +import static com.hotels.beans.utils.ValidationUtils.notNull; +import static java.lang.reflect.Modifier.isPublic; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; +import static java.util.Optional.ofNullable; +import static org.apache.commons.lang3.StringUtils.capitalize; /** * Reflection class utils. @@ -73,6 +71,12 @@ public final class ReflectionUtils { */ private final CacheManager cacheManager; + /** + * Name of method inside the Builder Class + */ + private final String nameOfBuilderMethod = "build"; + + /** * Default constructor. */ @@ -87,7 +91,7 @@ public ReflectionUtils() { * @param args the method parameters * @return the method result */ - private Object invokeMethod(final Method method, final Object target, final Object... args) { + public Object invokeMethod(final Method method, final Object target, final Object... args) { notNull(method, "method cannot be null!"); notNull(target, "target cannot be null!"); try { @@ -193,6 +197,21 @@ public A getFieldAnnotation(final Field field, final Clas }); } + + public Method getBuildMethod(Class builderClass) { + final String cacheKey = "BuildMethod-" + builderClass.getCanonicalName(); + return ofNullable(cacheManager.getFromCache(cacheKey, Method.class)).orElseGet(() -> { + try { + Method method = builderClass.getMethod(nameOfBuilderMethod, null); + cacheManager.cacheObject(cacheKey, method); + return method; + } catch (NoSuchMethodException e) { + throw new MissingMethodException(String.format("Error while getting method $1 in class $2 " , nameOfBuilderMethod, builderClass.getName()) + e.getMessage()); + } + }); + } + + /** * Returns (if existing) the constructor parameter's given type annotation. * @param parameter the field that should have the annotation diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java index d1fbd1ea9..111176f70 100644 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java @@ -30,12 +30,12 @@ public class BuilderTest { @Test public void checkDeclaredClassInManualBuilder(){ // WHEN - Class[] declaredClasses = ToFoo.class.getDeclaredClasses(); + Class[] declaredClasses = BuilderToFoo.class.getDeclaredClasses(); // TODO check for null value... Class clazz = declaredClasses[0]; // THEN - assertSame(clazz,ToFoo.Builder.class); + assertSame(clazz, BuilderToFoo.Builder.class); } diff --git a/src/test/java/com/hotels/beans/sample/builder/ToFoo.java b/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java similarity index 53% rename from src/test/java/com/hotels/beans/sample/builder/ToFoo.java rename to src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java index d70889388..11c2c7a95 100644 --- a/src/test/java/com/hotels/beans/sample/builder/ToFoo.java +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java @@ -15,24 +15,38 @@ */ package com.hotels.beans.sample.builder; +import com.hotels.beans.sample.mutable.MutableToSubFoo; import lombok.Getter; import lombok.Setter; import java.math.BigInteger; +import java.util.List; @Getter @Setter -public class ToFoo { +public class BuilderToFoo { private String name; private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; - private ToFoo() {} + + + private BuilderToFoo() {} // getters - public static class Builder { - private String name; - private BigInteger id; + static class Builder { + + public Builder(){}; + + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + public Builder withName(String name) { this.name = name; @@ -44,11 +58,14 @@ public Builder withId(BigInteger id) { return this; } - public ToFoo build() { - ToFoo toFoo = new ToFoo(); - toFoo.id = this.id; - toFoo.name = this.name; - return toFoo; + public BuilderToFoo build() { + BuilderToFoo builderToFoo = new BuilderToFoo(); + builderToFoo.id = this.id; + builderToFoo.name = this.name; + builderToFoo.list = this.list; + builderToFoo.nestedObjectList = this.nestedObjectList; + builderToFoo.nestedObject = this.nestedObject; + return builderToFoo; } } } \ No newline at end of file diff --git a/src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java b/src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java new file mode 100644 index 000000000..288c85b27 --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.hotels.beans.sample.builder; + +import com.hotels.beans.sample.FromSubFoo; +import lombok.Builder; + +import java.math.BigInteger; +import java.util.List; + +@Builder +public class LombokBuilderToFoo { + private final String name; + private BigInteger id; + private final List nestedObjectList; + private final List list; + private final FromSubFoo nestedObject; + +} diff --git a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java new file mode 100644 index 000000000..c3145b01e --- /dev/null +++ b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import com.hotels.beans.sample.builder.BuilderToFoo; +import com.hotels.beans.sample.builder.LombokBuilderToFoo; +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; +import static org.junit.Assert.assertThat; +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * Unit test for all {@link Transformer} functions related to Object based on Builder Pattern. + */ +public class BuilderObjectTransformationTest extends AbstractTransformerTest { + /** + * The class to be tested. + */ + @InjectMocks + private TransformerImpl underTest; + + /** + * Initialized mocks. + */ + @BeforeMethod + public void beforeMethod() { + initMocks(this); + } + + /** + * Test mutable beans are correctly copied. + */ + @Test + public void testBuilderWithLombok() { + //GIVEN + + //WHEN + LombokBuilderToFoo actual = underTest.transform(fromFoo, LombokBuilderToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + + @Test + public void testManualBuilder() { + //GIVEN + + //WHEN + BuilderToFoo actual = underTest.transform(fromFoo, BuilderToFoo.class); + + //THEN + assertThat(actual, sameBeanAs(fromFoo)); + } + +} From 9bae99bd6b2ebfb00c5cf4654d32fa4ef0599cc5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 14 Apr 2019 17:02:47 +0200 Subject: [PATCH 0407/1786] Modified condition order on method isPrimitiveType --- .../com/hotels/beans/cache/CacheManager.java | 6 ++--- .../com/hotels/beans/utils/ClassUtils.java | 7 ++---- .../hotels/beans/cache/CacheManagerTest.java | 22 ------------------- 3 files changed, 4 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/src/main/java/com/hotels/beans/cache/CacheManager.java index 0c59a91e6..9c280b389 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -19,8 +19,6 @@ import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; -import static com.hotels.beans.utils.ValidationUtils.notNull; - import static lombok.AccessLevel.PRIVATE; import static lombok.AccessLevel.PROTECTED; @@ -74,8 +72,8 @@ public void cacheObject(final String cacheKey, final T object, final Object * @return the cached object or {@code Optional.empty()} if not existing. */ public Optional getFromCache(final String cacheKey, final Class objectClass) { - notNull(cacheKey, "cacheKey cannot be null!"); - notNull(objectClass, "objectClass cannot be null!"); +// notNull(cacheKey, "cacheKey cannot be null!"); +// notNull(objectClass, "objectClass cannot be null!"); return ofNullable(cacheMap.get(cacheKey)).map(objectClass::cast); } diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index a94f46e9e..fffe3742b 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -93,7 +93,6 @@ public ClassUtils() { * @return true if is primitive or special type, false otherwise */ public boolean isPrimitiveOrSpecialType(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isPrimitiveOrSpecial-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = isPrimitiveType(clazz) || isSpecialType(clazz); @@ -108,10 +107,9 @@ public boolean isPrimitiveOrSpecialType(final Class clazz) { * @return true if is special type, false otherwise */ public boolean isPrimitiveType(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isPrimitive-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = clazz.isPrimitive() || clazz.equals(String.class) || Number.class.isAssignableFrom(clazz) || clazz.equals(Byte.class) || clazz.isEnum(); + final Boolean res = clazz.equals(String.class) || clazz.isPrimitive() || clazz.isEnum() || Number.class.isAssignableFrom(clazz); cacheManager.cacheObject(cacheKey, res); return res; }); @@ -123,7 +121,6 @@ public boolean isPrimitiveType(final Class clazz) { * @return true if is primitive type array, false otherwise */ public boolean isPrimitiveTypeArray(final Object object) { - notNull(object, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = object instanceof int[] || object instanceof char[] || object instanceof short[] @@ -140,7 +137,7 @@ public boolean isPrimitiveTypeArray(final Object object) { * @return true if is special type, false otherwise */ public boolean isSpecialType(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); +// notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isSpecial-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || Temporal.class.isAssignableFrom(clazz) diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index b7af797e1..d44083522 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -64,28 +64,6 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { assertSame(CACHED_VALUE, actual.get()); } - /** - * Tests that the method {@code getFromCache} throw exception when the cache key. - */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testGetFromCacheThrowsExceptionWhenTheCacheKeyIsNull() { - // GIVEN - - // WHEN - underTest.getFromCache(null, CACHED_OBJECT_CLASS); - } - - /** - * Tests that the method {@code getFromCache} throw exception when the cached value class is null. - */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testGetFromCacheThrowsExceptionWhenTheCachedValueClassIsNull() { - // GIVEN - - // WHEN - underTest.getFromCache(CACHE_KEY, null); - } - /** * Tests that the method {@code removeFromCache} really removes the object from the cache. */ From 8968bc55f2f7a80c1ab5c99bfb8f6cb46280ab7e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 14 Apr 2019 17:06:36 +0200 Subject: [PATCH 0408/1786] Modified condition order on method isPrimitiveTypeArray --- src/main/java/com/hotels/beans/utils/ClassUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index fffe3742b..7e44723d6 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -123,8 +123,8 @@ public boolean isPrimitiveType(final Class clazz) { public boolean isPrimitiveTypeArray(final Object object) { final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = object instanceof int[] || object instanceof char[] || object instanceof short[] - || object instanceof long[] || object instanceof byte[] || object instanceof float[] || object instanceof double[]; + final Boolean res = object instanceof int[] || object instanceof byte[] || object instanceof char[] + || object instanceof short[] || object instanceof long[] || object instanceof float[] || object instanceof double[]; cacheManager.cacheObject(cacheKey, res); return res; }); From b34581c183afbcd02a21f7733bfb09b306bc41b4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Apr 2019 22:13:27 +0200 Subject: [PATCH 0409/1786] Removed not null checks where possible --- src/main/java/com/hotels/beans/base/Defaults.java | 3 --- .../java/com/hotels/beans/cache/CacheManager.java | 2 -- src/main/java/com/hotels/beans/utils/ClassUtils.java | 12 ------------ .../java/com/hotels/beans/utils/ReflectionUtils.java | 5 ----- .../java/com/hotels/beans/base/DefaultsTest.java | 8 -------- .../com/hotels/beans/utils/ReflectionUtilsTest.java | 12 ------------ 6 files changed, 42 deletions(-) diff --git a/src/main/java/com/hotels/beans/base/Defaults.java b/src/main/java/com/hotels/beans/base/Defaults.java index fbfc5511e..feb773b18 100644 --- a/src/main/java/com/hotels/beans/base/Defaults.java +++ b/src/main/java/com/hotels/beans/base/Defaults.java @@ -18,8 +18,6 @@ import static java.lang.Boolean.FALSE; -import static com.hotels.beans.utils.ValidationUtils.notNull; - import static com.hotels.beans.utils.ClassUtils.isBoolean; import static com.hotels.beans.utils.ClassUtils.isByte; import static com.hotels.beans.utils.ClassUtils.isChar; @@ -44,7 +42,6 @@ public final class Defaults { * @return the default value of a primitive type. */ public static Object defaultValue(final Class type) { - notNull(type, "type cannot be null!"); Object res = null; if (isBoolean(type)) { res = FALSE; diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/src/main/java/com/hotels/beans/cache/CacheManager.java index 9c280b389..6a3e4c88b 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -72,8 +72,6 @@ public void cacheObject(final String cacheKey, final T object, final Object * @return the cached object or {@code Optional.empty()} if not existing. */ public Optional getFromCache(final String cacheKey, final Class objectClass) { -// notNull(cacheKey, "cacheKey cannot be null!"); -// notNull(objectClass, "objectClass cannot be null!"); return ofNullable(cacheMap.get(cacheKey)).map(objectClass::cast); } diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 7e44723d6..4c92105cc 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -32,7 +32,6 @@ import static org.apache.commons.lang3.ArrayUtils.isEmpty; import static org.apache.commons.lang3.ArrayUtils.isNotEmpty; -import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.constant.ClassType.IMMUTABLE; @@ -137,7 +136,6 @@ public boolean isPrimitiveTypeArray(final Object object) { * @return true if is special type, false otherwise */ public boolean isSpecialType(final Class clazz) { -// notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isSpecial-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || Temporal.class.isAssignableFrom(clazz) @@ -226,7 +224,6 @@ public static boolean isBoolean(final Class type) { */ @SuppressWarnings("unchecked") public List getPrivateFinalFields(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "PrivateFinalFields-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); @@ -249,7 +246,6 @@ public List getPrivateFinalFields(final Class clazz) { * @return the total matching item. */ public int getTotalFields(final Class clazz, final Predicate predicate) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "TotalFields-" + clazz.getName() + '-' + predicate; return cacheManager.getFromCache(cacheKey, Integer.class).orElseGet(() -> { List declaredFields = getDeclaredFields(clazz, true); @@ -278,7 +274,6 @@ public List getPrivateFields(final Class clazz) { */ @SuppressWarnings("unchecked") public List getPrivateFields(final Class clazz, final boolean skipFinal) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "PrivateFields-" + clazz.getName() + "-skipFinal-" + skipFinal; return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); @@ -304,7 +299,6 @@ public List getPrivateFields(final Class clazz, final boolean skipFina */ @SuppressWarnings("unchecked") public List getDeclaredFields(final Class clazz, final boolean skipStatic) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "DeclaredFields-" + clazz.getName() + "-skipStatic-" + skipStatic; return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new LinkedList<>(); @@ -374,7 +368,6 @@ public boolean usesBuilderPattern(final Constructor constructor, final Class * @return the all args constructor */ public Constructor getAllArgsConstructor(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "AllArgsConstructor-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { Constructor constructor = getAllArgsConstructor(clazz.getDeclaredConstructors()); @@ -444,7 +437,6 @@ public boolean hasField(final Object target, final String fieldName) { * @return true if has at least one setter method, false otherwise */ public boolean hasSetterMethods(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "HasSetterMethods-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class) .orElseGet(() -> { @@ -460,7 +452,6 @@ public boolean hasSetterMethods(final Class clazz) { * @return the class declared methods. */ private Method[] getDeclaredMethods(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "DeclaredMethods-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Method[].class) .orElseGet(() -> { @@ -476,7 +467,6 @@ private Method[] getDeclaredMethods(final Class clazz) { * @return true if it has private final field, false otherwise. */ public boolean hasFinalFields(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); return hasFieldsMatchingCondition(clazz, IS_FINAL_AND_NOT_STATIC_FIELD, "HasFinalNotStaticFields-"); } @@ -486,7 +476,6 @@ public boolean hasFinalFields(final Class clazz) { * @return true if it has private final field, false otherwise. */ private boolean hasNotFinalFields(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); return hasFieldsMatchingCondition(clazz, IS_NOT_FINAL_AND_NOT_STATIC_FIELD, "HasNotFinalNotStaticFields-"); } @@ -590,7 +579,6 @@ public ClassType getClassType(final Class clazz) { */ @SuppressWarnings("unchecked") public List getSetterMethods(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "SetterMethods-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List setterMethods = new LinkedList<>(); diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 93d1d724b..716a2d67d 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -26,7 +26,6 @@ import static com.hotels.beans.constant.MethodPrefix.GET; import static com.hotels.beans.constant.MethodPrefix.IS; import static com.hotels.beans.constant.MethodPrefix.SET; -import static com.hotels.beans.utils.ValidationUtils.notNull; import java.lang.annotation.Annotation; import java.lang.reflect.Field; @@ -87,8 +86,6 @@ public ReflectionUtils() { * @return the method result */ private Object invokeMethod(final Method method, final Object target, final Object... args) { - notNull(method, "method cannot be null!"); - notNull(target, "target cannot be null!"); try { return method.invoke(target, args); } catch (MissingFieldException | MissingMethodException e) { @@ -403,8 +400,6 @@ public Class getGenericFieldType(final Field field) { * @return the generic type class */ public MapType getMapGenericType(final Type fieldType, final String declaringClass, final String fieldName) { - notNull(fieldType, "fieldType cannot be null!"); - notNull(fieldName, "fieldName cannot be null!"); final Class fieldClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); if (isNull(fieldClass) || !Map.class.isAssignableFrom(fieldClass)) { throw new IllegalArgumentException( diff --git a/src/test/java/com/hotels/beans/base/DefaultsTest.java b/src/test/java/com/hotels/beans/base/DefaultsTest.java index ca7eadfd4..1aca49594 100644 --- a/src/test/java/com/hotels/beans/base/DefaultsTest.java +++ b/src/test/java/com/hotels/beans/base/DefaultsTest.java @@ -61,14 +61,6 @@ public DefaultsTest(final Class type, final Object expectedResult) { this.expectedResult = expectedResult; } - /** - * Tests that the method: {@code defaultValue} throws exception when type is null. - */ - @Test(expected = IllegalArgumentException.class) - public void testDefaultValueThrowsExceptionWhenTypeIsNull() { - underTest.defaultValue(null); - } - /** * Tests that the method: {@code defaultValue} returns the expected result for the given type. */ diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index 2265c0eab..b44dc5c21 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -36,7 +36,6 @@ import java.lang.reflect.Parameter; import java.lang.reflect.UndeclaredThrowableException; import java.math.BigInteger; -import java.util.List; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -161,17 +160,6 @@ public void testHandleReflectionExceptionThrowsUndeclaredThrowableExceptionWhenG underTest.handleReflectionException(exception); } - /** - * Tests that the method {@code getMapGenericType} throws Exception when the given type is not a map. - */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testGetMapGenericTypeThrowsIllegalArgumentExceptionWhenTheGivenTypeIsNotAMap() { - // GIVEN - - // WHEN - underTest.getMapGenericType(List.class, null, LIST_FIELD_NAME); - } - /** * Tests that the method {@code getGetterMethodPrefix} returns the expected value. * @param testCaseDescription the test case description From 147e1940fecf324ede387a665b4df3da4dc7b1b6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 10:21:38 +0200 Subject: [PATCH 0410/1786] Modified condition order --- .../com/hotels/beans/utils/ClassUtils.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 4c92105cc..1cdb60fc9 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -32,6 +32,7 @@ import static org.apache.commons.lang3.ArrayUtils.isEmpty; import static org.apache.commons.lang3.ArrayUtils.isNotEmpty; +import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.constant.ClassType.IMMUTABLE; @@ -108,7 +109,7 @@ public boolean isPrimitiveOrSpecialType(final Class clazz) { public boolean isPrimitiveType(final Class clazz) { final String cacheKey = "isPrimitive-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = clazz.equals(String.class) || clazz.isPrimitive() || clazz.isEnum() || Number.class.isAssignableFrom(clazz); + final Boolean res = clazz.isPrimitive() || clazz.equals(String.class) || clazz.isEnum() || Number.class.isAssignableFrom(clazz); cacheManager.cacheObject(cacheKey, res); return res; }); @@ -120,10 +121,10 @@ public boolean isPrimitiveType(final Class clazz) { * @return true if is primitive type array, false otherwise */ public boolean isPrimitiveTypeArray(final Object object) { - final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getName(); + final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getCanonicalName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = object instanceof int[] || object instanceof byte[] || object instanceof char[] - || object instanceof short[] || object instanceof long[] || object instanceof float[] || object instanceof double[]; + final Boolean res = object instanceof int[] || object instanceof char[] || object instanceof short[] + || object instanceof long[] || object instanceof byte[] || object instanceof float[] || object instanceof double[]; cacheManager.cacheObject(cacheKey, res); return res; }); @@ -224,6 +225,7 @@ public static boolean isBoolean(final Class type) { */ @SuppressWarnings("unchecked") public List getPrivateFinalFields(final Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "PrivateFinalFields-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); @@ -246,6 +248,7 @@ public List getPrivateFinalFields(final Class clazz) { * @return the total matching item. */ public int getTotalFields(final Class clazz, final Predicate predicate) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "TotalFields-" + clazz.getName() + '-' + predicate; return cacheManager.getFromCache(cacheKey, Integer.class).orElseGet(() -> { List declaredFields = getDeclaredFields(clazz, true); @@ -274,6 +277,7 @@ public List getPrivateFields(final Class clazz) { */ @SuppressWarnings("unchecked") public List getPrivateFields(final Class clazz, final boolean skipFinal) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "PrivateFields-" + clazz.getName() + "-skipFinal-" + skipFinal; return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); @@ -368,6 +372,7 @@ public boolean usesBuilderPattern(final Constructor constructor, final Class * @return the all args constructor */ public Constructor getAllArgsConstructor(final Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "AllArgsConstructor-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { Constructor constructor = getAllArgsConstructor(clazz.getDeclaredConstructors()); @@ -437,6 +442,7 @@ public boolean hasField(final Object target, final String fieldName) { * @return true if has at least one setter method, false otherwise */ public boolean hasSetterMethods(final Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "HasSetterMethods-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class) .orElseGet(() -> { @@ -452,6 +458,7 @@ public boolean hasSetterMethods(final Class clazz) { * @return the class declared methods. */ private Method[] getDeclaredMethods(final Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "DeclaredMethods-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Method[].class) .orElseGet(() -> { @@ -467,6 +474,7 @@ private Method[] getDeclaredMethods(final Class clazz) { * @return true if it has private final field, false otherwise. */ public boolean hasFinalFields(final Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); return hasFieldsMatchingCondition(clazz, IS_FINAL_AND_NOT_STATIC_FIELD, "HasFinalNotStaticFields-"); } @@ -476,6 +484,7 @@ public boolean hasFinalFields(final Class clazz) { * @return true if it has private final field, false otherwise. */ private boolean hasNotFinalFields(final Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); return hasFieldsMatchingCondition(clazz, IS_NOT_FINAL_AND_NOT_STATIC_FIELD, "HasNotFinalNotStaticFields-"); } @@ -579,6 +588,7 @@ public ClassType getClassType(final Class clazz) { */ @SuppressWarnings("unchecked") public List getSetterMethods(final Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "SetterMethods-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List setterMethods = new LinkedList<>(); From a1b678f3e30770584b90e63eaeb452ae3cf192c5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 16:56:43 +0200 Subject: [PATCH 0411/1786] bug fixing --- CHANGELOG.md | 9 ++++++ .../beans/transformer/TransformerImpl.java | 29 +++++++++---------- .../MutableObjectTransformationTest.java | 19 ++++++++++++ 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccd8a7f90..fa5b40285 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.2.7] TBD +#### Changed +* Improved optional usage. +* Fixed + ### [1.2.6] 2019.04.06 #### Added * Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). @@ -40,6 +45,10 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.13] TBD +#### Changed +Improved optional usage. + ### [1.1.12] 2019.04.06 #### Added * Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 4245c3639..6f9050ec8 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -39,6 +39,7 @@ import java.lang.reflect.Parameter; import java.util.List; import java.util.Optional; +import java.util.function.Function; import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.constant.ClassType; @@ -350,19 +351,16 @@ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { */ private Object getSourceFieldValue(final T sourceObj, final String sourceFieldName, final Field field, final boolean isFieldTransformerDefined) { Object fieldValue = null; - if (classUtils.isPrimitiveType(sourceObj.getClass())) { - fieldValue = sourceObj; - } else { - try { - fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); - } catch (MissingFieldException e) { - if (!isFieldTransformerDefined && !settings.isSetDefaultValue()) { - throw e; - } - } catch (Exception e) { - if (!isFieldTransformerDefined) { - throw e; - } + try { +// fieldValue = classUtils.isPrimitiveType(sourceObj.getClass()) ? sourceObj : reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); + fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); + } catch (MissingFieldException e) { + if (!isFieldTransformerDefined && !settings.isSetDefaultValue()) { + throw e; + } + } catch (Exception e) { + if (!isFieldTransformerDefined) { + throw e; } } return fieldValue; @@ -377,9 +375,8 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie */ private Object getTransformedField(final Field field, final String breadcrumb, final Object fieldValue) { String fieldName = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - return ofNullable(settings.getFieldsTransformers().get(fieldName)) - .map(fieldTransformer -> fieldTransformer.apply(fieldValue)) - .orElse(fieldValue); + Function transformerFunction = settings.getFieldsTransformers().get(fieldName); + return nonNull(transformerFunction) ? transformerFunction.apply(fieldValue) : fieldValue; } /** diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index f5008da5d..a7e5db1cb 100644 --- a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -97,6 +97,25 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); } + /** + * Test that no exception is thrown if the destination object don't met the constraints and the validation is disabled. + */ + @Test + public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotValidAndTheValidationIsDisabled() { + //GIVEN + MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); + fromFooSubClass.setId(null); + underTest.setValidationDisabled(true); + + //WHEN + underTest.transform(fromFooSubClass, mutableToFoo); + + //THEN + assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); + fromFooSubClass.setId(ID); + underTest.setValidationDisabled(false); + } + /** * Test that a given field transformer function is applied only to a specific field even if there are other ones with same name. */ From 0b01fbbbb925e5d54c7645793a2b844ed3308b9f Mon Sep 17 00:00:00 2001 From: Daniele Cali Date: Thu, 18 Apr 2019 17:32:39 +0200 Subject: [PATCH 0412/1786] Fix when transformerFunction is null --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 39527b49d..88b311bdf 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -39,6 +39,7 @@ import java.lang.reflect.Parameter; import java.util.List; import java.util.Optional; +import java.util.function.Function; import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.constant.ClassType; @@ -377,9 +378,8 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie */ private Object getTransformedField(final Field field, final String breadcrumb, final Object fieldValue) { String fieldName = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - return ofNullable(settings.getFieldsTransformers().get(fieldName)) - .map(fieldTransformer -> fieldTransformer.apply(fieldValue)) - .orElse(fieldValue); + Function transformerFunction = settings.getFieldsTransformers().get(fieldName); + return nonNull(transformerFunction) ? transformerFunction.apply(fieldValue) : fieldValue; } /** From f26d60f6c55ddf8c2090332295d3a2bd8f97af6e Mon Sep 17 00:00:00 2001 From: Daniele Cali Date: Thu, 18 Apr 2019 19:35:05 +0200 Subject: [PATCH 0413/1786] Updates CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccd8a7f90..052be0685 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.2.7] TBD +#### Fixed +* Fixed issue when returning null in a field tranformer + ### [1.2.6] 2019.04.06 #### Added * Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). From 7cc875bc1adf1a0541c451a87eac60770cda6793 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 21:03:45 +0200 Subject: [PATCH 0414/1786] Added tests for field transformation --- .../MutableObjectTransformationTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index a7e5db1cb..9cf1297c9 100644 --- a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -27,6 +27,7 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.hotels.beans.error.InvalidBeanException; @@ -36,6 +37,7 @@ import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooInvalid; import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; +import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; import com.hotels.beans.sample.mutable.MutableToFooSubClass; @@ -190,6 +192,40 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } + /** + * Test transformation field with field transformer. + * @param testCaseDescription the test case description + * @param fieldToTransform the name of the field on which apply the transformation + * @param transformationResult the value to return after the transformation + */ + @Test(dataProvider = "dataTransformationTesting") + public void testTransformationWithFieldTransformationWorksProperly(final String testCaseDescription, final String fieldToTransform, final Object transformationResult) { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FieldTransformer fieldTransformer = new FieldTransformer<>(fieldToTransform, val -> transformationResult); + + //WHEN + underTest.withFieldTransformer(fieldTransformer); + MutableToFooSimple actual = underTest.transform(fromFooSimple, MutableToFooSimple.class); + + //THEN + assertThat(actual, hasProperty(fieldToTransform, equalTo(transformationResult))); + } + + /** + * Creates the parameters to be used for testing the transformation with field transformer. + * @return parameters to be used for testing the transformation with field transformer. + */ + @DataProvider(parallel = true) + private Object[][] dataTransformationTesting() { + return new Object[][] { + {"Test that the field transformation returns the expected values.", + NAME_FIELD_NAME, NAME.toLowerCase()}, + {"Test that the field transformation returns the expected values even if null.", + NAME_FIELD_NAME, null} + }; + } + /** * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. */ From e45f4e4f20c497ab612dad94c2b3ee7bd7ff71ab Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 21:06:01 +0200 Subject: [PATCH 0415/1786] Updated changelog --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa5b40285..387b22c3e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,10 @@ All notable changes to this project will be documented in this file. -### [1.2.7] TBD +### [1.2.7] 2019.04.18 #### Changed * Improved optional usage. -* Fixed +* Fixed bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). ### [1.2.6] 2019.04.06 #### Added @@ -45,9 +45,10 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created -### [1.1.13] TBD +### [1.1.13] 2019.04.18 #### Changed -Improved optional usage. +* Improved optional usage. +* Fixed bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). ### [1.1.12] 2019.04.06 #### Added From 6209884746b110de044124cc202c9c1c373e760c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 21:13:46 +0200 Subject: [PATCH 0416/1786] preparing java 8 release --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8a1383a43..1f035067e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.7-SNAPSHOT + 1.1.13-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 From 807a7623bc0128ce63ded84266fac66aec2af101 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 21:17:23 +0200 Subject: [PATCH 0417/1786] made project compatible with java 8 --- src/test/java/com/hotels/beans/cache/CacheManagerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index d44083522..537d7ef67 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -59,7 +59,7 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertFalse(actual.isEmpty()); + assertTrue(actual.isPresent()); assertEquals(CACHED_OBJECT_CLASS, actual.get().getClass()); assertSame(CACHED_VALUE, actual.get()); } @@ -77,6 +77,6 @@ public void testRemoveFromCacheRemovesTheObject() { Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertTrue(actual.isEmpty()); + assertFalse(actual.isPresent()); } } From 2bd4f7335ffbd97b881cf26ed507ece857b853c8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 21:18:00 +0200 Subject: [PATCH 0418/1786] [maven-release-plugin] prepare release 1.1.13 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1f035067e..4398eeb26 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.13-SNAPSHOT + 1.1.13 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.13 From 94366e05433f94524d5da5ec73690f4c696bc32a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 21:18:09 +0200 Subject: [PATCH 0419/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4398eeb26..52775187e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.13 + 1.1.14-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.13 + HEAD From e96eee32e5a657e34d99f7dd9a38785ab98eb8a6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 21:23:38 +0200 Subject: [PATCH 0420/1786] preparing java 11 release --- PULL_REQUEST_TEMPLATE.md | 1 + pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 4009c0b56..d0f978669 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -22,3 +22,4 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] My changes generate no new warnings - [ ] Any dependent changes have been merged and published in downstream modules - [ ] My changes have no bad impacts on performances +- [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file diff --git a/pom.xml b/pom.xml index 52775187e..8a1383a43 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.14-SNAPSHOT + 1.2.7-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 From 7cfe85073a7902243aaa5d88eff7b82eead7277a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 21:29:23 +0200 Subject: [PATCH 0421/1786] [maven-release-plugin] prepare release 1.2.7 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8a1383a43..1d220b10a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.7-SNAPSHOT + 1.2.7 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.2.7 From 63eda9e482c0e99abac2f97515fcabd92d930efd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Apr 2019 21:29:30 +0200 Subject: [PATCH 0422/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1d220b10a..7f0063f05 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.7 + 1.2.8-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.2.7 + HEAD From 135ba525e32948c86f500ca011666e6b26f13a09 Mon Sep 17 00:00:00 2001 From: antimo Date: Fri, 19 Apr 2019 00:33:50 +0200 Subject: [PATCH 0423/1786] Fixed Checkstyle error --- .../com/hotels/beans/constant/ClassType.java | 2 +- .../beans/transformer/TransformerImpl.java | 36 +++++----- .../com/hotels/beans/utils/ClassUtils.java | 66 ++++++++++--------- .../hotels/beans/utils/ReflectionUtils.java | 48 ++++++++------ .../beans/sample/builder/BuilderTest.java | 32 +++------ .../beans/sample/builder/BuilderToFoo.java | 38 +++++------ .../sample/builder/LombokBuilderToFoo.java | 11 +++- .../beans/sample/builder/package-info.java | 20 ++++++ .../BuilderObjectTransformationTest.java | 11 ++-- .../hotels/beans/utils/ClassUtilsTest.java | 49 +++++++------- 10 files changed, 170 insertions(+), 143 deletions(-) create mode 100644 src/test/java/com/hotels/beans/sample/builder/package-info.java diff --git a/src/main/java/com/hotels/beans/constant/ClassType.java b/src/main/java/com/hotels/beans/constant/ClassType.java index ec4c0d3ff..4a3e6884a 100644 --- a/src/main/java/com/hotels/beans/constant/ClassType.java +++ b/src/main/java/com/hotels/beans/constant/ClassType.java @@ -33,7 +33,7 @@ public enum ClassType { */ MIXED, /** - * The class could be instantiated with a Builder + * The class could be instantiated with a Builder. */ BUILDER; diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 17232edf3..6c394dcfd 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -16,10 +16,12 @@ package com.hotels.beans.transformer; -import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.constant.ClassType; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.error.MissingFieldException; +import static java.util.Arrays.stream; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.joining; +import static java.util.stream.IntStream.range; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -29,6 +31,13 @@ import java.util.List; import java.util.Optional; +import static org.apache.commons.lang3.StringUtils.EMPTY; + +import com.hotels.beans.annotation.ConstructorArg; +import com.hotels.beans.constant.ClassType; +import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.error.MissingFieldException; + import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.constant.ClassType.BUILDER; import static com.hotels.beans.constant.ClassType.MIXED; @@ -38,13 +47,6 @@ import static com.hotels.beans.constant.Punctuation.LPAREN; import static com.hotels.beans.constant.Punctuation.RPAREN; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; -import static java.util.Arrays.stream; -import static java.util.Objects.isNull; -import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; -import static java.util.stream.Collectors.joining; -import static java.util.stream.IntStream.range; -import static org.apache.commons.lang3.StringUtils.EMPTY; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. @@ -68,8 +70,8 @@ protected final K transform(final T sourceObj, final Class t } catch (Exception e) { throw new InvalidBeanException(e.getMessage(), e); } - } else if (classType.is(BUILDER)){ - Object builder = null; + } else if (classType.is(BUILDER)) { + Object builder; Class builderClass = targetClass.getDeclaredClasses()[0]; Constructor declaredConstructor = builderClass.getDeclaredConstructors()[0]; declaredConstructor.setAccessible(true); @@ -78,15 +80,17 @@ protected final K transform(final T sourceObj, final Class t } catch (InstantiationException e) { throw new InvalidBeanException("Cannot instantiate class: " + builderClass.getName(), e); } catch (IllegalAccessException e) { - throw new InvalidBeanException("Illegal access exception to default constructor defined for class: " + builderClass.getName(), e); + throw new InvalidBeanException("Illegal access exception to default constructor defined for class: " + + builderClass.getName(), e); } catch (InvocationTargetException e) { - throw new InvalidBeanException(String.format("Error while invoking default constructor defined for class: $1. Are you sure that only default constructor is defined in the builder ?" , builderClass.getName()), e); + throw new InvalidBeanException(String.format("Error while invoking default constructor defined for " + + " class: $1. Are you sure that only default constructor is defined in the builder ?", builderClass.getName()), e); } injectAllFields(sourceObj, builder, breadcrumb); Method method; method = reflectionUtils.getBuildMethod(builderClass); method.setAccessible(true); - k = (K)reflectionUtils.invokeMethod(method, builder); + k = (K) reflectionUtils.invokeMethod(method, builder); } else { k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); if (classType.is(MIXED)) { diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index e04d7504d..c902f4934 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -16,9 +16,31 @@ package com.hotels.beans.utils; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.constant.ClassType; -import com.hotels.beans.error.InvalidBeanException; +import static java.lang.reflect.Modifier.isFinal; +import static java.lang.reflect.Modifier.isPrivate; +import static java.lang.reflect.Modifier.isPublic; +import static java.lang.reflect.Modifier.isStatic; +import static java.util.Arrays.asList; +import static java.util.Arrays.stream; +import static java.util.Collections.max; +import static java.util.Comparator.comparing; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.toList; + +import static org.apache.commons.lang3.ArrayUtils.isEmpty; + +import static com.hotels.beans.utils.ValidationUtils.notNull; +import static com.hotels.beans.base.Defaults.defaultValue; +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.constant.ClassType.IMMUTABLE; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; +import static com.hotels.beans.constant.ClassType.BUILDER; +import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_FIELD; +import static com.hotels.beans.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; +import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; @@ -35,29 +57,9 @@ import java.util.function.Predicate; import java.util.stream.Stream; -import static com.hotels.beans.base.Defaults.defaultValue; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.constant.ClassType.BUILDER; -import static com.hotels.beans.constant.ClassType.IMMUTABLE; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; -import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; -import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_FIELD; -import static com.hotels.beans.utils.ValidationUtils.notNull; -import static java.lang.reflect.Modifier.isFinal; -import static java.lang.reflect.Modifier.isPrivate; -import static java.lang.reflect.Modifier.isPublic; -import static java.lang.reflect.Modifier.isStatic; -import static java.util.Arrays.asList; -import static java.util.Arrays.stream; -import static java.util.Collections.max; -import static java.util.Comparator.comparing; -import static java.util.Objects.isNull; -import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; -import static java.util.stream.Collectors.toList; -import static org.apache.commons.lang3.ArrayUtils.isEmpty; +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.constant.ClassType; +import com.hotels.beans.error.InvalidBeanException; /** * Reflection utils for Class objects. @@ -370,7 +372,11 @@ public boolean usesBuilderPattern(final Constructor constructor, final Class }); } - + /** + * Check if nested class containt a valid build method. + * @param superclass class to be instantiated with the build pattern + * @return true if we find in nested class a valid build method + */ private boolean isValidBuildMethod(final Class superclass) { final String build = "build"; String cacheKey = "build-method-" + superclass.getCanonicalName(); @@ -386,11 +392,11 @@ && stream(getDeclaredMethods(nestedClasses.get(0))) } /** - * Get Nested Class defined inside the clazz parameter - * @param clazz + * Get Nested Class defined inside the clazz parameter. + * @param clazz Class where we search for a nested class * @return Nested class if present or an empty List */ - public List getNestedClass(Class clazz) { + public List getNestedClass(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); String cacheKey = "nested-classes-" + clazz.getCanonicalName(); return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index ecf9b1af5..f23baa932 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -16,13 +16,18 @@ package com.hotels.beans.utils; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.error.MissingFieldException; -import com.hotels.beans.error.MissingMethodException; -import com.hotels.beans.model.EmptyValue; -import com.hotels.beans.model.ItemType; -import com.hotels.beans.model.MapElemType; -import com.hotels.beans.model.MapType; +import static java.lang.reflect.Modifier.isPublic; +import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; +import static java.util.Optional.ofNullable; + +import static org.apache.commons.lang3.StringUtils.capitalize; + +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.constant.MethodPrefix.GET; +import static com.hotels.beans.constant.MethodPrefix.IS; +import static com.hotels.beans.constant.MethodPrefix.SET; +import static com.hotels.beans.utils.ValidationUtils.notNull; import java.lang.annotation.Annotation; import java.lang.reflect.Field; @@ -36,16 +41,13 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.constant.MethodPrefix.GET; -import static com.hotels.beans.constant.MethodPrefix.IS; -import static com.hotels.beans.constant.MethodPrefix.SET; -import static com.hotels.beans.utils.ValidationUtils.notNull; -import static java.lang.reflect.Modifier.isPublic; -import static java.util.Objects.isNull; -import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; -import static org.apache.commons.lang3.StringUtils.capitalize; +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.error.MissingFieldException; +import com.hotels.beans.error.MissingMethodException; +import com.hotels.beans.model.EmptyValue; +import com.hotels.beans.model.ItemType; +import com.hotels.beans.model.MapElemType; +import com.hotels.beans.model.MapType; /** * Reflection class utils. @@ -72,7 +74,7 @@ public final class ReflectionUtils { private final CacheManager cacheManager; /** - * Name of method inside the Builder Class + * Name of method inside the Builder Class. */ private final String nameOfBuilderMethod = "build"; @@ -197,8 +199,12 @@ public A getFieldAnnotation(final Field field, final Clas }); } - - public Method getBuildMethod(Class builderClass) { + /** + * Get build method inside the class. + * @param builderClass Class whit a build method (see Builder Pattern) + * @return Build method if present + */ + public Method getBuildMethod(final Class builderClass) { final String cacheKey = "BuildMethod-" + builderClass.getCanonicalName(); return ofNullable(cacheManager.getFromCache(cacheKey, Method.class)).orElseGet(() -> { try { @@ -206,7 +212,7 @@ public Method getBuildMethod(Class builderClass) { cacheManager.cacheObject(cacheKey, method); return method; } catch (NoSuchMethodException e) { - throw new MissingMethodException(String.format("Error while getting method $1 in class $2 " , nameOfBuilderMethod, builderClass.getName()) + e.getMessage()); + throw new MissingMethodException(String.format("Error while getting method $1 in class $2 ", nameOfBuilderMethod, builderClass.getName()) + e.getMessage()); } }); } diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java index 111176f70..fb5c5d932 100644 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java @@ -13,22 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.sample.builder; -import com.hotels.beans.sample.FromFooWithBuilder; +import static org.testng.AssertJUnit.assertSame; + import org.junit.Test; -import static org.testng.AssertJUnit.assertSame; +import com.hotels.beans.sample.FromFooWithBuilder; public class BuilderTest { - /** * Test that we can get the Builder from a class (with a builder) created manually */ - @Test - public void checkDeclaredClassInManualBuilder(){ + public void checkDeclaredClassInManualBuilder() { // WHEN Class[] declaredClasses = BuilderToFoo.class.getDeclaredClasses(); // TODO check for null value... @@ -38,7 +38,6 @@ public void checkDeclaredClassInManualBuilder(){ assertSame(clazz, BuilderToFoo.Builder.class); } - /** * Test that we can get the Builder from a class created with Lombok * Expected name for the Builder created from Lombok is "OriginalClassName" + "Builder" without any character in between @@ -46,28 +45,13 @@ public void checkDeclaredClassInManualBuilder(){ */ @Test - public void checkDeclaredClassInBuilderFromLombok(){ + public void checkDeclaredClassInBuilderFromLombok() { // WHEN Class[] declaredClasses = FromFooWithBuilder.class.getDeclaredClasses(); Class clazz = declaredClasses[0]; // THEN - assertSame(clazz,FromFooWithBuilder.FromFooWithBuilderBuilder.class); + assertSame(clazz, FromFooWithBuilder.FromFooWithBuilderBuilder.class); } +} - - /* - NONJAVADOC!!! TODO : check if useful!!! - Here some chat about builder constructed WITHOUT STATIC CLASS - https://softwareengineering.stackexchange.com/questions/225207/why-should-a-builder-be-an-inner-class-instead-of-in-its-own-class-file - - - Anyway buinder constructed with lombok use static class - https://projectlombok.org/features/Builder - */ -/* @Test - public void checkInnerClass(){ - //throw new NotImplementedException("Check builder with Inner (non static) class"); - }*/ - - } diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java b/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java index 11c2c7a95..882053ad6 100644 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java @@ -13,15 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.sample.builder; +import java.math.BigInteger; +import java.util.List; + import com.hotels.beans.sample.mutable.MutableToSubFoo; + import lombok.Getter; import lombok.Setter; -import java.math.BigInteger; -import java.util.List; - @Getter @Setter public class BuilderToFoo { @@ -31,29 +33,23 @@ public class BuilderToFoo { private List nestedObjectList; private MutableToSubFoo nestedObject; + /** + * Sample Class instantiable with builder. + */ + static class Builder { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; - private BuilderToFoo() {} - - // getters - - static class Builder { - - public Builder(){}; - - private String name; - private BigInteger id; - private List list; - private List nestedObjectList; - private MutableToSubFoo nestedObject; - - - public Builder withName(String name) { + public Builder withName(final String name) { this.name = name; return this; } - public Builder withId(BigInteger id) { + public Builder withId(final BigInteger id) { this.id = id; return this; } @@ -68,4 +64,4 @@ public BuilderToFoo build() { return builderToFoo; } } -} \ No newline at end of file +} diff --git a/src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java b/src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java index 288c85b27..4f70b93e4 100644 --- a/src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java +++ b/src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java @@ -13,14 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.builder; -import com.hotels.beans.sample.FromSubFoo; -import lombok.Builder; +package com.hotels.beans.sample.builder; import java.math.BigInteger; import java.util.List; +import com.hotels.beans.sample.FromSubFoo; + +import lombok.Builder; + +/** + * Sample class with Lombok Builder + */ @Builder public class LombokBuilderToFoo { private final String name; diff --git a/src/test/java/com/hotels/beans/sample/builder/package-info.java b/src/test/java/com/hotels/beans/sample/builder/package-info.java new file mode 100644 index 000000000..7bbb9925a --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/builder/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Immutable Bean package. + */ + +package com.hotels.beans.sample.builder; diff --git a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index c3145b01e..6368ce8d7 100644 --- a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -16,15 +16,18 @@ package com.hotels.beans.transformer; -import com.hotels.beans.sample.builder.BuilderToFoo; -import com.hotels.beans.sample.builder.LombokBuilderToFoo; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.junit.Assert.assertThat; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import com.hotels.beans.sample.builder.BuilderToFoo; +import com.hotels.beans.sample.builder.LombokBuilderToFoo; + import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; -import static org.junit.Assert.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; + /** * Unit test for all {@link Transformer} functions related to Object based on Builder Pattern. diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 377b8c897..caf68ef61 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -16,24 +16,13 @@ package com.hotels.beans.utils; -import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.constant.ClassType; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooWithBuilder; -import com.hotels.beans.sample.immutable.ImmutableToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.beans.sample.mixed.MixedToFoo; -import com.hotels.beans.sample.mixed.MixedToFooMissingConstructor; -import com.hotels.beans.sample.mixed.MixedToFooStaticField; -import com.hotels.beans.sample.mutable.MutableToFoo; -import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import static java.lang.reflect.Modifier.isFinal; +import static java.util.Objects.nonNull; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.MockitoAnnotations.initMocks; -import javax.validation.constraints.NotNull; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -45,11 +34,25 @@ import java.util.Locale; import java.util.function.Predicate; -import static java.lang.reflect.Modifier.isFinal; -import static java.util.Objects.nonNull; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.MockitoAnnotations.initMocks; +import javax.validation.constraints.NotNull; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import com.hotels.beans.annotation.ConstructorArg; +import com.hotels.beans.constant.ClassType; +import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.sample.FromFoo; +import com.hotels.beans.sample.FromFooWithBuilder; +import com.hotels.beans.sample.immutable.ImmutableToFoo; +import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; +import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; +import com.hotels.beans.sample.mixed.MixedToFoo; +import com.hotels.beans.sample.mixed.MixedToFooMissingConstructor; +import com.hotels.beans.sample.mixed.MixedToFooStaticField; +import com.hotels.beans.sample.mutable.MutableToFoo; /** * Unit test for {@link ClassUtils}. @@ -573,7 +576,7 @@ private Object[][] dataGetClassTypeTesting() { {"Tests that the method returns immutable if the given class is immutable", ImmutableToFoo.class, ClassType.IMMUTABLE}, {"Tests that the method returns mutable if the given class is mutable", MutableToFoo.class, ClassType.MUTABLE}, {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED}, - {"Test that the method returns builder if the given class is a Builder",FromFooWithBuilder.class, ClassType.BUILDER } + {"Test that the method returns builder if the given class is a Builder", FromFooWithBuilder.class, ClassType.BUILDER } }; } From ca0b900d61fdc83167d208251391b77dea9601a5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 22 Apr 2019 08:28:06 +0200 Subject: [PATCH 0424/1786] Merged with master --- CHANGELOG.md | 10 ++ PULL_REQUEST_TEMPLATE.md | 1 + pom.xml | 2 +- .../java/com/hotels/beans/base/Defaults.java | 3 - .../com/hotels/beans/cache/CacheManager.java | 11 +- .../beans/transformer/TransformerImpl.java | 74 ++++++------ .../com/hotels/beans/utils/ClassUtils.java | 114 ++++++++---------- .../hotels/beans/utils/ReflectionUtils.java | 92 +++++++------- .../hotels/beans/utils/ValidationUtils.java | 5 +- .../java/com/hotels/beans/BeanUtilsTest.java | 6 +- .../com/hotels/beans/base/DefaultsTest.java | 8 -- .../beans/cache/CacheManagerFactoryTest.java | 6 +- .../hotels/beans/cache/CacheManagerTest.java | 45 ++----- .../beans/performance/PerformanceTest.java | 8 -- .../beans/populator/ArrayPopulatorTest.java | 8 +- .../beans/populator/PopulatorFactoryTest.java | 8 +- .../ImmutableObjectTransformationTest.java | 8 +- .../MutableObjectTransformationTest.java | 56 +++++++++ .../hotels/beans/utils/ClassUtilsTest.java | 11 +- .../beans/utils/ReflectionUtilsTest.java | 6 +- .../beans/utils/ValidationUtilsTest.java | 6 +- 21 files changed, 245 insertions(+), 243 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccd8a7f90..387b22c3e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.2.7] 2019.04.18 +#### Changed +* Improved optional usage. +* Fixed bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). + ### [1.2.6] 2019.04.06 #### Added * Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). @@ -40,6 +45,11 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.13] 2019.04.18 +#### Changed +* Improved optional usage. +* Fixed bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). + ### [1.1.12] 2019.04.06 #### Added * Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 4009c0b56..d0f978669 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -22,3 +22,4 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] My changes generate no new warnings - [ ] Any dependent changes have been merged and published in downstream modules - [ ] My changes have no bad impacts on performances +- [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file diff --git a/pom.xml b/pom.xml index 8a1383a43..7f0063f05 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.7-SNAPSHOT + 1.2.8-SNAPSHOT jar 2019 diff --git a/src/main/java/com/hotels/beans/base/Defaults.java b/src/main/java/com/hotels/beans/base/Defaults.java index fbfc5511e..feb773b18 100644 --- a/src/main/java/com/hotels/beans/base/Defaults.java +++ b/src/main/java/com/hotels/beans/base/Defaults.java @@ -18,8 +18,6 @@ import static java.lang.Boolean.FALSE; -import static com.hotels.beans.utils.ValidationUtils.notNull; - import static com.hotels.beans.utils.ClassUtils.isBoolean; import static com.hotels.beans.utils.ClassUtils.isByte; import static com.hotels.beans.utils.ClassUtils.isChar; @@ -44,7 +42,6 @@ public final class Defaults { * @return the default value of a primitive type. */ public static Object defaultValue(final Class type) { - notNull(type, "type cannot be null!"); Object res = null; if (isBoolean(type)) { res = FALSE; diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/src/main/java/com/hotels/beans/cache/CacheManager.java index 90e0af73b..6a3e4c88b 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -19,12 +19,11 @@ import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; -import static com.hotels.beans.utils.ValidationUtils.notNull; - import static lombok.AccessLevel.PRIVATE; import static lombok.AccessLevel.PROTECTED; import java.util.Map; +import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Getter; @@ -70,12 +69,10 @@ public void cacheObject(final String cacheKey, final T object, final Object * @param cacheKey the cache key. * @param objectClass the class of the object to return. * @param the class object type. - * @return the cached object. + * @return the cached object or {@code Optional.empty()} if not existing. */ - public T getFromCache(final String cacheKey, final Class objectClass) { - notNull(cacheKey, "cacheKey cannot be null!"); - notNull(objectClass, "objectClass cannot be null!"); - return ofNullable(cacheMap.get(cacheKey)).map(objectClass::cast).orElse(null); + public Optional getFromCache(final String cacheKey, final Class objectClass) { + return ofNullable(cacheMap.get(cacheKey)).map(objectClass::cast); } /** diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 6c394dcfd..c148e6b57 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -23,6 +23,18 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; +import static org.apache.commons.lang3.StringUtils.EMPTY; + +import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.constant.Punctuation.COMMA; +import static com.hotels.beans.constant.Punctuation.LPAREN; +import static com.hotels.beans.constant.Punctuation.RPAREN; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; +import static com.hotels.beans.constant.ClassType.BUILDER; +import static com.hotels.beans.base.Defaults.defaultValue; +import static com.hotels.beans.populator.PopulatorFactory.getPopulator; + import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -30,30 +42,18 @@ import java.lang.reflect.Parameter; import java.util.List; import java.util.Optional; - -import static org.apache.commons.lang3.StringUtils.EMPTY; +import java.util.function.Function; import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.constant.ClassType; import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.error.MissingFieldException; -import static com.hotels.beans.base.Defaults.defaultValue; -import static com.hotels.beans.constant.ClassType.BUILDER; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.Punctuation.COMMA; -import static com.hotels.beans.constant.Punctuation.DOT; -import static com.hotels.beans.constant.Punctuation.LPAREN; -import static com.hotels.beans.constant.Punctuation.RPAREN; -import static com.hotels.beans.populator.PopulatorFactory.getPopulator; - /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * The implementations are provided by BeanUtils. */ public class TransformerImpl extends AbstractTransformer { - /** * {@inheritDoc} */ @@ -139,7 +139,7 @@ private K injectValues(final T sourceObj, final Class targetClass, fin throw new InvalidBeanException("Constructor invoked with arguments. Expected: " + constructor + "; Found: " + getFormattedConstructorArgs(targetClass, constructorArgs) + ". Double check that each " + targetClass.getSimpleName() + "'s field have the same type and name than the source object: " - + sourceObj.getClass().getCanonicalName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(), e); + + sourceObj.getClass().getName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(), e); } } @@ -152,8 +152,8 @@ private K injectValues(final T sourceObj, final Class targetClass, fin */ private String getFormattedConstructorArgs(final Class targetClass, final Object[] constructorArgs) { return stream(constructorArgs) - .map(arg -> isNull(arg) ? "null" : arg.getClass().getCanonicalName()) - .collect(joining(COMMA.getSymbol(), targetClass.getCanonicalName() + LPAREN.getSymbol(), RPAREN.getSymbol())); + .map(arg -> isNull(arg) ? "null" : arg.getClass().getName()) + .collect(joining(COMMA.getSymbol(), targetClass.getName() + LPAREN.getSymbol(), RPAREN.getSymbol())); } /** @@ -164,8 +164,8 @@ private String getFormattedConstructorArgs(final Class targetClass, final * @return true if the parameter names are defined or the parameters are annotated with: {@link ConstructorArg} */ private boolean canBeInjectedByConstructorParams(final Constructor constructor, final Class targetClass) { - final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() && (classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class)); cacheManager.cacheObject(cacheKey, res); @@ -191,9 +191,9 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< range(0, constructorParameters.length) //.parallel() .forEach(i -> { - String destFieldName = getDestFieldName(constructorParameters[i], targetClass.getCanonicalName()); + String destFieldName = getDestFieldName(constructorParameters[i], targetClass.getName()); if (isNull(destFieldName)) { - constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); + constructorArgsValues[i] = classUtils.getDefaultTypeValue(constructorParameters[i].getType()); } else { String sourceFieldName = getSourceFieldName(destFieldName); constructorArgsValues[i] = @@ -215,7 +215,7 @@ private boolean doSkipTransformation(final String breadcrumb) { /** * Returns the field name in the source object. - * @param field the field that has to be valorized. + * @param field the field that has to be set. * @return the source field name. */ private String getSourceFieldName(final Field field) { @@ -224,7 +224,7 @@ private String getSourceFieldName(final Field field) { /** * Returns the field name in the source object. - * @param fieldName the field name that has to be valorized. + * @param fieldName the field name that has to be set. * @return the source field name. */ private String getSourceFieldName(final String fieldName) { @@ -239,7 +239,7 @@ private String getSourceFieldName(final String fieldName) { */ private String getDestFieldName(final Parameter constructorParameter, final String declaringClassName) { String cacheKey = "DestFieldName-" + declaringClassName + "-" + constructorParameter.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, String.class)) + return cacheManager.getFromCache(cacheKey, String.class) .orElseGet(() -> { String destFieldName; if (constructorParameter.isNamePresent()) { @@ -375,19 +375,16 @@ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { */ private Object getSourceFieldValue(final T sourceObj, final String sourceFieldName, final Field field, final boolean isFieldTransformerDefined) { Object fieldValue = null; - if (classUtils.isPrimitiveType(sourceObj.getClass())) { - fieldValue = sourceObj; - } else { - try { - fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); - } catch (MissingFieldException e) { - if (!isFieldTransformerDefined && !settings.isSetDefaultValue()) { - throw e; - } - } catch (Exception e) { - if (!isFieldTransformerDefined) { - throw e; - } + try { +// fieldValue = classUtils.isPrimitiveType(sourceObj.getClass()) ? sourceObj : reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); + fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); + } catch (MissingFieldException e) { + if (!isFieldTransformerDefined && !settings.isSetDefaultValue()) { + throw e; + } + } catch (Exception e) { + if (!isFieldTransformerDefined) { + throw e; } } return fieldValue; @@ -402,9 +399,8 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie */ private Object getTransformedField(final Field field, final String breadcrumb, final Object fieldValue) { String fieldName = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - return ofNullable(settings.getFieldsTransformers().get(fieldName)) - .map(fieldTransformer -> fieldTransformer.apply(fieldValue)) - .orElse(fieldValue); + Function transformerFunction = settings.getFieldsTransformers().get(fieldName); + return nonNull(transformerFunction) ? transformerFunction.apply(fieldValue) : fieldValue; } /** diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index c902f4934..ec762a296 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -49,7 +49,6 @@ import java.lang.reflect.Parameter; import java.time.temporal.Temporal; import java.util.ArrayList; -import java.util.Arrays; import java.util.Currency; import java.util.LinkedList; import java.util.List; @@ -94,9 +93,8 @@ public ClassUtils() { * @return true if is primitive or special type, false otherwise */ public boolean isPrimitiveOrSpecialType(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "isPrimitiveOrSpecial-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "isPrimitiveOrSpecial-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = isPrimitiveType(clazz) || isSpecialType(clazz); cacheManager.cacheObject(cacheKey, res); return res; @@ -109,10 +107,9 @@ public boolean isPrimitiveOrSpecialType(final Class clazz) { * @return true if is special type, false otherwise */ public boolean isPrimitiveType(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "isPrimitive-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { - final Boolean res = clazz.isPrimitive() || clazz.equals(String.class) || Number.class.isAssignableFrom(clazz) || clazz.equals(Byte.class) || clazz.isEnum(); + final String cacheKey = "isPrimitive-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { + final Boolean res = clazz.isPrimitive() || clazz.equals(String.class) || clazz.isEnum() || Number.class.isAssignableFrom(clazz); cacheManager.cacheObject(cacheKey, res); return res; }); @@ -124,9 +121,8 @@ public boolean isPrimitiveType(final Class clazz) { * @return true if is primitive type array, false otherwise */ public boolean isPrimitiveTypeArray(final Object object) { - notNull(object, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = object instanceof int[] || object instanceof char[] || object instanceof short[] || object instanceof long[] || object instanceof byte[] || object instanceof float[] || object instanceof double[]; cacheManager.cacheObject(cacheKey, res); @@ -141,9 +137,8 @@ public boolean isPrimitiveTypeArray(final Object object) { * @return true if is special type, false otherwise */ public boolean isSpecialType(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "isSpecial-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "isSpecial-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || Temporal.class.isAssignableFrom(clazz) || clazz.isSynthetic() || clazz.isAnonymousClass(); cacheManager.cacheObject(cacheKey, res); @@ -231,8 +226,8 @@ public static boolean isBoolean(final Class type) { @SuppressWarnings("unchecked") public List getPrivateFinalFields(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "PrivateFinalFields-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + final String cacheKey = "PrivateFinalFields-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { res.addAll(getPrivateFinalFields(clazz.getSuperclass())); @@ -254,8 +249,8 @@ public List getPrivateFinalFields(final Class clazz) { */ public int getTotalFields(final Class clazz, final Predicate predicate) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "TotalFields-" + clazz.getCanonicalName() + '-' + predicate; - return ofNullable(cacheManager.getFromCache(cacheKey, Integer.class)).orElseGet(() -> { + final String cacheKey = "TotalFields-" + clazz.getName() + '-' + predicate; + return cacheManager.getFromCache(cacheKey, Integer.class).orElseGet(() -> { List declaredFields = getDeclaredFields(clazz, true); int res = ofNullable(predicate) .map(filter -> (int) declaredFields.stream().filter(filter).count()) @@ -283,8 +278,8 @@ public List getPrivateFields(final Class clazz) { @SuppressWarnings("unchecked") public List getPrivateFields(final Class clazz, final boolean skipFinal) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "PrivateFields-" + clazz.getCanonicalName() + "-skipFinal-" + skipFinal; - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + final String cacheKey = "PrivateFields-" + clazz.getName() + "-skipFinal-" + skipFinal; + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { res.addAll(getPrivateFields(clazz.getSuperclass(), skipFinal)); @@ -308,9 +303,8 @@ public List getPrivateFields(final Class clazz, final boolean skipFina */ @SuppressWarnings("unchecked") public List getDeclaredFields(final Class clazz, final boolean skipStatic) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "DeclaredFields-" + clazz.getCanonicalName() + "-skipStatic-" + skipStatic; - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + final String cacheKey = "DeclaredFields-" + clazz.getName() + "-skipStatic-" + skipStatic; + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new LinkedList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { res.addAll(getDeclaredFields(clazz.getSuperclass(), skipStatic)); @@ -332,8 +326,8 @@ public List getDeclaredFields(final Class clazz, final boolean skipSta * @return a list of class fields */ private Field[] getDeclaredFields(final Class clazz) { - final String cacheKey = "ClassDeclaredFields-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Field[].class)).orElseGet(() -> { + final String cacheKey = "ClassDeclaredFields-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, Field[].class).orElseGet(() -> { Field[] res = clazz.getDeclaredFields(); cacheManager.cacheObject(cacheKey, res); return res; @@ -347,8 +341,8 @@ private Field[] getDeclaredFields(final Class clazz) { * @return true if the target class uses the builder pattern */ public boolean hasAccessibleConstructors(final Class targetClass) { - final String cacheKey = "HasAccessibleConstructors-" + targetClass.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "HasAccessibleConstructors-" + targetClass.getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = stream(targetClass.getDeclaredConstructors()).anyMatch(constructor -> isPublic(constructor.getModifiers())); cacheManager.cacheObject(cacheKey, res); return res; @@ -363,8 +357,8 @@ public boolean hasAccessibleConstructors(final Class targetClass) { * @return true if the target class uses the builder pattern */ public boolean usesBuilderPattern(final Constructor constructor, final Class targetClass) { - final String cacheKey = "UsesBuilderPattern-" + constructor.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "UsesBuilderPattern-" + constructor.getDeclaringClass().getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = !isPublic(constructor.getModifiers()) && !getNestedClass(targetClass).isEmpty() && isValidBuildMethod(targetClass); cacheManager.cacheObject(cacheKey, res); @@ -380,7 +374,7 @@ public boolean usesBuilderPattern(final Constructor constructor, final Class private boolean isValidBuildMethod(final Class superclass) { final String build = "build"; String cacheKey = "build-method-" + superclass.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { List nestedClasses = getNestedClass(superclass); boolean res = !nestedClasses.isEmpty() @@ -399,8 +393,8 @@ && stream(getDeclaredMethods(nestedClasses.get(0))) public List getNestedClass(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); String cacheKey = "nested-classes-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { - List> declaredClasses = Arrays.asList(clazz.getDeclaredClasses()); + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { + List> declaredClasses = asList(clazz.getDeclaredClasses()); cacheManager.cacheObject(cacheKey, declaredClasses); return declaredClasses; }); @@ -414,8 +408,8 @@ public List getNestedClass(final Class clazz) { */ public Constructor getAllArgsConstructor(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "AllArgsConstructor-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Constructor.class)).orElseGet(() -> { + final String cacheKey = "AllArgsConstructor-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { Constructor constructor = getAllArgsConstructor(clazz.getDeclaredConstructors()); cacheManager.cacheObject(cacheKey, constructor); return constructor; @@ -431,8 +425,8 @@ public Constructor getAllArgsConstructor(final Constructor[] constructors) { if (isEmpty(constructors)) { throw new InvalidBeanException("No constructors available"); } - final String cacheKey = "AllArgsConstructor-" + constructors[0].getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Constructor.class)).orElseGet(() -> { + final String cacheKey = "AllArgsConstructor-" + constructors[0].getDeclaringClass().getName(); + return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { final Constructor constructor = max(asList(constructors), comparing(Constructor::getParameterCount)); cacheManager.cacheObject(cacheKey, constructor); return constructor; @@ -445,8 +439,8 @@ public Constructor getAllArgsConstructor(final Constructor[] constructors) { * @return the constructor parameters */ public Parameter[] getConstructorParameters(final Constructor constructor) { - final String cacheKey = "ConstructorParams-" + constructor.getDeclaringClass().getCanonicalName() + '-' + constructor.getParameterCount(); - return ofNullable(cacheManager.getFromCache(cacheKey, Parameter[].class)).orElseGet(() -> { + final String cacheKey = "ConstructorParams-" + constructor.getDeclaringClass().getName() + '-' + constructor.getParameterCount(); + return cacheManager.getFromCache(cacheKey, Parameter[].class).orElseGet(() -> { final Parameter[] parameters = constructor.getParameters(); cacheManager.cacheObject(cacheKey, parameters); return parameters; @@ -460,8 +454,8 @@ public Parameter[] getConstructorParameters(final Constructor constructor) { * @return true if the field is available, false otherwise */ public boolean hasField(final Object target, final String fieldName) { - final String cacheKey = "ClassHasField-" + target.getClass().getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "ClassHasField-" + target.getClass().getName() + '-' + fieldName; + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { boolean hasField; try { hasField = nonNull(target.getClass().getDeclaredField(fieldName)); @@ -484,8 +478,8 @@ public boolean hasField(final Object target, final String fieldName) { */ public boolean hasSetterMethods(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "HasSetterMethods-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)) + final String cacheKey = "HasSetterMethods-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class) .orElseGet(() -> { final Boolean res = stream(getDeclaredMethods(clazz)).anyMatch(reflectionUtils::isSetter); cacheManager.cacheObject(cacheKey, res); @@ -500,8 +494,8 @@ public boolean hasSetterMethods(final Class clazz) { */ private Method[] getDeclaredMethods(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "DeclaredMethods-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Method[].class)) + final String cacheKey = "DeclaredMethods-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, Method[].class) .orElseGet(() -> { final Method[] res = clazz.getDeclaredMethods(); cacheManager.cacheObject(cacheKey, res); @@ -537,7 +531,7 @@ private boolean hasNotFinalFields(final Class clazz) { * @return true if it has private final field, false otherwise. */ private boolean hasFieldsMatchingCondition(final Class clazz, final Predicate filterPredicate, final String cacheKey) { - return ofNullable(cacheManager.getFromCache(cacheKey + clazz.getCanonicalName(), Boolean.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey + clazz.getName(), Boolean.class).orElseGet(() -> { boolean res = stream(getDeclaredFields(clazz)) //.parallel() .anyMatch(filterPredicate); @@ -545,7 +539,7 @@ private boolean hasFieldsMatchingCondition(final Class clazz, final Predicate Class superclass = clazz.getSuperclass(); res = hasFieldsMatchingCondition(superclass, filterPredicate, cacheKey); } - cacheManager.cacheObject(cacheKey + clazz.getCanonicalName(), res); + cacheManager.cacheObject(cacheKey + clazz.getName(), res); return res; }); } @@ -557,8 +551,8 @@ private boolean hasFieldsMatchingCondition(final Class clazz, final Predicate * @return true if any of the parameter contains the annotation, false otherwise. */ public boolean containsAnnotation(final Constructor constructor, final Class annotationClass) { - final String cacheKey = "ConstructorHasAnnotation-" + constructor.getDeclaringClass().getCanonicalName() + '-' + annotationClass.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "ConstructorHasAnnotation-" + constructor.getDeclaringClass().getName() + '-' + annotationClass.getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean containsAnnotation = stream(constructor.getParameters()) .noneMatch(parameter -> isNull(parameter.getAnnotation(annotationClass))); cacheManager.cacheObject(cacheKey, containsAnnotation); @@ -573,8 +567,8 @@ public boolean containsAnnotation(final Constructor constructor, final Class annotationClass) { - final String cacheKey = "AllParameterAnnotatedWith-" + constructor.getDeclaringClass().getCanonicalName() + '-' + annotationClass.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "AllParameterAnnotatedWith-" + constructor.getDeclaringClass().getName() + '-' + annotationClass.getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean notAllAnnotatedWith = stream(constructor.getParameters()) .allMatch(parameter -> nonNull(parameter.getAnnotation(annotationClass))); cacheManager.cacheObject(cacheKey, notAllAnnotatedWith); @@ -588,8 +582,8 @@ public boolean allParameterAnnotatedWith(final Constructor constructor, final Cl * @return true if some parameters names are not defined, false otherwise. */ public boolean areParameterNamesAvailable(final Constructor constructor) { - final String cacheKey = "AreParameterNamesAvailable-" + constructor.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "AreParameterNamesAvailable-" + constructor.getDeclaringClass().getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = stream(getConstructorParameters(constructor)) .anyMatch(Parameter::isNamePresent); cacheManager.cacheObject(cacheKey, res); @@ -603,10 +597,9 @@ public boolean areParameterNamesAvailable(final Constructor constructor) { * @return the class type {@link ClassType} */ public ClassType getClassType(final Class clazz) { - final String cacheKey = "ClassType-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, ClassType.class)).orElseGet(() -> { + final String cacheKey = "ClassType-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, ClassType.class).orElseGet(() -> { final ClassType classType; - boolean hasFinalFields = hasFinalFields(clazz); if (usesBuilderPattern(getAllArgsConstructor(clazz), clazz)) { classType = BUILDER; @@ -625,7 +618,6 @@ public ClassType getClassType(final Class clazz) { }); } - /** * Retrieves all the setters method for the given class. * @param clazz the clazz containing the methods. @@ -634,8 +626,8 @@ public ClassType getClassType(final Class clazz) { @SuppressWarnings("unchecked") public List getSetterMethods(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "SetterMethods-" + clazz.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + final String cacheKey = "SetterMethods-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { final List setterMethods = new LinkedList<>(); if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { setterMethods.addAll(getSetterMethods(clazz.getSuperclass())); @@ -654,8 +646,8 @@ public List getSetterMethods(final Class clazz) { * @return the default value of a primitive type */ public Object getDefaultTypeValue(final Class objectType) { - final String cacheKey = "DefaultTypeValue-" + objectType.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Object.class)).orElseGet(() -> { + final String cacheKey = "DefaultTypeValue-" + objectType.getName(); + return cacheManager.getFromCache(cacheKey, Object.class).orElseGet(() -> { final Object defaultValue = isPrimitiveType(objectType) ? defaultValue(objectType) : null; cacheManager.cacheObject(cacheKey, defaultValue); return defaultValue; @@ -670,8 +662,8 @@ public Object getDefaultTypeValue(final Class objectType) { */ @SuppressWarnings("unchecked") public List getNotFinalFields(final Class clazz, final Boolean skipStatic) { - final String cacheKey = "NotFinalFields-" + clazz.getCanonicalName() + "-" + skipStatic; - return ofNullable(cacheManager.getFromCache(cacheKey, List.class)).orElseGet(() -> { + final String cacheKey = "NotFinalFields-" + clazz.getName() + "-" + skipStatic; + return cacheManager.getFromCache(cacheKey, List.class).orElseGet(() -> { List notFinalFields = getDeclaredFields(clazz, skipStatic) .stream() .filter(IS_NOT_FINAL_FIELD).collect(toList()); diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index f23baa932..2c3a16c25 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -19,7 +19,6 @@ import static java.lang.reflect.Modifier.isPublic; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; -import static java.util.Optional.ofNullable; import static org.apache.commons.lang3.StringUtils.capitalize; @@ -27,7 +26,6 @@ import static com.hotels.beans.constant.MethodPrefix.GET; import static com.hotels.beans.constant.MethodPrefix.IS; import static com.hotels.beans.constant.MethodPrefix.SET; -import static com.hotels.beans.utils.ValidationUtils.notNull; import java.lang.annotation.Annotation; import java.lang.reflect.Field; @@ -94,8 +92,6 @@ public ReflectionUtils() { * @return the method result */ public Object invokeMethod(final Method method, final Object target, final Object... args) { - notNull(method, "method cannot be null!"); - notNull(target, "target cannot be null!"); try { return method.invoke(target, args); } catch (MissingFieldException | MissingMethodException e) { @@ -112,8 +108,8 @@ public Object invokeMethod(final Method method, final Object target, final Objec * @return true if the method is a setter method, false otherwise */ public boolean isSetter(final Method method) { - final String cacheKey = "IsSetter-" + method.getDeclaringClass().getCanonicalName() + '-' + method.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Boolean.class)).orElseGet(() -> { + final String cacheKey = "IsSetter-" + method.getDeclaringClass().getName() + '-' + method.getName(); + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { boolean res = isPublic(method.getModifiers()) && method.getName().matches(SETTER_METHOD_NAME_REGEX) && method.getParameterTypes().length == 1 @@ -163,18 +159,18 @@ public Object getFieldValue(final Object target, final String fieldName, final C * @return the getter method */ private Method getGetterMethod(final Class fieldClass, final String fieldName, final Class fieldType) { - final String cacheKey = "GetterMethod-" + fieldClass.getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Method.class)).orElseGet(() -> { + final String cacheKey = "GetterMethod-" + fieldClass.getName() + '-' + fieldName; + return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { Method method = fieldClass.getMethod(getGetterMethodPrefix(fieldType) + capitalize(fieldName)); cacheManager.cacheObject(cacheKey, method); return method; } catch (NoSuchMethodException e) { if (new ClassUtils().hasField(fieldClass, fieldName)) { - throw new MissingMethodException(fieldClass.getCanonicalName() + " does not allow to get value for field: " + fieldName + throw new MissingMethodException(fieldClass.getName() + " does not allow to get value for field: " + fieldName + ". Is a getter method defined?"); } else { - throw new MissingFieldException(fieldClass.getCanonicalName() + " hasn't a field called: " + fieldName + "."); + throw new MissingFieldException(fieldClass.getName() + " hasn't a field called: " + fieldName + "."); } } }); @@ -188,8 +184,8 @@ private Method getGetterMethod(final Class fieldClass, final String fieldName * @return the annotation */ public A getFieldAnnotation(final Field field, final Class annotationClazz) { - final String cacheKey = "FieldAnnotation-" + field.getDeclaringClass().getCanonicalName() + "-" + field.getName() + "-" + annotationClazz.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, annotationClazz)).orElseGet(() -> { + final String cacheKey = "FieldAnnotation-" + field.getDeclaringClass().getName() + "-" + field.getName() + "-" + annotationClazz.getName(); + return cacheManager.getFromCache(cacheKey, annotationClazz).orElseGet(() -> { A annotation = null; if (field.isAnnotationPresent(annotationClazz)) { annotation = field.getAnnotation(annotationClazz); @@ -206,7 +202,7 @@ public A getFieldAnnotation(final Field field, final Clas */ public Method getBuildMethod(final Class builderClass) { final String cacheKey = "BuildMethod-" + builderClass.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Method.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { Method method = builderClass.getMethod(nameOfBuilderMethod, null); cacheManager.cacheObject(cacheKey, method); @@ -217,7 +213,6 @@ public Method getBuildMethod(final Class builderClass) { }); } - /** * Returns (if existing) the constructor parameter's given type annotation. * @param parameter the field that should have the annotation @@ -228,7 +223,7 @@ public Method getBuildMethod(final Class builderClass) { */ public A getParameterAnnotation(final Parameter parameter, final Class annotationClazz, final String declaringClassName) { final String cacheKey = "ParameterAnnotation-" + declaringClassName + "-" + parameter.getName() + "-" + annotationClazz.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, annotationClazz)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, annotationClazz).orElseGet(() -> { A annotation = null; if (parameter.isAnnotationPresent(annotationClazz)) { annotation = parameter.getAnnotation(annotationClazz); @@ -274,15 +269,16 @@ private Object getFieldValue(final Object target, final String fieldName) { */ public Field getDeclaredField(final String fieldName, final Class targetClass) { final String cacheKey = "ClassDeclaredField-" + targetClass.getName() + "-" + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Field.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, Field.class).orElseGet(() -> { Field field; try { field = targetClass.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { - if (!targetClass.getSuperclass().equals(Object.class)) { - field = getDeclaredField(fieldName, targetClass.getSuperclass()); + Class superclass = targetClass.getSuperclass(); + if (!superclass.equals(Object.class)) { + field = getDeclaredField(fieldName, superclass); } else { - throw new MissingFieldException(targetClass.getCanonicalName() + " does not contain field: " + fieldName); + throw new MissingFieldException(targetClass.getName() + " does not contain field: " + fieldName); } } catch (final Exception e) { handleReflectionException(e); @@ -371,9 +367,9 @@ private boolean isOptionalType(final Object object) { * @return the method prefix (get or is) */ private String getGetterMethodPrefix(final Class fieldType) { - final String cacheKey = "GetterMethodPrefix-" + fieldType.getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, String.class)).orElseGet(() -> { - String res = Boolean.class.equals(fieldType) || fieldType.getCanonicalName().equals(BOOLEAN) ? IS.getPrefix() : GET.getPrefix(); + final String cacheKey = "GetterMethodPrefix-" + fieldType.getName(); + return cacheManager.getFromCache(cacheKey, String.class).orElseGet(() -> { + String res = Boolean.class.equals(fieldType) || fieldType.getName().equals(BOOLEAN) ? IS.getPrefix() : GET.getPrefix(); cacheManager.cacheObject(cacheKey, res); return res; }); @@ -388,8 +384,8 @@ private String getGetterMethodPrefix(final Class fieldType) { * @throws MissingMethodException if the method does not exists */ public Method getSetterMethodForField(final Class fieldClass, final String fieldName, final Class fieldType) { - final String cacheKey = "SetterMethod-" + fieldClass.getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, Method.class)).orElseGet(() -> { + final String cacheKey = "SetterMethod-" + fieldClass.getName() + '-' + fieldName; + return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { Method method = fieldClass.getMethod(SET.getPrefix() + capitalize(fieldName), fieldType); cacheManager.cacheObject(cacheKey, method); @@ -406,8 +402,8 @@ public Method getSetterMethodForField(final Class fieldClass, final String fi * @return the generic type class */ public Class getGenericFieldType(final Field field) { - final String cacheKey = "GenericFieldType-" + field.getDeclaringClass().getCanonicalName() + '-' + field.getName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Class.class)).orElseGet(() -> { + final String cacheKey = "GenericFieldType-" + field.getDeclaringClass().getName() + '-' + field.getName(); + return cacheManager.getFromCache(cacheKey, Class.class).orElseGet(() -> { Class res = null; if (ParameterizedType.class.isAssignableFrom(field.getGenericType().getClass())) { final Type[] fieldArgTypes = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); @@ -428,16 +424,14 @@ public Class getGenericFieldType(final Field field) { * @return the generic type class */ public MapType getMapGenericType(final Type fieldType, final String declaringClass, final String fieldName) { - notNull(fieldType, "fieldType cannot be null!"); - notNull(fieldName, "fieldName cannot be null!"); final Class fieldClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); if (isNull(fieldClass) || !Map.class.isAssignableFrom(fieldClass)) { throw new IllegalArgumentException( "Type for object: " + fieldName + " is invalid. " - + "It cannot be assigned from: " + Map.class.getCanonicalName() + "."); + + "It cannot be assigned from: " + Map.class.getName() + "."); } - final String cacheKey = "MapGenericFieldType-" + fieldClass.getCanonicalName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, MapType.class)).orElseGet(() -> { + final String cacheKey = "MapGenericFieldType-" + fieldClass.getName() + '-' + fieldName; + return cacheManager.getFromCache(cacheKey, MapType.class).orElseGet(() -> { final ParameterizedType genericType = (ParameterizedType) fieldType; final MapElemType keyType = getMapElemType(genericType.getActualTypeArguments()[0], declaringClass, fieldName); final MapElemType elemType = getMapElemType(genericType.getActualTypeArguments()[1], declaringClass, fieldName); @@ -458,7 +452,7 @@ public MapType getMapGenericType(final Type fieldType, final String declaringCla */ private MapElemType getMapElemType(final Type fieldType, final String declaringClass, final String fieldName) { final String cacheKey = "MapElemType-" + declaringClass + "-" + fieldType.getTypeName() + '-' + fieldName; - return ofNullable(cacheManager.getFromCache(cacheKey, MapElemType.class)).orElseGet(() -> { + return cacheManager.getFromCache(cacheKey, MapElemType.class).orElseGet(() -> { final Class argumentTypeClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); final MapElemType res; if (Map.class.isAssignableFrom(argumentTypeClass)) { @@ -498,22 +492,20 @@ public Class getArgumentTypeClass(final Object argument, final String declari final boolean argumentIsTypeClass = argument instanceof Class; final String cacheKey = "ArgumentTypeClass-" + declaringClass + "-" + fieldName + "-" + getNestedGenericClass + "-" + "-" + (argumentIsTypeClass || !List.class.isAssignableFrom(argument.getClass()) ? argument : argument.getClass()); - Class argumentTypeClass = cacheManager.getFromCache(cacheKey, Class.class); - if (nonNull(argumentTypeClass)) { - if (argumentTypeClass == EmptyValue.class) { - argumentTypeClass = null; - } - } else { - if (argumentIsTypeClass) { - argumentTypeClass = getNestedGenericClass ? null : (Class) argument; - } else if (ParameterizedType.class.isAssignableFrom(argument.getClass())) { - argumentTypeClass = getNestedGenericClass - ? getArgumentTypeClass(((ParameterizedType) argument).getActualTypeArguments()[0], declaringClass, fieldName, false) - : (Class) ((ParameterizedType) argument).getRawType(); - } - cacheManager.cacheObject(cacheKey, argumentTypeClass, EmptyValue.class); - } - return argumentTypeClass; + return cacheManager.getFromCache(cacheKey, Class.class) + .map(atc -> atc == EmptyValue.class ? null : atc) + .orElseGet(() -> { + Class res = null; + if (argumentIsTypeClass) { + res = getNestedGenericClass ? null : (Class) argument; + } else if (ParameterizedType.class.isAssignableFrom(argument.getClass())) { + res = getNestedGenericClass + ? getArgumentTypeClass(((ParameterizedType) argument).getActualTypeArguments()[0], declaringClass, fieldName, false) + : (Class) ((ParameterizedType) argument).getRawType(); + } + cacheManager.cacheObject(cacheKey, res, EmptyValue.class); + return res; + }); } /** @@ -522,8 +514,8 @@ public Class getArgumentTypeClass(final Object argument, final String declari * @return the array class */ public Class getArrayType(final Field arrayField) { - final String cacheKey = "ArrayType-" + arrayField.getDeclaringClass().getCanonicalName(); - return ofNullable(cacheManager.getFromCache(cacheKey, Class.class)).orElseGet(() -> { + final String cacheKey = "ArrayType-" + arrayField.getDeclaringClass().getName(); + return cacheManager.getFromCache(cacheKey, Class.class).orElseGet(() -> { final Class arrayType = arrayField.getType().getComponentType(); cacheManager.cacheObject(cacheKey, arrayType); return arrayType; diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java index f1a1d4b36..e1d2cb72d 100644 --- a/src/main/java/com/hotels/beans/utils/ValidationUtils.java +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -17,7 +17,6 @@ package com.hotels.beans.utils; import static java.util.Objects.isNull; -import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.joining; import static javax.validation.Validation.buildDefaultValidatorFactory; @@ -89,7 +88,7 @@ public final void validate(final K k) { final Set> constraintViolations = getValidator().validate(k); if (!constraintViolations.isEmpty()) { final String errors = constraintViolations.stream() - .map(cv -> cv.getRootBeanClass().getCanonicalName() + .map(cv -> cv.getRootBeanClass().getName() + DOT.getSymbol() + cv.getPropertyPath() + SPACE @@ -105,7 +104,7 @@ public final void validate(final K k) { */ private Validator getValidator() { String cacheKey = "BeanValidator"; - return ofNullable(cacheManager.getFromCache(cacheKey, Validator.class)) + return cacheManager.getFromCache(cacheKey, Validator.class) .orElseGet(() -> { Validator validator = buildDefaultValidatorFactory().getValidator(); cacheManager.cacheObject(cacheKey, validator); diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/src/test/java/com/hotels/beans/BeanUtilsTest.java index 7c6532754..712827a98 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -30,7 +30,7 @@ import java.util.stream.IntStream; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -54,8 +54,8 @@ public class BeanUtilsTest { /** * Initialized mocks. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/base/DefaultsTest.java b/src/test/java/com/hotels/beans/base/DefaultsTest.java index ca7eadfd4..1aca49594 100644 --- a/src/test/java/com/hotels/beans/base/DefaultsTest.java +++ b/src/test/java/com/hotels/beans/base/DefaultsTest.java @@ -61,14 +61,6 @@ public DefaultsTest(final Class type, final Object expectedResult) { this.expectedResult = expectedResult; } - /** - * Tests that the method: {@code defaultValue} throws exception when type is null. - */ - @Test(expected = IllegalArgumentException.class) - public void testDefaultValueThrowsExceptionWhenTypeIsNull() { - underTest.defaultValue(null); - } - /** * Tests that the method: {@code defaultValue} returns the expected result for the given type. */ diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java index bd05d3217..907d1d78c 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java @@ -20,7 +20,7 @@ import static org.mockito.MockitoAnnotations.initMocks; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** @@ -41,8 +41,8 @@ public class CacheManagerFactoryTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index 193536d37..537d7ef67 100644 --- a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -17,13 +17,14 @@ package com.hotels.beans.cache; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** @@ -41,8 +42,8 @@ public class CacheManagerTest { /** * Initializes mock. */ - @BeforeMethod - public void before() { + @BeforeClass + public void beforeClass() { underTest = new CacheManager(new ConcurrentHashMap<>()); } @@ -55,34 +56,12 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { underTest.cacheObject(CACHE_KEY, CACHED_VALUE); // WHEN - Object actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); + Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertNotNull(actual); - assertEquals(CACHED_OBJECT_CLASS, actual.getClass()); - assertSame(CACHED_VALUE, actual); - } - - /** - * Tests that the method {@code getFromCache} throw exception when the cache key. - */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testGetFromCacheThrowsExceptionWhenTheCacheKeyIsNull() { - // GIVEN - - // WHEN - underTest.getFromCache(null, CACHED_OBJECT_CLASS); - } - - /** - * Tests that the method {@code getFromCache} throw exception when the cached value class is null. - */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testGetFromCacheThrowsExceptionWhenTheCachedValueClassIsNull() { - // GIVEN - - // WHEN - underTest.getFromCache(CACHE_KEY, null); + assertTrue(actual.isPresent()); + assertEquals(CACHED_OBJECT_CLASS, actual.get().getClass()); + assertSame(CACHED_VALUE, actual.get()); } /** @@ -95,9 +74,9 @@ public void testRemoveFromCacheRemovesTheObject() { // WHEN underTest.removeFromCache(CACHE_KEY); - Object actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); + Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertNull(actual); + assertFalse(actual.isPresent()); } } diff --git a/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/src/test/java/com/hotels/beans/performance/PerformanceTest.java index c7087dd57..95ed20bf6 100644 --- a/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -35,7 +35,6 @@ import org.apache.commons.lang3.time.StopWatch; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -94,13 +93,6 @@ public class PerformanceTest { @BeforeClass public void beforeClass() { initObjects(); - } - - /** - * Initialized mocks. - */ - @BeforeMethod - public void beforeMethod() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index cc62631ab..812e084de 100644 --- a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -27,7 +27,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -59,10 +59,9 @@ public class ArrayPopulatorTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); - MIXED_TO_FOO_STATIC_FIELDS_OBJECTS.setNormalField(VAL_1); } /** @@ -113,6 +112,7 @@ public Object[][] dataProvider() { * @return an array containing an instance of {@link MixedToFooStaticField}. */ private static MixedToFooStaticField[] createMixedToFooArray() { + MIXED_TO_FOO_STATIC_FIELDS_OBJECTS.setNormalField(VAL_1); return new MixedToFooStaticField[] {MIXED_TO_FOO_STATIC_FIELDS_OBJECTS}; } } diff --git a/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index 5fd1ef31b..647edc6be 100644 --- a/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -27,7 +27,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -53,14 +53,14 @@ public class PopulatorFactoryTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } /** * Tests that the method: {@code defaultValue} returns the expected result for the given type. - * @param type the type for wich a populator needs to be found + * @param type the type for which a populator needs to be found * @param expectedResult the expected populator */ @Test(dataProvider = "dataProvider") diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index baef9fb19..bfc499825 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -175,9 +175,9 @@ public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(f private Object[][] dataCompositeFieldNameTesting() { return new Object[][] { {"Test that, in case a destination object field is contained into a nested object of the source field, defining a composite FieldMapping" - + "the field is correctly valorized.", fromFoo, fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObject().getPhoneNumbers()}, + + "the field is correctly set.", fromFoo, fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObject().getPhoneNumbers()}, {"Test that, in case a destination object field is contained into a nested object of the source field, defining a composite {@link FieldMapping}" - + " the field is correctly valorized even if some of them are null.", fromFooWithNullProperties, fromFooWithNullProperties.getName(), + + " the field is correctly set even if some of them are null.", fromFooWithNullProperties, fromFooWithNullProperties.getName(), fromFooWithNullProperties.getId(), null} }; } @@ -425,9 +425,9 @@ public void testTransformationReturnsAMeaningfulException() { "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration. " + "Error message: argument type mismatch"; - String targetClassName = targetClass.getCanonicalName(); + String targetClassName = targetClass.getName(); String expectedExceptionMessage = - format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getCanonicalName()); + format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getName()); //WHEN Exception raisedException = null; diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index f5008da5d..2b620a57c 100644 --- a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -27,6 +27,7 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.hotels.beans.error.InvalidBeanException; @@ -36,6 +37,7 @@ import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooInvalid; import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; +import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; import com.hotels.beans.sample.mutable.MutableToFooSubClass; @@ -97,6 +99,25 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); } + /** + * Test that no exception is thrown if the destination object don't met the constraints and the validation is disabled. + */ + @Test + public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotValidAndTheValidationIsDisabled() { + //GIVEN + MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); + fromFooSubClass.setId(null); + underTest.setValidationDisabled(true); + + //WHEN + underTest.transform(fromFooSubClass, mutableToFoo); + + //THEN + assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); + fromFooSubClass.setId(ID); + underTest.setValidationDisabled(false); + } + /** * Test that a given field transformer function is applied only to a specific field even if there are other ones with same name. */ @@ -171,6 +192,41 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } + /** + * Test transformation field with field transformer. + * @param testCaseDescription the test case description + * @param fieldToTransform the name of the field on which apply the transformation + * @param transformationResult the value to return after the transformation + */ + @Test(dataProvider = "dataTransformationTesting") + public void testTransformationWithFieldTransformationWorksProperly(final String testCaseDescription, final String fieldToTransform, final Object transformationResult) { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FieldTransformer fieldTransformer = new FieldTransformer<>(fieldToTransform, val -> transformationResult); + + //WHEN + underTest.withFieldTransformer(fieldTransformer); + MutableToFooSimple actual = underTest.transform(fromFooSimple, MutableToFooSimple.class); + + //THEN + assertThat(actual, hasProperty(fieldToTransform, equalTo(transformationResult))); + underTest.removeFieldTransformer(fieldToTransform); + } + + /** + * Creates the parameters to be used for testing the transformation with field transformer. + * @return parameters to be used for testing the transformation with field transformer. + */ + @DataProvider + private Object[][] dataTransformationTesting() { + return new Object[][] { + {"Test that the field transformation returns the expected values.", + NAME_FIELD_NAME, NAME.toLowerCase()}, + {"Test that the field transformation returns the expected values even if null.", + NAME_FIELD_NAME, null} + }; + } + /** * Test that, given a set of fields for which the transformation has to be skipped, they are actually skipped. */ diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index caf68ef61..c74c0ce00 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -37,7 +37,7 @@ import javax.validation.constraints.NotNull; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -94,8 +94,8 @@ public class ClassUtilsTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } @@ -568,15 +568,14 @@ public void testGetClassTypeWorksAsExpected(final String testCaseDescription, fi /** * Creates the parameters to be used for testing the method {@code getClassType}. - * @return parameters to be used for testing the the method {@code getClassType}. FromFooWithBuilder + * @return parameters to be used for testing the the method {@code getClassType}. */ @DataProvider private Object[][] dataGetClassTypeTesting() { return new Object[][] { {"Tests that the method returns immutable if the given class is immutable", ImmutableToFoo.class, ClassType.IMMUTABLE}, {"Tests that the method returns mutable if the given class is mutable", MutableToFoo.class, ClassType.MUTABLE}, - {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED}, - {"Test that the method returns builder if the given class is a Builder", FromFooWithBuilder.class, ClassType.BUILDER } + {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED} }; } diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index 3c222c077..2265c0eab 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -41,10 +41,10 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; import com.hotels.beans.error.MissingMethodException; import com.hotels.beans.error.MissingFieldException; @@ -73,8 +73,8 @@ public class ReflectionUtilsTest { /** * Initializes mock. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } diff --git a/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java index 460512340..7c90cd1db 100644 --- a/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ValidationUtilsTest.java @@ -21,7 +21,7 @@ import static org.mockito.MockitoAnnotations.initMocks; import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -48,8 +48,8 @@ public class ValidationUtilsTest { /** * Initialized mocks. */ - @BeforeMethod - public void beforeMethod() { + @BeforeClass + public void beforeClass() { initMocks(this); } From 353cc71088851dbb77335b5fdf11eb10f50a937b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 22 Apr 2019 17:47:15 +0200 Subject: [PATCH 0425/1786] Merged with branch: "builderWithFailingTest" --- .../com/hotels/beans/utils/ClassUtils.java | 4 +- .../beans/sample/builder/BuilderToFoo.java | 11 ++- .../BuilderToFooWithTwoConstructor.java | 76 +++++++++++++++++++ .../BuilderObjectTransformationTest.java | 15 +++- .../hotels/beans/utils/ClassUtilsTest.java | 3 +- .../beans/utils/ReflectionUtilsTest.java | 12 +++ 6 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 src/test/java/com/hotels/beans/sample/builder/BuilderToFooWithTwoConstructor.java diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index eaaf22986..6916967c2 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -368,7 +368,7 @@ public boolean usesBuilderPattern(final Constructor constructor, final Class } /** - * Check if nested class containt a valid build method. + * Check if nested class contains a valid build method. * @param superclass class to be instantiated with the build pattern * @return true if we find in nested class a valid build method */ @@ -389,7 +389,7 @@ && stream(getDeclaredMethods(nestedClasses.get(0))) /** * Retrieves all classes defined into the given one. * @param clazz class where we search for a nested class - * @return all classes defined into the given one + * @return all classes defined into the given one */ public Class[] getDeclaredClasses(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java b/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java index 882053ad6..4ef70348d 100644 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java @@ -21,23 +21,22 @@ import com.hotels.beans.sample.mutable.MutableToSubFoo; -import lombok.Getter; import lombok.Setter; +import lombok.Getter; @Getter @Setter -public class BuilderToFoo { +public final class BuilderToFoo { private String name; private BigInteger id; private List list; private List nestedObjectList; private MutableToSubFoo nestedObject; - /** - * Sample Class instantiable with builder. - */ - static class Builder { + private BuilderToFoo() { + } + static class Builder { private String name; private BigInteger id; private List list; diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderToFooWithTwoConstructor.java b/src/test/java/com/hotels/beans/sample/builder/BuilderToFooWithTwoConstructor.java new file mode 100644 index 000000000..442358d78 --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/builder/BuilderToFooWithTwoConstructor.java @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.builder; + +import java.math.BigInteger; +import java.util.List; + +import com.hotels.beans.sample.mutable.MutableToSubFoo; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public final class BuilderToFooWithTwoConstructor { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + /** + * Private constructor. + */ + private BuilderToFooWithTwoConstructor() { + } + + static class Builder { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + Builder(final String name) { + this.name = name; + } + + Builder() { + } + + public Builder withName(final String name) { + this.name = name; + return this; + } + + public Builder withId(final BigInteger id) { + this.id = id; + return this; + } + + public BuilderToFooWithTwoConstructor build() { + BuilderToFooWithTwoConstructor builderToFoo = new BuilderToFooWithTwoConstructor(); + builderToFoo.id = this.id; + builderToFoo.name = this.name; + builderToFoo.list = this.list; + builderToFoo.nestedObjectList = this.nestedObjectList; + builderToFoo.nestedObject = this.nestedObject; + return builderToFoo; + } + } +} diff --git a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 6368ce8d7..5b37de5ef 100644 --- a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -19,15 +19,16 @@ import static org.mockito.MockitoAnnotations.initMocks; import static org.junit.Assert.assertThat; +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +//import com.hotels.beans.sample.builder.BuilderToFooWithTwoConstructor; import com.hotels.beans.sample.builder.BuilderToFoo; import com.hotels.beans.sample.builder.LombokBuilderToFoo; -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; - /** * Unit test for all {@link Transformer} functions related to Object based on Builder Pattern. @@ -72,4 +73,14 @@ public void testManualBuilder() { assertThat(actual, sameBeanAs(fromFoo)); } +// @Test +// public void testManualBuilderWithTwoContructor() { +// //GIVEN +// +// //WHEN +// BuilderToFooWithTwoConstructor actual = underTest.transform(fromFoo, BuilderToFooWithTwoConstructor.class); +// +// //THEN +// assertThat(actual, sameBeanAs(fromFoo)); +// } } diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index c74c0ce00..d15a11600 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -575,7 +575,8 @@ private Object[][] dataGetClassTypeTesting() { return new Object[][] { {"Tests that the method returns immutable if the given class is immutable", ImmutableToFoo.class, ClassType.IMMUTABLE}, {"Tests that the method returns mutable if the given class is mutable", MutableToFoo.class, ClassType.MUTABLE}, - {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED} + {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED}, + {"Test that the method returns builder if the given class is a Builder", FromFooWithBuilder.class, ClassType.BUILDER} }; } diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index b44dc5c21..2265c0eab 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -36,6 +36,7 @@ import java.lang.reflect.Parameter; import java.lang.reflect.UndeclaredThrowableException; import java.math.BigInteger; +import java.util.List; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -160,6 +161,17 @@ public void testHandleReflectionExceptionThrowsUndeclaredThrowableExceptionWhenG underTest.handleReflectionException(exception); } + /** + * Tests that the method {@code getMapGenericType} throws Exception when the given type is not a map. + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testGetMapGenericTypeThrowsIllegalArgumentExceptionWhenTheGivenTypeIsNotAMap() { + // GIVEN + + // WHEN + underTest.getMapGenericType(List.class, null, LIST_FIELD_NAME); + } + /** * Tests that the method {@code getGetterMethodPrefix} returns the expected value. * @param testCaseDescription the test case description From d169ebae0adad7e6e56e6fbc0ca96ed04d9c8c82 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 22 Apr 2019 17:49:58 +0200 Subject: [PATCH 0426/1786] Fixed typo --- .../beans/transformer/BuilderObjectTransformationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 5b37de5ef..ecd61ff22 100644 --- a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -74,7 +74,7 @@ public void testManualBuilder() { } // @Test -// public void testManualBuilderWithTwoContructor() { +// public void testManualBuilderWithTwoConstructor() { // //GIVEN // // //WHEN From bfe8bbbb3f2dd8f96eac9ce8880d785fa18e6225 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 22 Apr 2019 18:03:22 +0200 Subject: [PATCH 0427/1786] Added data provider for testing builder --- .../BuilderObjectTransformationTest.java | 47 +++++++++---------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index ecd61ff22..e248b9b9c 100644 --- a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -23,9 +23,10 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -//import com.hotels.beans.sample.builder.BuilderToFooWithTwoConstructor; +import com.hotels.beans.sample.builder.BuilderToFooWithTwoConstructor; import com.hotels.beans.sample.builder.BuilderToFoo; import com.hotels.beans.sample.builder.LombokBuilderToFoo; @@ -49,38 +50,32 @@ public void beforeMethod() { } /** - * Test mutable beans are correctly copied. + * Test mutable beans are correctly copied through builder. + * @param testDescription the test case description + * @param sourceObject the object to transform + * @param targetObjectClass the target object class */ - @Test - public void testBuilderWithLombok() { + @Test(dataProvider = "transformationThroughBuilderTesting") + public void testTransformationThroughBuilder(final String testDescription, final Object sourceObject, final Class targetObjectClass) { //GIVEN //WHEN - LombokBuilderToFoo actual = underTest.transform(fromFoo, LombokBuilderToFoo.class); + Object actual = underTest.transform(sourceObject, targetObjectClass); //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertThat(actual, sameBeanAs(sourceObject)); } - @Test - public void testManualBuilder() { - //GIVEN - - //WHEN - BuilderToFoo actual = underTest.transform(fromFoo, BuilderToFoo.class); - - //THEN - assertThat(actual, sameBeanAs(fromFoo)); + /** + * Creates the parameters to be used for testing the bean transformation through builder. + * @return parameters to be used for testing the bean transformation through builder. + */ + @DataProvider + private Object[][] transformationThroughBuilderTesting() { + return new Object[][] { + {"Test beans are correctly copied if annotated with {@link lombok.Builder} annotation", fromFoo, LombokBuilderToFoo.class}, + {"Test beans are correctly copied if contains a custom Builder", fromFoo, BuilderToFoo.class}, + {"Test beans are correctly copied if contains a custom Builder with two constructors", fromFoo, BuilderToFooWithTwoConstructor.class} + }; } - -// @Test -// public void testManualBuilderWithTwoConstructor() { -// //GIVEN -// -// //WHEN -// BuilderToFooWithTwoConstructor actual = underTest.transform(fromFoo, BuilderToFooWithTwoConstructor.class); -// -// //THEN -// assertThat(actual, sameBeanAs(fromFoo)); -// } } From f5e6519cca9ac6f93ca9388c830f73bb322c2920 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 23 Apr 2019 12:36:39 +0200 Subject: [PATCH 0428/1786] Builder tests refactoring --- .../beans/sample/FromFooWithBuilder.java | 32 ----------- .../beans/sample/builder/BuilderTest.java | 57 ------------------- .../beans/sample/builder/package-info.java | 20 ------- .../immutable/ImmutableToFooWithBuilder.java | 52 +++++++++++++++++ .../MixedToFooWithBuilder.java} | 13 +++-- .../MutableToFooWithBuilder.java} | 31 +++++----- ...eToFooWithBuilderMultipleConstructor.java} | 28 ++++----- .../BuilderObjectTransformationTest.java | 16 ++++-- .../hotels/beans/utils/ClassUtilsTest.java | 44 ++++++++++++-- 9 files changed, 140 insertions(+), 153 deletions(-) delete mode 100644 src/test/java/com/hotels/beans/sample/FromFooWithBuilder.java delete mode 100644 src/test/java/com/hotels/beans/sample/builder/BuilderTest.java delete mode 100644 src/test/java/com/hotels/beans/sample/builder/package-info.java create mode 100644 src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java rename src/test/java/com/hotels/beans/sample/{builder/LombokBuilderToFoo.java => mixed/MixedToFooWithBuilder.java} (77%) rename src/test/java/com/hotels/beans/sample/{builder/BuilderToFoo.java => mutable/MutableToFooWithBuilder.java} (65%) rename src/test/java/com/hotels/beans/sample/{builder/BuilderToFooWithTwoConstructor.java => mutable/MutableToFooWithBuilderMultipleConstructor.java} (71%) diff --git a/src/test/java/com/hotels/beans/sample/FromFooWithBuilder.java b/src/test/java/com/hotels/beans/sample/FromFooWithBuilder.java deleted file mode 100644 index 448678bf4..000000000 --- a/src/test/java/com/hotels/beans/sample/FromFooWithBuilder.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (C) 2019 Expedia Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.math.BigInteger; - -import lombok.Builder; -import lombok.Getter; - -/** - * Sample object using Builder pattern. - */ -@Builder -@Getter -public class FromFooWithBuilder { - private final String name; - private final BigInteger id; -} diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java b/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java deleted file mode 100644 index fb5c5d932..000000000 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (C) 2019 Expedia Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.builder; - -import static org.testng.AssertJUnit.assertSame; - -import org.junit.Test; - -import com.hotels.beans.sample.FromFooWithBuilder; - -public class BuilderTest { - - /** - * Test that we can get the Builder from a class (with a builder) created manually - */ - @Test - public void checkDeclaredClassInManualBuilder() { - // WHEN - Class[] declaredClasses = BuilderToFoo.class.getDeclaredClasses(); - // TODO check for null value... - Class clazz = declaredClasses[0]; - - // THEN - assertSame(clazz, BuilderToFoo.Builder.class); - } - - /** - * Test that we can get the Builder from a class created with Lombok - * Expected name for the Builder created from Lombok is "OriginalClassName" + "Builder" without any character in between - * see https://projectlombok.org/features/Builder - */ - - @Test - public void checkDeclaredClassInBuilderFromLombok() { - // WHEN - Class[] declaredClasses = FromFooWithBuilder.class.getDeclaredClasses(); - Class clazz = declaredClasses[0]; - - // THEN - assertSame(clazz, FromFooWithBuilder.FromFooWithBuilderBuilder.class); - } -} - diff --git a/src/test/java/com/hotels/beans/sample/builder/package-info.java b/src/test/java/com/hotels/beans/sample/builder/package-info.java deleted file mode 100644 index 7bbb9925a..000000000 --- a/src/test/java/com/hotels/beans/sample/builder/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Immutable Bean package. - */ - -package com.hotels.beans.sample.builder; diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java new file mode 100644 index 000000000..6b72ad65c --- /dev/null +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import static lombok.AccessLevel.PRIVATE; + +import java.math.BigInteger; +import java.util.List; + +import com.hotels.beans.sample.FromSubFoo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +/** + * Immutable bean instantiable only through a Builder. + */ +@Getter +@Builder(builderMethodName = "hiddenBuilder") +@AllArgsConstructor(access = PRIVATE) +public class ImmutableToFooWithBuilder { + private final String name; + private final BigInteger id; + private final List nestedObjectList; + private final List list; + private final FromSubFoo nestedObject; + + public static ImmutableToFooWithBuilderBuilder builder(final String name, final BigInteger id, + final List nestedObjectList, final List list, final FromSubFoo nestedObject) { + return hiddenBuilder() + .name(name) + .id(id) + .nestedObjectList(nestedObjectList) + .list(list) + .nestedObject(nestedObject); + } +} diff --git a/src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java b/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java similarity index 77% rename from src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java rename to src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java index 4f70b93e4..c2c576074 100644 --- a/src/test/java/com/hotels/beans/sample/builder/LombokBuilderToFoo.java +++ b/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java @@ -14,24 +14,29 @@ * limitations under the License. */ -package com.hotels.beans.sample.builder; +package com.hotels.beans.sample.mixed; import java.math.BigInteger; import java.util.List; +import static lombok.AccessLevel.PRIVATE; + import com.hotels.beans.sample.FromSubFoo; +import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Getter; /** - * Sample class with Lombok Builder + * Mixed bean instantiable only through a Builder. */ +@Getter @Builder -public class LombokBuilderToFoo { +@AllArgsConstructor(access = PRIVATE) +public class MixedToFooWithBuilder { private final String name; private BigInteger id; private final List nestedObjectList; private final List list; private final FromSubFoo nestedObject; - } diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java similarity index 65% rename from src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java rename to src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java index 4ef70348d..4b6933455 100644 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderToFoo.java +++ b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java @@ -14,29 +14,30 @@ * limitations under the License. */ -package com.hotels.beans.sample.builder; +package com.hotels.beans.sample.mutable; import java.math.BigInteger; import java.util.List; -import com.hotels.beans.sample.mutable.MutableToSubFoo; - -import lombok.Setter; import lombok.Getter; +import lombok.Setter; +/** + * Mutable object instantiable only through a Builder. + */ @Getter @Setter -public final class BuilderToFoo { +public final class MutableToFooWithBuilder { private String name; private BigInteger id; private List list; private List nestedObjectList; private MutableToSubFoo nestedObject; - private BuilderToFoo() { + private MutableToFooWithBuilder() { } - static class Builder { + public static class Builder { private String name; private BigInteger id; private List list; @@ -53,14 +54,14 @@ public Builder withId(final BigInteger id) { return this; } - public BuilderToFoo build() { - BuilderToFoo builderToFoo = new BuilderToFoo(); - builderToFoo.id = this.id; - builderToFoo.name = this.name; - builderToFoo.list = this.list; - builderToFoo.nestedObjectList = this.nestedObjectList; - builderToFoo.nestedObject = this.nestedObject; - return builderToFoo; + public MutableToFooWithBuilder build() { + MutableToFooWithBuilder mutableToFooWithBuilder = new MutableToFooWithBuilder(); + mutableToFooWithBuilder.id = this.id; + mutableToFooWithBuilder.name = this.name; + mutableToFooWithBuilder.list = this.list; + mutableToFooWithBuilder.nestedObjectList = this.nestedObjectList; + mutableToFooWithBuilder.nestedObject = this.nestedObject; + return mutableToFooWithBuilder; } } } diff --git a/src/test/java/com/hotels/beans/sample/builder/BuilderToFooWithTwoConstructor.java b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java similarity index 71% rename from src/test/java/com/hotels/beans/sample/builder/BuilderToFooWithTwoConstructor.java rename to src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java index 442358d78..c017eb4f8 100644 --- a/src/test/java/com/hotels/beans/sample/builder/BuilderToFooWithTwoConstructor.java +++ b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.hotels.beans.sample.builder; +package com.hotels.beans.sample.mutable; import java.math.BigInteger; import java.util.List; -import com.hotels.beans.sample.mutable.MutableToSubFoo; - import lombok.Getter; -import lombok.Setter; +/** + * Mutable object instantiable only through a Builder. + * The Builder class contains multiple constructors. + */ @Getter -@Setter -public final class BuilderToFooWithTwoConstructor { +public final class MutableToFooWithBuilderMultipleConstructor { private String name; private BigInteger id; private List list; @@ -36,35 +36,35 @@ public final class BuilderToFooWithTwoConstructor { /** * Private constructor. */ - private BuilderToFooWithTwoConstructor() { + private MutableToFooWithBuilderMultipleConstructor() { } - static class Builder { + static class Pippo { private String name; private BigInteger id; private List list; private List nestedObjectList; private MutableToSubFoo nestedObject; - Builder(final String name) { + Pippo(final String name) { this.name = name; } - Builder() { + Pippo() { } - public Builder withName(final String name) { + public Pippo withName(final String name) { this.name = name; return this; } - public Builder withId(final BigInteger id) { + public Pippo withId(final BigInteger id) { this.id = id; return this; } - public BuilderToFooWithTwoConstructor build() { - BuilderToFooWithTwoConstructor builderToFoo = new BuilderToFooWithTwoConstructor(); + public MutableToFooWithBuilderMultipleConstructor build() { + MutableToFooWithBuilderMultipleConstructor builderToFoo = new MutableToFooWithBuilderMultipleConstructor(); builderToFoo.id = this.id; builderToFoo.name = this.name; builderToFoo.list = this.list; diff --git a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index e248b9b9c..084800a7b 100644 --- a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -26,9 +26,10 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.builder.BuilderToFooWithTwoConstructor; -import com.hotels.beans.sample.builder.BuilderToFoo; -import com.hotels.beans.sample.builder.LombokBuilderToFoo; +import com.hotels.beans.sample.mutable.MutableToFooWithBuilderMultipleConstructor; +import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; +import com.hotels.beans.sample.mixed.MixedToFooWithBuilder; +import com.hotels.beans.sample.immutable.ImmutableToFooWithBuilder; /** @@ -73,9 +74,12 @@ public void testTransformationThroughBuilder(final String testDescription, final @DataProvider private Object[][] transformationThroughBuilderTesting() { return new Object[][] { - {"Test beans are correctly copied if annotated with {@link lombok.Builder} annotation", fromFoo, LombokBuilderToFoo.class}, - {"Test beans are correctly copied if contains a custom Builder", fromFoo, BuilderToFoo.class}, - {"Test beans are correctly copied if contains a custom Builder with two constructors", fromFoo, BuilderToFooWithTwoConstructor.class} + {"Test that a Mutable bean, containing a custom Builder is correctly transformed", fromFoo, MutableToFooWithBuilder.class}, + {"Test that a Mutable bean, containing a custom Builder with multiple constructors, is correctly transformed", + fromFoo, MutableToFooWithBuilderMultipleConstructor.class}, + {"Test that a Mixed bean, containing a Builder generated by lombok, is correctly transformed", fromFoo, MixedToFooWithBuilder.class}, + {"Test that an Immutable bean, containing a Builder generated by lombok with all mandatory fields, is correctly transformed", + fromFoo, ImmutableToFooWithBuilder.class} }; } } diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index d15a11600..4799a6fe4 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -19,8 +19,10 @@ import static java.lang.reflect.Modifier.isFinal; import static java.util.Objects.nonNull; +import static org.apache.commons.lang3.ArrayUtils.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; import java.lang.annotation.Annotation; @@ -45,14 +47,15 @@ import com.hotels.beans.constant.ClassType; import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooWithBuilder; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mixed.MixedToFooMissingConstructor; +import com.hotels.beans.sample.mixed.MixedToFooWithBuilder; import com.hotels.beans.sample.mixed.MixedToFooStaticField; import com.hotels.beans.sample.mutable.MutableToFoo; +import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; /** * Unit test for {@link ClassUtils}. @@ -357,6 +360,37 @@ private Object[][] dataGetDeclaredFieldsTesting() { }; } + /** + * Test that the a manual declared Builder is returned by method: {@code getDeclaredClasses}. + * @param testCaseDescription the test case description + * @param testClass the class from which extract the nested classes + * @param expectedClass the class expected as nested + */ + @Test(dataProvider = "dataGetDeclaredClassesTesting") + public void testGetDeclaredClassesWorksAsExpected(final String testCaseDescription, final Class testClass, final Class expectedClass) { + // GIVEN + + // WHEN + Class[] actual = underTest.getDeclaredClasses(testClass); + + // THEN + assertTrue(contains(actual, expectedClass)); + } + + /** + * Creates the parameters to be used for testing the method {@code getDeclaredClasses}. + * @return parameters to be used for testing the the method {@code getDeclaredClasses}. + */ + @DataProvider + private Object[][] dataGetDeclaredClassesTesting() { + return new Object[][] { + {"Test that the a manual declared Builder is returned by method: {@code getDeclaredClasses}", MutableToFooWithBuilder.class, + MutableToFooWithBuilder.Builder.class}, + {"Test that the a Builder created by lombok is returned by method: {@code getDeclaredClasses}", MixedToFooWithBuilder.class, + MixedToFooWithBuilder.builder().getClass()} + }; + } + /** * Tests that the method {@code getAllArgsConstructor} returns the class constructor. */ @@ -576,7 +610,7 @@ private Object[][] dataGetClassTypeTesting() { {"Tests that the method returns immutable if the given class is immutable", ImmutableToFoo.class, ClassType.IMMUTABLE}, {"Tests that the method returns mutable if the given class is mutable", MutableToFoo.class, ClassType.MUTABLE}, {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED}, - {"Test that the method returns builder if the given class is a Builder", FromFooWithBuilder.class, ClassType.BUILDER} + {"Test that the method returns builder if the given class is a Builder", MutableToFooWithBuilder.class, ClassType.BUILDER} }; } @@ -648,7 +682,7 @@ public void testUsesBuilderPatternWorksAsExpected(final String testCaseDescripti @DataProvider private Object[][] dataUsesBuilderPatternTesting() { return new Object[][] { - {"Tests that the method returns true if the class has a builder", FromFooWithBuilder.class, true}, + {"Tests that the method returns true if the class has a builder", MutableToFooWithBuilder.class, true}, {"Tests that the method returns false if the class hasn't a builder", FromFoo.class, false} }; } @@ -677,8 +711,8 @@ public void testHasAccessibleConstructorsWorksAsExpected(final String testCaseDe @DataProvider private Object[][] dataHasAccessibleConstructorsTesting() { return new Object[][] { - {"Tests that the method returns false if the constructor is private", FromFooWithBuilder.class, false}, - {"Tests that the method returns false if the constructor is public", FromFoo.class, true} + {"Tests that the method returns false if the constructor is public", FromFoo.class, true}, + {"Tests that the method returns false if the constructor is private", MutableToFooWithBuilder.class, false} }; } } From b4f066793bbc2e9fc424350acb914808a6f7e38d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 23 Apr 2019 14:51:49 +0200 Subject: [PATCH 0429/1786] Enabled transformation for all beans including the one with the builder. Draft version to be finalized --- .../beans/transformer/TransformerImpl.java | 44 +++---- .../com/hotels/beans/utils/ClassUtils.java | 116 ++++++++++++++---- .../hotels/beans/utils/ReflectionUtils.java | 13 +- ...leToFooWithBuilderMultipleConstructor.java | 10 +- .../ImmutableObjectTransformationTest.java | 3 +- .../hotels/beans/utils/ClassUtilsTest.java | 4 +- 6 files changed, 120 insertions(+), 70 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index c148e6b57..b0858169b 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -31,13 +31,11 @@ import static com.hotels.beans.constant.Punctuation.RPAREN; import static com.hotels.beans.constant.ClassType.MIXED; import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.ClassType.BUILDER; import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.List; @@ -60,43 +58,29 @@ public class TransformerImpl extends AbstractTransformer { @Override protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final ClassType classType = classUtils.getClassType(targetClass); + final Object transformedClass; + Optional> builderClass = classUtils.getBuilderClass(targetClass); + final Class classToTransform = builderClass.isPresent() ? builderClass.get() : targetClass; + final ClassType classType = classUtils.getClassType(classToTransform); if (classType.is(MUTABLE)) { try { - k = targetClass.getDeclaredConstructor().newInstance(); - injectAllFields(sourceObj, k, breadcrumb); - } catch (NoSuchMethodException e) { - throw new InvalidBeanException("No default constructor defined for class: " + targetClass.getName(), e); + transformedClass = classUtils.getInstance(classToTransform); + injectAllFields(sourceObj, transformedClass, breadcrumb); } catch (Exception e) { throw new InvalidBeanException(e.getMessage(), e); } - } else if (classType.is(BUILDER)) { - Object builder; - Class builderClass = targetClass.getDeclaredClasses()[0]; - Constructor declaredConstructor = builderClass.getDeclaredConstructors()[0]; - declaredConstructor.setAccessible(true); - try { - builder = declaredConstructor.newInstance(); - } catch (InstantiationException e) { - throw new InvalidBeanException("Cannot instantiate class: " + builderClass.getName(), e); - } catch (IllegalAccessException e) { - throw new InvalidBeanException("Illegal access exception to default constructor defined for class: " - + builderClass.getName(), e); - } catch (InvocationTargetException e) { - throw new InvalidBeanException(String.format("Error while invoking default constructor defined for " - + " class: $1. Are you sure that only default constructor is defined in the builder ?", builderClass.getName()), e); - } - injectAllFields(sourceObj, builder, breadcrumb); - Method method; - method = reflectionUtils.getBuildMethod(builderClass); - method.setAccessible(true); - k = (K) reflectionUtils.invokeMethod(method, builder); } else { - k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); + transformedClass = injectValues(sourceObj, classToTransform, classUtils.getAllArgsConstructor(classToTransform), breadcrumb); if (classType.is(MIXED)) { - injectNotFinalFields(sourceObj, k, breadcrumb); + injectNotFinalFields(sourceObj, transformedClass, breadcrumb); } } + if (builderClass.isPresent()) { + Method method = reflectionUtils.getBuildMethod(classToTransform); + k = (K) reflectionUtils.invokeMethod(method, transformedClass); + } else { + k = (K) transformedClass; + } if (!settings.isValidationDisabled()) { validationUtils.validate(k); } diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 6916967c2..d992a3b4d 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -23,6 +23,7 @@ import static java.util.Arrays.asList; import static java.util.Arrays.stream; import static java.util.Collections.max; +import static java.util.Collections.min; import static java.util.Comparator.comparing; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; @@ -30,7 +31,6 @@ import static java.util.stream.Collectors.toList; import static org.apache.commons.lang3.ArrayUtils.isEmpty; -import static org.apache.commons.lang3.ArrayUtils.isNotEmpty; import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.base.Defaults.defaultValue; @@ -38,7 +38,6 @@ import static com.hotels.beans.constant.ClassType.IMMUTABLE; import static com.hotels.beans.constant.ClassType.MIXED; import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.ClassType.BUILDER; import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_FIELD; import static com.hotels.beans.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; @@ -54,6 +53,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Stream; @@ -70,6 +70,11 @@ public final class ClassUtils { */ private static final String CLAZZ_CANNOT_BE_NULL = "clazz cannot be null!"; + /** + * Default method name used by a Builder for creating an object. + */ + private static final String BUILD_METHOD_NAME = "build"; + /** * Reflection utils instance {@link ReflectionUtils}. */ @@ -122,7 +127,7 @@ public boolean isPrimitiveType(final Class clazz) { * @return true if is primitive type array, false otherwise */ public boolean isPrimitiveTypeArray(final Object object) { - final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getCanonicalName(); + final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = object instanceof int[] || object instanceof char[] || object instanceof short[] || object instanceof long[] || object instanceof byte[] || object instanceof float[] || object instanceof double[]; @@ -360,30 +365,48 @@ public boolean hasAccessibleConstructors(final Class targetClass) { public boolean usesBuilderPattern(final Constructor constructor, final Class targetClass) { final String cacheKey = "UsesBuilderPattern-" + constructor.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final boolean res = !isPublic(constructor.getModifiers()) && isNotEmpty(getDeclaredClasses(targetClass)) - && isValidBuildMethod(targetClass); + final boolean res = !isPublic(constructor.getModifiers()) && getBuilderClass(targetClass).isPresent(); cacheManager.cacheObject(cacheKey, res); return res; }); } - /** - * Check if nested class contains a valid build method. - * @param superclass class to be instantiated with the build pattern - * @return true if we find in nested class a valid build method +// /** +// * Check if nested class contains a valid build method. +// * @param superclass class to be instantiated with the build pattern +// * @return true if we find in nested class a valid build method +// */ +// private boolean isValidBuildMethod(final Class superclass) { +// final String build = "build"; +// String cacheKey = "build-method-" + superclass.getCanonicalName(); +// return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { +// List nestedClasses = asList(getDeclaredClasses(superclass)); +// boolean res = +// !nestedClasses.isEmpty() +// && stream(getDeclaredMethods(nestedClasses.get(0))) +// .anyMatch(method -> method.getName().equals(build) && method.getReturnType().equals(superclass)); +// cacheManager.cacheObject(cacheKey, res); +// return res; +// }); +// } + + /** + * Returns the builder class. + * @param targetClass the class where the builder should be searched + * @return the Builder class if available. */ - private boolean isValidBuildMethod(final Class superclass) { - final String build = "build"; - String cacheKey = "build-method-" + superclass.getCanonicalName(); - return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - List nestedClasses = asList(getDeclaredClasses(superclass)); - boolean res = - !nestedClasses.isEmpty() - && stream(getDeclaredMethods(nestedClasses.get(0))) - .anyMatch(method -> method.getName().equals(build) && method.getReturnType().equals(superclass)); - cacheManager.cacheObject(cacheKey, res); - return res; - }); + @SuppressWarnings("unchecked") + public Optional> getBuilderClass(final Class targetClass) { + String cacheKey = "BuilderClass-" + targetClass.getName(); + return cacheManager.getFromCache(cacheKey, Optional.class).orElseGet(() -> { + Optional res = stream(getDeclaredClasses(targetClass)) + .filter(nestedClass -> + stream(getDeclaredMethods(nestedClass)) + .anyMatch(method -> method.getName().equals(BUILD_METHOD_NAME) && method.getReturnType().equals(targetClass))) + .findAny(); + cacheManager.cacheObject(cacheKey, res); + return res; + }); } /** @@ -393,7 +416,7 @@ && stream(getDeclaredMethods(nestedClasses.get(0))) */ public Class[] getDeclaredClasses(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - String cacheKey = "nested-classes-" + clazz.getCanonicalName(); + String cacheKey = "nested-classes-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Class[].class).orElseGet(() -> { Class[] declaredClasses = clazz.getDeclaredClasses(); cacheManager.cacheObject(cacheKey, declaredClasses); @@ -402,7 +425,48 @@ public Class[] getDeclaredClasses(final Class clazz) { } /** - * Retrieves the all args constructor. + * Retrieves an object from cache. + * @param objectClass the class of the object to return. + * @param the class object type. + * @return the object instance. + * @throws Exception in case the object creation fails. + */ + public T getInstance(final Class objectClass) throws Exception { + Constructor constructor = getNoArgsConstructor(objectClass); + boolean isAccessible = constructor.isAccessible(); + try { + if (!isAccessible) { + constructor.setAccessible(true); + } + return (T) constructor.newInstance(); + } catch (Exception e) { + throw e; + } finally { + constructor.setAccessible(isAccessible); + } + } + + /** + * Retrieves the no args constructor. + * @param clazz the class from which gets the constructor. + * @param the object type + * @return the all args constructor + */ + public Constructor getNoArgsConstructor(final Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); + final String cacheKey = "NoArgsConstructor-" + clazz.getName(); + return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { + final Constructor constructor = min(asList(clazz.getDeclaredConstructors()), comparing(Constructor::getParameterCount)); + if (constructor.getParameterCount() != 0) { + throw new InvalidBeanException("No default constructor defined for class: " + clazz.getName()); + } + cacheManager.cacheObject(cacheKey, constructor); + return constructor; + }); + } + + /** + * Retrieves the constructor with more parameters. * @param clazz the class from which gets the all arg constructor. * @param the object type * @return the all args constructor @@ -426,7 +490,7 @@ public Constructor getAllArgsConstructor(final Constructor[] constructors) { if (isEmpty(constructors)) { throw new InvalidBeanException("No constructors available"); } - final String cacheKey = "AllArgsConstructor-" + constructors[0].getDeclaringClass().getName(); + final String cacheKey = "AllArgsConstructorFromConstructor-" + constructors[0].getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { final Constructor constructor = max(asList(constructors), comparing(Constructor::getParameterCount)); cacheManager.cacheObject(cacheKey, constructor); @@ -602,9 +666,7 @@ public ClassType getClassType(final Class clazz) { return cacheManager.getFromCache(cacheKey, ClassType.class).orElseGet(() -> { final ClassType classType; boolean hasFinalFields = hasFinalFields(clazz); - if (usesBuilderPattern(getAllArgsConstructor(clazz), clazz)) { - classType = BUILDER; - } else if (!hasFinalFields) { + if (!hasFinalFields) { classType = MUTABLE; } else { boolean hasNotFinalFields = hasNotFinalFields(clazz); diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 2c3a16c25..547cf0cf5 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -16,6 +16,7 @@ package com.hotels.beans.utils; +import static java.lang.String.format; import static java.lang.reflect.Modifier.isPublic; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; @@ -92,13 +93,19 @@ public ReflectionUtils() { * @return the method result */ public Object invokeMethod(final Method method, final Object target, final Object... args) { + boolean isAccessible = method.isAccessible(); try { + if (!isAccessible) { + method.setAccessible(true); + } return method.invoke(target, args); } catch (MissingFieldException | MissingMethodException e) { throw e; } catch (final Exception e) { handleReflectionException(e); throw new IllegalStateException(e); + } finally { + method.setAccessible(isAccessible); } } @@ -201,14 +208,14 @@ public A getFieldAnnotation(final Field field, final Clas * @return Build method if present */ public Method getBuildMethod(final Class builderClass) { - final String cacheKey = "BuildMethod-" + builderClass.getCanonicalName(); + final String cacheKey = "BuildMethod-" + builderClass.getName(); return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { - Method method = builderClass.getMethod(nameOfBuilderMethod, null); + Method method = builderClass.getMethod(nameOfBuilderMethod); cacheManager.cacheObject(cacheKey, method); return method; } catch (NoSuchMethodException e) { - throw new MissingMethodException(String.format("Error while getting method $1 in class $2 ", nameOfBuilderMethod, builderClass.getName()) + e.getMessage()); + throw new MissingMethodException(format("Error while getting method %s in class %s.", nameOfBuilderMethod, builderClass.getName()) + e.getMessage()); } }); } diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java index c017eb4f8..c5170f814 100644 --- a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java +++ b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java @@ -39,26 +39,26 @@ public final class MutableToFooWithBuilderMultipleConstructor { private MutableToFooWithBuilderMultipleConstructor() { } - static class Pippo { + static class Builder { private String name; private BigInteger id; private List list; private List nestedObjectList; private MutableToSubFoo nestedObject; - Pippo(final String name) { + Builder(final String name) { this.name = name; } - Pippo() { + Builder() { } - public Pippo withName(final String name) { + public Builder withName(final String name) { this.name = name; return this; } - public Pippo withId(final BigInteger id) { + public Builder withId(final BigInteger id) { this.id = id; return this; } diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index bfc499825..1bc002849 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -60,7 +60,6 @@ import com.hotels.beans.sample.immutable.ImmutableToFooInvalid; import com.hotels.beans.sample.immutable.ImmutableToFooMap; import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooNoConstructors; import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; import com.hotels.beans.sample.immutable.ImmutableToFooSimple; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; @@ -206,7 +205,7 @@ private Object[][] dataConstructorErrorTesting() { FromFoo actual = new FromFoo(NAME, ID, null, null, null); return new Object[][] { {"Test that an exception is thrown if the constructor invocation throws exception", actual, ImmutableToFooCustomAnnotation.class}, - {"Test that an exception is thrown if no constructors are defined", actual, ImmutableToFooNoConstructors.class}, +// {"Test that an exception is thrown if no constructors are defined", actual, ImmutableToFooNoConstructors.class}, }; } diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 4799a6fe4..23c5d190d 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -71,7 +71,6 @@ public class ClassUtilsTest { private static final Class CLASS_WITHOUT_CONSTRUCTOR = MixedToFooMissingConstructor.class; private static final int EXPECTED_NOT_STATIC_FIELDS = 1; private static final String NAME = "name"; - private static final String NORMAL_FIELD = "normalField"; private static final int EXPECTED_CLASS_PARAMETERS = 5; private static final String NOT_EXISTING_FIELD_NAME = "notExistingFieldName"; private static final Class CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS = ImmutableToFooSubClass.class; @@ -609,8 +608,7 @@ private Object[][] dataGetClassTypeTesting() { return new Object[][] { {"Tests that the method returns immutable if the given class is immutable", ImmutableToFoo.class, ClassType.IMMUTABLE}, {"Tests that the method returns mutable if the given class is mutable", MutableToFoo.class, ClassType.MUTABLE}, - {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED}, - {"Test that the method returns builder if the given class is a Builder", MutableToFooWithBuilder.class, ClassType.BUILDER} + {"Tests that the method returns mixed if the given class contains both final and not fields", MixedToFoo.class, ClassType.MIXED} }; } From e55d206a4485354d4871c858cc825c38ea4b9b84 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 23 Apr 2019 15:16:53 +0200 Subject: [PATCH 0430/1786] minor: changed constant name --- .../com/hotels/beans/utils/ReflectionUtils.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 547cf0cf5..1fdb9fb8f 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -62,6 +62,11 @@ public final class ReflectionUtils { */ private static final String SETTER_METHOD_NAME_REGEX = "^set[A-Z].*"; + /** + * Name of method inside the Builder Class. + */ + private static final String BUILD_METHOD_NAME = "build"; + /** * Regex for identify dots into a string. */ @@ -72,12 +77,6 @@ public final class ReflectionUtils { */ private final CacheManager cacheManager; - /** - * Name of method inside the Builder Class. - */ - private final String nameOfBuilderMethod = "build"; - - /** * Default constructor. */ @@ -211,11 +210,11 @@ public Method getBuildMethod(final Class builderClass) { final String cacheKey = "BuildMethod-" + builderClass.getName(); return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { - Method method = builderClass.getMethod(nameOfBuilderMethod); + Method method = builderClass.getMethod(BUILD_METHOD_NAME); cacheManager.cacheObject(cacheKey, method); return method; } catch (NoSuchMethodException e) { - throw new MissingMethodException(format("Error while getting method %s in class %s.", nameOfBuilderMethod, builderClass.getName()) + e.getMessage()); + throw new MissingMethodException(format("Error while getting method %s in class %s.", BUILD_METHOD_NAME, builderClass.getName()) + e.getMessage()); } }); } From 4afcbd51febd989eb064a153bd77ada2b6088b47 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 23 Apr 2019 16:06:10 +0200 Subject: [PATCH 0431/1786] removed not used method --- .../com/hotels/beans/utils/ClassUtils.java | 19 ---------- .../hotels/beans/utils/ReflectionUtils.java | 37 +++++++++++++++++++ 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index d992a3b4d..be13fae35 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -371,25 +371,6 @@ public boolean usesBuilderPattern(final Constructor constructor, final Class }); } -// /** -// * Check if nested class contains a valid build method. -// * @param superclass class to be instantiated with the build pattern -// * @return true if we find in nested class a valid build method -// */ -// private boolean isValidBuildMethod(final Class superclass) { -// final String build = "build"; -// String cacheKey = "build-method-" + superclass.getCanonicalName(); -// return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { -// List nestedClasses = asList(getDeclaredClasses(superclass)); -// boolean res = -// !nestedClasses.isEmpty() -// && stream(getDeclaredMethods(nestedClasses.get(0))) -// .anyMatch(method -> method.getName().equals(build) && method.getReturnType().equals(superclass)); -// cacheManager.cacheObject(cacheKey, res); -// return res; -// }); -// } - /** * Returns the builder class. * @param targetClass the class where the builder should be searched diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 1fdb9fb8f..f009ade25 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -29,6 +29,10 @@ import static com.hotels.beans.constant.MethodPrefix.SET; import java.lang.annotation.Annotation; +import java.lang.invoke.CallSite; +import java.lang.invoke.LambdaMetafactory; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -39,6 +43,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import com.hotels.beans.cache.CacheManager; import com.hotels.beans.error.MissingFieldException; @@ -108,6 +113,38 @@ public Object invokeMethod(final Method method, final Object target, final Objec } } + public Object invokeMethod(final String methodName, final Object target) { + try { + Function methodFunction = getMethodFunction(methodName, target.getClass()); + return methodFunction.apply(target); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + /** + * Retrieves the method function. + * @param methodName the method name. + * @param targetClass the class on which invoke the method + * @return the function method + * + * https://www.optaplanner.org/blog/2018/01/09/JavaReflectionButMuchFaster.html + */ + private Function getMethodFunction(final String methodName, final Class targetClass) throws Throwable { + try { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + CallSite site = LambdaMetafactory.metafactory(lookup, + "apply", + MethodType.methodType(Function.class), + MethodType.methodType(Object.class, Object.class), + lookup.findVirtual(targetClass, methodName, MethodType.methodType(Object.class)), + MethodType.methodType(Object.class, targetClass)); + return (Function) site.getTarget().invokeExact(); + } catch (Throwable e) { + throw e; + } + } + /** * Checks if the given method is a setter. * @param method the method to be checked From 58ce8850b37edaf440226f63879efc2007c3b514 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 23 Apr 2019 16:51:02 +0200 Subject: [PATCH 0432/1786] Fixed checkstyle issues --- .../hotels/beans/utils/ReflectionUtils.java | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index f009ade25..1fdb9fb8f 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -29,10 +29,6 @@ import static com.hotels.beans.constant.MethodPrefix.SET; import java.lang.annotation.Annotation; -import java.lang.invoke.CallSite; -import java.lang.invoke.LambdaMetafactory; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -43,7 +39,6 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; import com.hotels.beans.cache.CacheManager; import com.hotels.beans.error.MissingFieldException; @@ -113,38 +108,6 @@ public Object invokeMethod(final Method method, final Object target, final Objec } } - public Object invokeMethod(final String methodName, final Object target) { - try { - Function methodFunction = getMethodFunction(methodName, target.getClass()); - return methodFunction.apply(target); - } catch (Throwable e) { - throw new RuntimeException(e); - } - } - - /** - * Retrieves the method function. - * @param methodName the method name. - * @param targetClass the class on which invoke the method - * @return the function method - * - * https://www.optaplanner.org/blog/2018/01/09/JavaReflectionButMuchFaster.html - */ - private Function getMethodFunction(final String methodName, final Class targetClass) throws Throwable { - try { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - CallSite site = LambdaMetafactory.metafactory(lookup, - "apply", - MethodType.methodType(Function.class), - MethodType.methodType(Object.class, Object.class), - lookup.findVirtual(targetClass, methodName, MethodType.methodType(Object.class)), - MethodType.methodType(Object.class, targetClass)); - return (Function) site.getTarget().invokeExact(); - } catch (Throwable e) { - throw e; - } - } - /** * Checks if the given method is a setter. * @param method the method to be checked From cf75a389cddd66f330ca5c7deade37d55b29a237 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 24 Apr 2019 16:32:00 +0200 Subject: [PATCH 0433/1786] Implemented simple solution for transforming java bean containing a builder --- .../com/hotels/beans/constant/ClassType.java | 6 +- .../beans/transformer/TransformerImpl.java | 22 ++----- .../com/hotels/beans/utils/ClassUtils.java | 62 +++++-------------- .../hotels/beans/utils/ReflectionUtils.java | 37 +++-------- .../hotels/beans/utils/ClassUtilsTest.java | 18 ------ 5 files changed, 29 insertions(+), 116 deletions(-) diff --git a/src/main/java/com/hotels/beans/constant/ClassType.java b/src/main/java/com/hotels/beans/constant/ClassType.java index 4a3e6884a..6c5af701f 100644 --- a/src/main/java/com/hotels/beans/constant/ClassType.java +++ b/src/main/java/com/hotels/beans/constant/ClassType.java @@ -31,11 +31,7 @@ public enum ClassType { /** * The class contains both final and not final fields. */ - MIXED, - /** - * The class could be instantiated with a Builder. - */ - BUILDER; + MIXED; /** * Checks if a the class type instance is equal to the given one. diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index b0858169b..b672e2a23 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -36,7 +36,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.List; import java.util.Optional; @@ -58,29 +57,20 @@ public class TransformerImpl extends AbstractTransformer { @Override protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final Object transformedClass; - Optional> builderClass = classUtils.getBuilderClass(targetClass); - final Class classToTransform = builderClass.isPresent() ? builderClass.get() : targetClass; - final ClassType classType = classUtils.getClassType(classToTransform); + final ClassType classType = classUtils.getClassType(targetClass); if (classType.is(MUTABLE)) { try { - transformedClass = classUtils.getInstance(classToTransform); - injectAllFields(sourceObj, transformedClass, breadcrumb); + k = classUtils.getInstance(targetClass); + injectAllFields(sourceObj, k, breadcrumb); } catch (Exception e) { throw new InvalidBeanException(e.getMessage(), e); } } else { - transformedClass = injectValues(sourceObj, classToTransform, classUtils.getAllArgsConstructor(classToTransform), breadcrumb); + k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); if (classType.is(MIXED)) { - injectNotFinalFields(sourceObj, transformedClass, breadcrumb); + injectNotFinalFields(sourceObj, k, breadcrumb); } } - if (builderClass.isPresent()) { - Method method = reflectionUtils.getBuildMethod(classToTransform); - k = (K) reflectionUtils.invokeMethod(method, transformedClass); - } else { - k = (K) transformedClass; - } if (!settings.isValidationDisabled()) { validationUtils.validate(k); } @@ -118,7 +108,7 @@ private K injectValues(final T sourceObj, final Class targetClass, fin constructorArgs = getConstructorValuesFromFields(sourceObj, targetClass, breadcrumb); } try { - return (K) constructor.newInstance(constructorArgs); + return (K) classUtils.getInstance(constructor, constructorArgs); } catch (final Exception e) { throw new InvalidBeanException("Constructor invoked with arguments. Expected: " + constructor + "; Found: " + getFormattedConstructorArgs(targetClass, constructorArgs) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index be13fae35..b79ae017a 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -53,7 +53,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Stream; @@ -70,11 +69,6 @@ public final class ClassUtils { */ private static final String CLAZZ_CANNOT_BE_NULL = "clazz cannot be null!"; - /** - * Default method name used by a Builder for creating an object. - */ - private static final String BUILD_METHOD_NAME = "build"; - /** * Reflection utils instance {@link ReflectionUtils}. */ @@ -355,41 +349,6 @@ public boolean hasAccessibleConstructors(final Class targetClass) { }); } - /** - * Checks if the destination class uses the Builder pattern. - * @param constructor the all args constructor - * @param targetClass the destination object class - * @param the target object type - * @return true if the target class uses the builder pattern - */ - public boolean usesBuilderPattern(final Constructor constructor, final Class targetClass) { - final String cacheKey = "UsesBuilderPattern-" + constructor.getDeclaringClass().getName(); - return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final boolean res = !isPublic(constructor.getModifiers()) && getBuilderClass(targetClass).isPresent(); - cacheManager.cacheObject(cacheKey, res); - return res; - }); - } - - /** - * Returns the builder class. - * @param targetClass the class where the builder should be searched - * @return the Builder class if available. - */ - @SuppressWarnings("unchecked") - public Optional> getBuilderClass(final Class targetClass) { - String cacheKey = "BuilderClass-" + targetClass.getName(); - return cacheManager.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional res = stream(getDeclaredClasses(targetClass)) - .filter(nestedClass -> - stream(getDeclaredMethods(nestedClass)) - .anyMatch(method -> method.getName().equals(BUILD_METHOD_NAME) && method.getReturnType().equals(targetClass))) - .findAny(); - cacheManager.cacheObject(cacheKey, res); - return res; - }); - } - /** * Retrieves all classes defined into the given one. * @param clazz class where we search for a nested class @@ -397,7 +356,7 @@ public Optional> getBuilderClass(final Class targetClass) { */ public Class[] getDeclaredClasses(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - String cacheKey = "nested-classes-" + clazz.getName(); + String cacheKey = "DeclaredClasses-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Class[].class).orElseGet(() -> { Class[] declaredClasses = clazz.getDeclaredClasses(); cacheManager.cacheObject(cacheKey, declaredClasses); @@ -406,22 +365,31 @@ public Class[] getDeclaredClasses(final Class clazz) { } /** - * Retrieves an object from cache. + * Creates an instance of the given class invoking the no args constructor. * @param objectClass the class of the object to return. * @param the class object type. * @return the object instance. * @throws Exception in case the object creation fails. */ public T getInstance(final Class objectClass) throws Exception { - Constructor constructor = getNoArgsConstructor(objectClass); + return getInstance(getNoArgsConstructor(objectClass), null); + } + + /** + * Creates an instance of the given class invoking the given constructor. + * @param constructor the constructor to invoke. + * @param constructorArgs the constructor args. + * @param the class object type. + * @return the object instance. + * @throws Exception in case the object creation fails. + */ + public T getInstance(final Constructor constructor, final Object... constructorArgs) throws Exception { boolean isAccessible = constructor.isAccessible(); try { if (!isAccessible) { constructor.setAccessible(true); } - return (T) constructor.newInstance(); - } catch (Exception e) { - throw e; + return (T) constructor.newInstance(constructorArgs); } finally { constructor.setAccessible(isAccessible); } diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 1fdb9fb8f..55dd746ff 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -16,7 +16,6 @@ package com.hotels.beans.utils; -import static java.lang.String.format; import static java.lang.reflect.Modifier.isPublic; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; @@ -62,11 +61,6 @@ public final class ReflectionUtils { */ private static final String SETTER_METHOD_NAME_REGEX = "^set[A-Z].*"; - /** - * Name of method inside the Builder Class. - */ - private static final String BUILD_METHOD_NAME = "build"; - /** * Regex for identify dots into a string. */ @@ -92,20 +86,21 @@ public ReflectionUtils() { * @return the method result */ public Object invokeMethod(final Method method, final Object target, final Object... args) { - boolean isAccessible = method.isAccessible(); +// boolean isAccessible = method.isAccessible(); try { - if (!isAccessible) { - method.setAccessible(true); - } +// if (!isAccessible) { +// method.setAccessible(true); +// } return method.invoke(target, args); } catch (MissingFieldException | MissingMethodException e) { throw e; } catch (final Exception e) { handleReflectionException(e); throw new IllegalStateException(e); - } finally { - method.setAccessible(isAccessible); } +// finally { +// method.setAccessible(isAccessible); +// } } /** @@ -201,24 +196,6 @@ public A getFieldAnnotation(final Field field, final Clas }); } - /** - * Get build method inside the class. - * @param builderClass Class whit a build method (see Builder Pattern) - * @return Build method if present - */ - public Method getBuildMethod(final Class builderClass) { - final String cacheKey = "BuildMethod-" + builderClass.getName(); - return cacheManager.getFromCache(cacheKey, Method.class).orElseGet(() -> { - try { - Method method = builderClass.getMethod(BUILD_METHOD_NAME); - cacheManager.cacheObject(cacheKey, method); - return method; - } catch (NoSuchMethodException e) { - throw new MissingMethodException(format("Error while getting method %s in class %s.", BUILD_METHOD_NAME, builderClass.getName()) + e.getMessage()); - } - }); - } - /** * Returns (if existing) the constructor parameter's given type annotation. * @param parameter the field that should have the annotation diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 23c5d190d..4fc9dcef0 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -655,24 +655,6 @@ public void testGetDefaultTypeValueWorksAsExpected() { assertEquals(EXPECTED_DEFAULT_VALUE, actual); } - /** - * Tests that the method {@code usesBuilderPattern} works as expected. - * @param testCaseDescription the test case description - * @param testClass the class to test - * @param expectedResult the expected result - */ - @Test(dataProvider = "dataUsesBuilderPatternTesting") - public void testUsesBuilderPatternWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { - // GIVEN - final Constructor constructor = underTest.getAllArgsConstructor(testClass); - - // WHEN - final boolean usesBuilderPattern = underTest.usesBuilderPattern(constructor, testClass); - - // THEN - assertEquals(expectedResult, usesBuilderPattern); - } - /** * Creates the parameters to be used for testing the method {@code usesBuilderPattern}. * @return parameters to be used for testing the the method {@code usesBuilderPattern}. From 584a267a0ddc85e95f3e6d786de53099f5a0ec7b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 24 Apr 2019 16:43:46 +0200 Subject: [PATCH 0434/1786] Modified exceptions throw --- .../hotels/beans/transformer/TransformerImpl.java | 8 ++------ src/main/java/com/hotels/beans/utils/ClassUtils.java | 12 +++++++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index b672e2a23..0ad8fbcf6 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -59,12 +59,8 @@ protected final K transform(final T sourceObj, final Class t final K k; final ClassType classType = classUtils.getClassType(targetClass); if (classType.is(MUTABLE)) { - try { - k = classUtils.getInstance(targetClass); - injectAllFields(sourceObj, k, breadcrumb); - } catch (Exception e) { - throw new InvalidBeanException(e.getMessage(), e); - } + k = classUtils.getInstance(targetClass); + injectAllFields(sourceObj, k, breadcrumb); } else { k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); if (classType.is(MIXED)) { diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index b79ae017a..b857ce262 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -369,10 +369,16 @@ public Class[] getDeclaredClasses(final Class clazz) { * @param objectClass the class of the object to return. * @param the class object type. * @return the object instance. - * @throws Exception in case the object creation fails. + * @throws InvalidBeanException in case the object creation fails. */ - public T getInstance(final Class objectClass) throws Exception { - return getInstance(getNoArgsConstructor(objectClass), null); + public T getInstance(final Class objectClass) { + try { + return getInstance(getNoArgsConstructor(objectClass), null); + } catch (final NoSuchMethodException e) { + throw new InvalidBeanException("No default constructor defined for class: " + objectClass.getName(), e); + } catch (final Exception e) { + throw new InvalidBeanException(e.getMessage(), e); + } } /** From 7177beaf2d0f0bb98ace6bc9b1e03cf1a8ab729e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 24 Apr 2019 18:59:36 +0200 Subject: [PATCH 0435/1786] Minor fixes --- .../com/hotels/beans/utils/ClassUtils.java | 5 ++- .../hotels/beans/utils/ReflectionUtils.java | 40 +++++++++++-------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index b857ce262..1357c2704 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -373,7 +373,7 @@ public Class[] getDeclaredClasses(final Class clazz) { */ public T getInstance(final Class objectClass) { try { - return getInstance(getNoArgsConstructor(objectClass), null); + return getInstance(getNoArgsConstructor(objectClass)); } catch (final NoSuchMethodException e) { throw new InvalidBeanException("No default constructor defined for class: " + objectClass.getName(), e); } catch (final Exception e) { @@ -389,8 +389,9 @@ public T getInstance(final Class objectClass) { * @return the object instance. * @throws Exception in case the object creation fails. */ + @SuppressWarnings("unchecked") public T getInstance(final Constructor constructor, final Object... constructorArgs) throws Exception { - boolean isAccessible = constructor.isAccessible(); + boolean isAccessible = reflectionUtils.isAccessible(constructor, null, "IsAccessible-" + constructor.getName() + constructor.getParameterCount()); try { if (!isAccessible) { constructor.setAccessible(true); diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 55dd746ff..dbded549e 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -28,6 +28,7 @@ import static com.hotels.beans.constant.MethodPrefix.SET; import java.lang.annotation.Annotation; +import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -86,21 +87,23 @@ public ReflectionUtils() { * @return the method result */ public Object invokeMethod(final Method method, final Object target, final Object... args) { -// boolean isAccessible = method.isAccessible(); + boolean isAccessible = isAccessible(method, target, "IsAccessible-" + method.getName() + + method.getParameterCount() + "-" + target.getClass().getName()); try { -// if (!isAccessible) { -// method.setAccessible(true); -// } + if (!isAccessible) { + method.setAccessible(true); + } return method.invoke(target, args); } catch (MissingFieldException | MissingMethodException e) { throw e; } catch (final Exception e) { handleReflectionException(e); throw new IllegalStateException(e); + } finally { + if (!isAccessible) { + method.setAccessible(false); + } } -// finally { -// method.setAccessible(isAccessible); -// } } /** @@ -227,7 +230,7 @@ private Object getFieldValue(final Object target, final String fieldName) { Field field = null; try { field = getDeclaredField(fieldName, target.getClass()); - isAccessible = isFieldAccessible(field, target); + isAccessible = isAccessible(field, target, "IsAccessible-" + fieldName + "-" + target.getClass().getName()); if (!isAccessible) { field.setAccessible(true); } @@ -273,7 +276,7 @@ public Field getDeclaredField(final String fieldName, final Class targetClass } /** - * Sets the value of a field through setter method. + * Set the value of a field. * @param target the field's class * @param field the field to set * @param fieldValue the value to set @@ -289,13 +292,13 @@ public void setFieldValue(final Object target, final Field field, final Object f } /** - * Sets the value of a field through {@link Field#set} method. + * Set the value of a field through {@link Field#set} method. * @param target the field's class * @param field the field to set * @param fieldValue the value to set */ private void setFieldValueWithoutSetterMethod(final Object target, final Field field, final Object fieldValue) { - final boolean isAccessible = isFieldAccessible(field, target); + final boolean isAccessible = isAccessible(field, target, "IsAccessible-" + field.getName() + "-" + target.getClass().getName()); try { if (!isAccessible) { field.setAccessible(true); @@ -312,14 +315,19 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f } /** - * Check if a field is accessible or not. - * To make the project compiling with Java version > 8, replace the following line with: {@code field.canAccess(target);} - * @param field the field to check + * Check if the given object is accessible or not. + * To make the project compiling with Java version greater than 8, replace the following line with: {@code accessibleObject.canAccess(target);} + * @param accessibleObject the object to check * @param target the field's class + * @param cacheKey the cache key * @return true id is accessible, false otherwise */ - private boolean isFieldAccessible(final Field field, final Object target) { - return field.isAccessible(); + protected boolean isAccessible(final AccessibleObject accessibleObject, final Object target, final String cacheKey) { + return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { + Boolean res = accessibleObject.isAccessible(); + cacheManager.cacheObject(cacheKey, res); + return res; + }); } /** From 406e5b8012afb13b093a07c8dfec27f351fdfc89 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 24 Apr 2019 19:09:40 +0200 Subject: [PATCH 0436/1786] removed isAccessible caching --- .../java/com/hotels/beans/utils/ClassUtils.java | 2 +- .../com/hotels/beans/utils/ReflectionUtils.java | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 1357c2704..93d426bf4 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -391,7 +391,7 @@ public T getInstance(final Class objectClass) { */ @SuppressWarnings("unchecked") public T getInstance(final Constructor constructor, final Object... constructorArgs) throws Exception { - boolean isAccessible = reflectionUtils.isAccessible(constructor, null, "IsAccessible-" + constructor.getName() + constructor.getParameterCount()); + boolean isAccessible = reflectionUtils.isAccessible(constructor, null); try { if (!isAccessible) { constructor.setAccessible(true); diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index dbded549e..1e9685d38 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -87,8 +87,7 @@ public ReflectionUtils() { * @return the method result */ public Object invokeMethod(final Method method, final Object target, final Object... args) { - boolean isAccessible = isAccessible(method, target, "IsAccessible-" + method.getName() - + method.getParameterCount() + "-" + target.getClass().getName()); + boolean isAccessible = isAccessible(method, target); try { if (!isAccessible) { method.setAccessible(true); @@ -230,7 +229,7 @@ private Object getFieldValue(final Object target, final String fieldName) { Field field = null; try { field = getDeclaredField(fieldName, target.getClass()); - isAccessible = isAccessible(field, target, "IsAccessible-" + fieldName + "-" + target.getClass().getName()); + isAccessible = isAccessible(field, target); if (!isAccessible) { field.setAccessible(true); } @@ -298,7 +297,7 @@ public void setFieldValue(final Object target, final Field field, final Object f * @param fieldValue the value to set */ private void setFieldValueWithoutSetterMethod(final Object target, final Field field, final Object fieldValue) { - final boolean isAccessible = isAccessible(field, target, "IsAccessible-" + field.getName() + "-" + target.getClass().getName()); + final boolean isAccessible = isAccessible(field, target); try { if (!isAccessible) { field.setAccessible(true); @@ -319,15 +318,10 @@ private void setFieldValueWithoutSetterMethod(final Object target, final Field f * To make the project compiling with Java version greater than 8, replace the following line with: {@code accessibleObject.canAccess(target);} * @param accessibleObject the object to check * @param target the field's class - * @param cacheKey the cache key * @return true id is accessible, false otherwise */ - protected boolean isAccessible(final AccessibleObject accessibleObject, final Object target, final String cacheKey) { - return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - Boolean res = accessibleObject.isAccessible(); - cacheManager.cacheObject(cacheKey, res); - return res; - }); + protected boolean isAccessible(final AccessibleObject accessibleObject, final Object target) { + return accessibleObject.isAccessible(); } /** From cff8cf7a283b1a04ff85c0acfd59a94d694b53e1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 25 Apr 2019 18:47:55 +0200 Subject: [PATCH 0437/1786] Minor improvements --- .../beans/transformer/TransformerImpl.java | 11 ++++-- .../com/hotels/beans/utils/ClassUtils.java | 37 ++++++------------- .../hotels/beans/utils/ReflectionUtils.java | 10 +---- .../mixed/MixedToFooMissingConstructor.java | 10 ++--- .../ImmutableObjectTransformationTest.java | 3 +- .../hotels/beans/utils/ClassUtilsTest.java | 10 ++--- 6 files changed, 30 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 0ad8fbcf6..b0657f613 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -59,8 +59,12 @@ protected final K transform(final T sourceObj, final Class t final K k; final ClassType classType = classUtils.getClassType(targetClass); if (classType.is(MUTABLE)) { - k = classUtils.getInstance(targetClass); - injectAllFields(sourceObj, k, breadcrumb); + try { + k = classUtils.getInstance(classUtils.getNoArgsConstructor(targetClass)); + injectAllFields(sourceObj, k, breadcrumb); + } catch (Exception e) { + throw new InvalidBeanException(e.getMessage(), e); + } } else { k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); if (classType.is(MIXED)) { @@ -95,7 +99,6 @@ protected final void transform(final T sourceObj, final K targetObject, f * @return a copy of the source object into the destination object * @throws InvalidBeanException {@link InvalidBeanException} if the target object is not compliant with the requirements */ - @SuppressWarnings("unchecked") private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { final Object[] constructorArgs; if (canBeInjectedByConstructorParams(constructor, targetClass)) { @@ -104,7 +107,7 @@ private K injectValues(final T sourceObj, final Class targetClass, fin constructorArgs = getConstructorValuesFromFields(sourceObj, targetClass, breadcrumb); } try { - return (K) classUtils.getInstance(constructor, constructorArgs); + return classUtils.getInstance(constructor, constructorArgs); } catch (final Exception e) { throw new InvalidBeanException("Constructor invoked with arguments. Expected: " + constructor + "; Found: " + getFormattedConstructorArgs(targetClass, constructorArgs) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 93d426bf4..a05f7aa5b 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -30,8 +30,6 @@ import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.toList; -import static org.apache.commons.lang3.ArrayUtils.isEmpty; - import static com.hotels.beans.utils.ValidationUtils.notNull; import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; @@ -398,23 +396,26 @@ public T getInstance(final Constructor constructor, final Object... construc } return (T) constructor.newInstance(constructorArgs); } finally { - constructor.setAccessible(isAccessible); + if (!isAccessible) { + constructor.setAccessible(false); + } } } /** * Retrieves the no args constructor. - * @param clazz the class from which gets the constructor. + * @param clazz the class from which gets the all arg constructor. * @param the object type - * @return the all args constructor + * @return the no args constructor */ public Constructor getNoArgsConstructor(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "NoArgsConstructor-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { - final Constructor constructor = min(asList(clazz.getDeclaredConstructors()), comparing(Constructor::getParameterCount)); + Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); + final Constructor constructor = min(asList(declaredConstructors), comparing(Constructor::getParameterCount)); if (constructor.getParameterCount() != 0) { - throw new InvalidBeanException("No default constructor defined for class: " + clazz.getName()); + throw new InvalidBeanException("No default constructors available"); } cacheManager.cacheObject(cacheKey, constructor); return constructor; @@ -422,7 +423,7 @@ public Constructor getNoArgsConstructor(final Class clazz) { } /** - * Retrieves the constructor with more parameters. + * Retrieves the all args constructor. * @param clazz the class from which gets the all arg constructor. * @param the object type * @return the all args constructor @@ -431,24 +432,8 @@ public Constructor getAllArgsConstructor(final Class clazz) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "AllArgsConstructor-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { - Constructor constructor = getAllArgsConstructor(clazz.getDeclaredConstructors()); - cacheManager.cacheObject(cacheKey, constructor); - return constructor; - }); - } - - /** - * Retrieves the all args constructor. - * @param constructors class constructors - * @return the all args constructor - */ - public Constructor getAllArgsConstructor(final Constructor[] constructors) { - if (isEmpty(constructors)) { - throw new InvalidBeanException("No constructors available"); - } - final String cacheKey = "AllArgsConstructorFromConstructor-" + constructors[0].getDeclaringClass().getName(); - return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { - final Constructor constructor = max(asList(constructors), comparing(Constructor::getParameterCount)); + Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); + final Constructor constructor = max(asList(declaredConstructors), comparing(Constructor::getParameterCount)); cacheManager.cacheObject(cacheKey, constructor); return constructor; }); diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 1e9685d38..261669ef7 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -86,22 +86,14 @@ public ReflectionUtils() { * @param args the method parameters * @return the method result */ - public Object invokeMethod(final Method method, final Object target, final Object... args) { - boolean isAccessible = isAccessible(method, target); + private Object invokeMethod(final Method method, final Object target, final Object... args) { try { - if (!isAccessible) { - method.setAccessible(true); - } return method.invoke(target, args); } catch (MissingFieldException | MissingMethodException e) { throw e; } catch (final Exception e) { handleReflectionException(e); throw new IllegalStateException(e); - } finally { - if (!isAccessible) { - method.setAccessible(false); - } } } diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java index e3522ff19..e3a225c28 100644 --- a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java +++ b/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -16,24 +16,24 @@ package com.hotels.beans.sample.mixed; -import static lombok.AccessLevel.PRIVATE; - import java.math.BigInteger; import javax.validation.constraints.NotNull; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.ToString; /** * Sample mixed object. */ -@NoArgsConstructor(access = PRIVATE) @Getter @ToString public class MixedToFooMissingConstructor { @NotNull public BigInteger id; - private final String name = null; + private final String name; + + public MixedToFooMissingConstructor(final String name) { + this.name = name; + } } diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 1bc002849..eae65edfd 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -204,8 +204,7 @@ public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsExceptio private Object[][] dataConstructorErrorTesting() { FromFoo actual = new FromFoo(NAME, ID, null, null, null); return new Object[][] { - {"Test that an exception is thrown if the constructor invocation throws exception", actual, ImmutableToFooCustomAnnotation.class}, -// {"Test that an exception is thrown if no constructors are defined", actual, ImmutableToFooNoConstructors.class}, + {"Test that an exception is thrown if the constructor invocation throws exception", actual, ImmutableToFooCustomAnnotation.class} }; } diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 4fc9dcef0..1cc0b0baf 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -398,21 +398,21 @@ public void testGetAllArgsConstructorWorksAsExpected() { // GIVEN // WHEN - Constructor actual = underTest.getAllArgsConstructor(CLASS_WITH_PRIVATE_FINAL_FIELDS.getConstructors()); + Constructor actual = underTest.getAllArgsConstructor(CLASS_WITH_PRIVATE_FINAL_FIELDS); // THEN assertNotNull(actual); } /** - * Tests that the method {@code getAllArgsConstructor} throws exception if the class has no all args constructor. + * Tests that the method {@code getNoArgsConstructor} throws exception if the class has no all args constructor. */ @Test(expectedExceptions = InvalidBeanException.class) - public void testGetAllArgsConstructorThrowsExceptionIfTheConstructorIsMissing() { + public void testGetNoArgsConstructorThrowsExceptionIfTheConstructorIsMissing() { // GIVEN // WHEN - underTest.getAllArgsConstructor(CLASS_WITHOUT_CONSTRUCTOR.getConstructors()); + underTest.getNoArgsConstructor(CLASS_WITHOUT_CONSTRUCTOR); } /** @@ -421,7 +421,7 @@ public void testGetAllArgsConstructorThrowsExceptionIfTheConstructorIsMissing() @Test public void testGetConstructorParameters() { // GIVEN - Constructor classConstructor = underTest.getAllArgsConstructor(CLASS_WITH_PRIVATE_FINAL_FIELDS.getConstructors()); + Constructor classConstructor = underTest.getAllArgsConstructor(CLASS_WITH_PRIVATE_FINAL_FIELDS); // WHEN Parameter[] constructorParameters = underTest.getConstructorParameters(classConstructor); From ce45d7394761c6460df0cd1d99a41dbe98376bee Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 25 Apr 2019 18:51:14 +0200 Subject: [PATCH 0438/1786] Raised test coverage ratio --- pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 7f0063f05..0e5562595 100644 --- a/pom.xml +++ b/pom.xml @@ -40,12 +40,12 @@ 2.2.6 0.8.2 - 0.80 - 0.80 - 0.80 - 0.75 - 0.80 - 0.80 + 0.85 + 0.85 + 0.85 + 0.85 + 0.85 + 0.85 3.2.0 0.12 From 637e8e61e6a21a10bd380e32c61cfc98dba27cc6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 25 Apr 2019 19:13:00 +0200 Subject: [PATCH 0439/1786] Fixed potential bug --- .../com/hotels/beans/cache/CacheManager.java | 3 --- .../hotels/beans/populator/ArrayPopulator.java | 2 +- .../java/com/hotels/beans/utils/ClassUtils.java | 2 +- .../beans/populator/ArrayPopulatorTest.java | 16 +++++++++++++++- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/src/main/java/com/hotels/beans/cache/CacheManager.java index 6a3e4c88b..a59846a29 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -19,14 +19,12 @@ import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; -import static lombok.AccessLevel.PRIVATE; import static lombok.AccessLevel.PROTECTED; import java.util.Map; import java.util.Optional; import lombok.AllArgsConstructor; -import lombok.Getter; /** * Cache Utils class. @@ -36,7 +34,6 @@ public final class CacheManager { /** * Cache store. */ - @Getter(PRIVATE) private final Map cacheMap; /** diff --git a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index cd9180f7c..5814c78a8 100644 --- a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -54,7 +54,7 @@ public Object getPopulatedObject(final Class fieldType, final Class generi } else { res = stream((Object[]) fieldValue) //.parallel() - .map(o -> classUtils.isPrimitiveOrSpecialType(genericFieldType) ? o : transform(o, genericFieldType)).toArray(); + .map(o -> classUtils.isPrimitiveOrSpecialType(o.getClass()) ? o : transform(o, genericFieldType)).toArray(); } return res; } diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index a05f7aa5b..2d7145efd 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -107,7 +107,7 @@ public boolean isPrimitiveOrSpecialType(final Class clazz) { public boolean isPrimitiveType(final Class clazz) { final String cacheKey = "isPrimitive-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = clazz.isPrimitive() || clazz.equals(String.class) || clazz.isEnum() || Number.class.isAssignableFrom(clazz); + final Boolean res = clazz.isPrimitive() || clazz.equals(String.class) || clazz.equals(Boolean.class) || clazz.isEnum() || Number.class.isAssignableFrom(clazz); cacheManager.cacheObject(cacheKey, res); return res; }); diff --git a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 812e084de..807adebc5 100644 --- a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -16,6 +16,9 @@ package com.hotels.beans.populator; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -83,6 +86,8 @@ public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, assertArrayEquals((char[]) array, (char[]) actual); } else if (genericFieldType == Integer.class) { assertArrayEquals((int[]) array, (int[]) actual); + } else if (genericFieldType == Object.class) { + assertArrayEquals((Object[]) array, (Object[]) actual); } else if (genericFieldType == MixedToFooStaticField.class) { final MixedToFooStaticField[] expectedArray = (MixedToFooStaticField[]) array; final Object[] actualArray = (Object[]) actual; @@ -103,7 +108,8 @@ public Object[][] dataProvider() { {String.class, STRING_ARRAY, null}, {Character.class, CHAR_ARRAY, null}, {Integer.class, INT_ARRAY, null}, - {MixedToFooStaticField.class, createMixedToFooArray(), null} + {MixedToFooStaticField.class, createMixedToFooArray(), null}, + {Object.class, createBooleanArray(), null} }; } @@ -115,4 +121,12 @@ private static MixedToFooStaticField[] createMixedToFooArray() { MIXED_TO_FOO_STATIC_FIELDS_OBJECTS.setNormalField(VAL_1); return new MixedToFooStaticField[] {MIXED_TO_FOO_STATIC_FIELDS_OBJECTS}; } + + /** + * Creates an array containing an instance of {@link Boolean}. + * @return an array containing an instance of {@link Boolean}. + */ + private static Object[] createBooleanArray() { + return new Object[] {TRUE, FALSE}; + } } From 4b3bac5908dc7b3b2715a05b990b42d903df8968 Mon Sep 17 00:00:00 2001 From: antimo Date: Fri, 26 Apr 2019 12:17:01 +0200 Subject: [PATCH 0440/1786] Updated description of method testTransformationThroughBuilder (we test every type of builder) --- .../beans/transformer/BuilderObjectTransformationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 084800a7b..8acaaf6a4 100644 --- a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -51,7 +51,7 @@ public void beforeMethod() { } /** - * Test mutable beans are correctly copied through builder. + * Test mutable / immutable / mixed beans are correctly copied through builder. * @param testDescription the test case description * @param sourceObject the object to transform * @param targetObjectClass the target object class From eabfecc6e116878a981e628cf53e2c9c5203cf3a Mon Sep 17 00:00:00 2001 From: antimo Date: Fri, 26 Apr 2019 12:26:44 +0200 Subject: [PATCH 0441/1786] Updated description of method testTransformationThroughBuilder (we test every type of builder) --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 387b22c3e..2479486f8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [TO BE DEFINED] 2019.04.26 +#### Added +* Added support for copying Bean into Object populated with Builder Pattern + ### [1.2.7] 2019.04.18 #### Changed * Improved optional usage. From 52464cb58fc048b1cc0c7e49975fdeef6566374d Mon Sep 17 00:00:00 2001 From: antimo Date: Fri, 26 Apr 2019 12:26:44 +0200 Subject: [PATCH 0442/1786] Updated CHANGELOG with "Added support for copying Bean Into Object populated with Builder Pattern" --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 387b22c3e..2479486f8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [TO BE DEFINED] 2019.04.26 +#### Added +* Added support for copying Bean into Object populated with Builder Pattern + ### [1.2.7] 2019.04.18 #### Changed * Improved optional usage. From cbec465e0af24a7b6c8114c5168c9911161b6a02 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 26 Apr 2019 14:41:24 +0200 Subject: [PATCH 0443/1786] minor: added test case --- src/test/java/com/hotels/beans/utils/ClassUtilsTest.java | 3 ++- src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 1cc0b0baf..5422394bc 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -126,7 +126,8 @@ public void testIsPrimitiveTypeWorksAsExpected(final String testCaseDescription, private Object[][] dataIsPrimitiveTypeObjectTesting() { return new Object[][] { {"Tests that the method returns true if the class is a primitive type object", BigDecimal.class, true}, - {"Tests that the method returns false if the class is not a primitive type object", FromFoo.class, false} + {"Tests that the method returns false if the class is not a primitive type object", FromFoo.class, false}, + {"Tests that the method returns true if the class is not a Boolean", Boolean.class, true} }; } diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index 2265c0eab..e9a3db9dd 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -211,6 +211,7 @@ private Object[][] dataGetGetterMethodPrefixTesting() throws Exception { * @param testCaseDescription the test case description * @param annotationToGet the annotation to retrieve * @param expectNull true if it's expected to find it null, false otherwise + * @throws NoSuchFieldException if the field does not exists. */ @Test(dataProvider = "dataGetFieldAnnotationTesting") public void testGetFieldAnnotationWorksProperly(final String testCaseDescription, final Class annotationToGet, From 1b1bb68bb542bd899a70f0c39761d77a9391d62a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 26 Apr 2019 15:24:10 +0200 Subject: [PATCH 0444/1786] Added specific exception in case the getInstance fails --- .../error/InstanceCreationException.java | 43 +++++++++++++++++++ .../com/hotels/beans/utils/ClassUtils.java | 25 +++-------- 2 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/hotels/beans/error/InstanceCreationException.java diff --git a/src/main/java/com/hotels/beans/error/InstanceCreationException.java b/src/main/java/com/hotels/beans/error/InstanceCreationException.java new file mode 100644 index 000000000..4a6fad4ea --- /dev/null +++ b/src/main/java/com/hotels/beans/error/InstanceCreationException.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2019 Expedia Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.error; + +/** + * Instance creation exception class. + */ +public class InstanceCreationException extends RuntimeException { + /** + * Constructs a new instance creation exception with the specified detail message. + * The cause is the call of newInstance method throws an Exception. + * @param message the detail message. The detail message is saved for later + * retrieval by the {@link #getMessage()} method. + */ + public InstanceCreationException(final String message) { + super(message); + } + + /** + * Constructs a new instance creation exception with the specified detail message. + * The cause is the call of newInstance method throws an Exception. + * @param message the detail message. The detail message is saved for later + * retrieval by the {@link #getMessage()} method. + * @param cause the given bean is not valid and caused an exception while copying the properties. + */ + public InstanceCreationException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 2d7145efd..3e0f9bfe0 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -43,6 +43,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.time.temporal.Temporal; @@ -56,6 +57,7 @@ import com.hotels.beans.cache.CacheManager; import com.hotels.beans.constant.ClassType; +import com.hotels.beans.error.InstanceCreationException; import com.hotels.beans.error.InvalidBeanException; /** @@ -362,39 +364,24 @@ public Class[] getDeclaredClasses(final Class clazz) { }); } - /** - * Creates an instance of the given class invoking the no args constructor. - * @param objectClass the class of the object to return. - * @param the class object type. - * @return the object instance. - * @throws InvalidBeanException in case the object creation fails. - */ - public T getInstance(final Class objectClass) { - try { - return getInstance(getNoArgsConstructor(objectClass)); - } catch (final NoSuchMethodException e) { - throw new InvalidBeanException("No default constructor defined for class: " + objectClass.getName(), e); - } catch (final Exception e) { - throw new InvalidBeanException(e.getMessage(), e); - } - } - /** * Creates an instance of the given class invoking the given constructor. * @param constructor the constructor to invoke. * @param constructorArgs the constructor args. * @param the class object type. * @return the object instance. - * @throws Exception in case the object creation fails. + * @throws InstanceCreationException in case the object creation fails. */ @SuppressWarnings("unchecked") - public T getInstance(final Constructor constructor, final Object... constructorArgs) throws Exception { + public T getInstance(final Constructor constructor, final Object... constructorArgs) { boolean isAccessible = reflectionUtils.isAccessible(constructor, null); try { if (!isAccessible) { constructor.setAccessible(true); } return (T) constructor.newInstance(constructorArgs); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { + throw new InstanceCreationException(e.getMessage(), e); } finally { if (!isAccessible) { constructor.setAccessible(false); From b4e0e2bc2537a7620dae110bfca26f6fc3b8974f Mon Sep 17 00:00:00 2001 From: antimo Date: Fri, 26 Apr 2019 15:24:43 +0200 Subject: [PATCH 0445/1786] Fixed as per comment on Pull Request --- CHANGELOG.md | 4 ++-- .../beans/transformer/BuilderObjectTransformationTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2479486f8..2cd7efa5e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,9 @@ All notable changes to this project will be documented in this file. -### [TO BE DEFINED] 2019.04.26 +### [1.2.8] TBD #### Added -* Added support for copying Bean into Object populated with Builder Pattern +* Added support for the transformation of Java Beans built through Builder ### [1.2.7] 2019.04.18 #### Changed diff --git a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 8acaaf6a4..9bd663cf6 100644 --- a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -51,7 +51,7 @@ public void beforeMethod() { } /** - * Test mutable / immutable / mixed beans are correctly copied through builder. + * Test mutable,immutable,mixed beans are correctly copied through builder. * @param testDescription the test case description * @param sourceObject the object to transform * @param targetObjectClass the target object class From 63f671fd9b78168d09a8dbd71be15ca524adbc6f Mon Sep 17 00:00:00 2001 From: antimo Date: Fri, 26 Apr 2019 15:32:31 +0200 Subject: [PATCH 0446/1786] Removed unused method getInstance (with no args constructor) --- .../java/com/hotels/beans/utils/ClassUtils.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 2d7145efd..3e6b2f4be 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -362,23 +362,6 @@ public Class[] getDeclaredClasses(final Class clazz) { }); } - /** - * Creates an instance of the given class invoking the no args constructor. - * @param objectClass the class of the object to return. - * @param the class object type. - * @return the object instance. - * @throws InvalidBeanException in case the object creation fails. - */ - public T getInstance(final Class objectClass) { - try { - return getInstance(getNoArgsConstructor(objectClass)); - } catch (final NoSuchMethodException e) { - throw new InvalidBeanException("No default constructor defined for class: " + objectClass.getName(), e); - } catch (final Exception e) { - throw new InvalidBeanException(e.getMessage(), e); - } - } - /** * Creates an instance of the given class invoking the given constructor. * @param constructor the constructor to invoke. From 9a17d7190e3e9d34f55f9229bedd1abdfe70e473 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 26 Apr 2019 15:38:35 +0200 Subject: [PATCH 0447/1786] Updated documentation --- CHANGELOG.md | 4 ++++ README.md | 1 + docs/site/markdown/index.md | 1 + 3 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cd7efa5e..467acd99b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,10 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.14] TBD +#### Added +* Added support for the transformation of Java Beans built through Builder + ### [1.1.13] 2019.04.18 #### Changed * Improved optional usage. diff --git a/README.md b/README.md index e9cea1a80..6dfde75ab 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ mvn clean install -P relaxed * support validation through annotations. * support copy of beans with different field's name. * support lambda function field transformation. +* support copy of java bean built through Builder. * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. * allows to skip transformation for a given set of fields. diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 2f50ab8f7..2b3d1820d 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -28,6 +28,7 @@ This BeanUtils library is a utility library for managing Bean objects. The libra * support validation through annotations. * support copy of beans with different field's name. * support lambda function field transformation. + * support copy of java bean built through Builder. * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. * allows to skip transformation for a given set of fields. From 4858d9929b02076a2beca85b60541abc89c4cccd Mon Sep 17 00:00:00 2001 From: antimo Date: Fri, 26 Apr 2019 16:07:12 +0200 Subject: [PATCH 0448/1786] Removed version 1.1.14 in CHANGELOG.md, erroneously created by a missing pull from upstream --- CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 467acd99b..2cd7efa5e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,10 +49,6 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created -### [1.1.14] TBD -#### Added -* Added support for the transformation of Java Beans built through Builder - ### [1.1.13] 2019.04.18 #### Changed * Improved optional usage. From 666ff6949fc3ee9c97689baa244691e376fb74f2 Mon Sep 17 00:00:00 2001 From: antimo Date: Fri, 26 Apr 2019 16:19:35 +0200 Subject: [PATCH 0449/1786] Readded version 1.1.14 in CHANGELOG.md (previously deleted by mistake) --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cd7efa5e..467acd99b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,10 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created +### [1.1.14] TBD +#### Added +* Added support for the transformation of Java Beans built through Builder + ### [1.1.13] 2019.04.18 #### Changed * Improved optional usage. From 96fb7dbb7fa5d19bfe03b5643e43417d02ce6cc0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Apr 2019 00:00:05 +0200 Subject: [PATCH 0450/1786] Removed not needed checks as per pull request --- src/main/java/com/hotels/beans/utils/ClassUtils.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 3e0f9bfe0..2e8fbc228 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -396,7 +396,6 @@ public T getInstance(final Constructor constructor, final Object... construc * @return the no args constructor */ public Constructor getNoArgsConstructor(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "NoArgsConstructor-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); @@ -416,7 +415,6 @@ public Constructor getNoArgsConstructor(final Class clazz) { * @return the all args constructor */ public Constructor getAllArgsConstructor(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); final String cacheKey = "AllArgsConstructor-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); From 07e679f02aeec38e73af812b96d123083c5cddb9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 15:13:33 +0200 Subject: [PATCH 0451/1786] Improved isPrimitiveTypeMethod --- pom.xml | 2 +- .../java/com/hotels/beans/utils/ClassUtils.java | 16 +++++++++++++--- .../com/hotels/beans/utils/ClassUtilsTest.java | 6 +++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 0e5562595..95412082a 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ - ossrh + onatype-nexus-snapshot https://oss.sonatype.org/content/repositories/snapshots diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 2e8fbc228..07449ec95 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -28,6 +28,7 @@ import static java.util.Objects.isNull; import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; +import static java.util.Set.of; import static java.util.stream.Collectors.toList; import static com.hotels.beans.utils.ValidationUtils.notNull; @@ -46,12 +47,15 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; +import java.math.BigDecimal; +import java.math.BigInteger; import java.time.temporal.Temporal; import java.util.ArrayList; import java.util.Currency; import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.function.Predicate; import java.util.stream.Stream; @@ -69,6 +73,12 @@ public final class ClassUtils { */ private static final String CLAZZ_CANNOT_BE_NULL = "clazz cannot be null!"; + /** + * Primitive types list. + */ + private static final Set> PRIMITIVE_TYPES = of(String.class, Boolean.class, Integer.class, Long.class, + Double.class, BigDecimal.class, BigInteger.class, Short.class, Float.class, Character.class, Byte.class); + /** * Reflection utils instance {@link ReflectionUtils}. */ @@ -109,7 +119,7 @@ public boolean isPrimitiveOrSpecialType(final Class clazz) { public boolean isPrimitiveType(final Class clazz) { final String cacheKey = "isPrimitive-" + clazz.getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = clazz.isPrimitive() || clazz.equals(String.class) || clazz.equals(Boolean.class) || clazz.isEnum() || Number.class.isAssignableFrom(clazz); + final Boolean res = clazz.isPrimitive() || PRIMITIVE_TYPES.contains(clazz) || clazz.isEnum(); cacheManager.cacheObject(cacheKey, res); return res; }); @@ -123,8 +133,7 @@ public boolean isPrimitiveType(final Class clazz) { public boolean isPrimitiveTypeArray(final Object object) { final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = object instanceof int[] || object instanceof char[] || object instanceof short[] - || object instanceof long[] || object instanceof byte[] || object instanceof float[] || object instanceof double[]; + final Boolean res = isPrimitiveType(object.getClass().getComponentType()); cacheManager.cacheObject(cacheKey, res); return res; }); @@ -394,6 +403,7 @@ public T getInstance(final Constructor constructor, final Object... construc * @param clazz the class from which gets the all arg constructor. * @param the object type * @return the no args constructor + * @throws InvalidBeanException if no default constructor is available */ public Constructor getNoArgsConstructor(final Class clazz) { final String cacheKey = "NoArgsConstructor-" + clazz.getName(); diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 5422394bc..0f3ceaf62 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -85,6 +85,7 @@ public class ClassUtilsTest { private static final double[] PRIMITIVE_DOUBLE_ARRAY = {}; private static final float[] PRIMITIVE_FLOAT_ARRAY = {}; private static final long[] PRIMITIVE_LONG_ARRAY = {}; + private static final Integer[] PRIMITIVE_INTEGER_ARRAY = {}; private static final FromFoo[] NOT_PRIMITIVE_ARRAY = {}; /** @@ -127,7 +128,9 @@ private Object[][] dataIsPrimitiveTypeObjectTesting() { return new Object[][] { {"Tests that the method returns true if the class is a primitive type object", BigDecimal.class, true}, {"Tests that the method returns false if the class is not a primitive type object", FromFoo.class, false}, - {"Tests that the method returns true if the class is not a Boolean", Boolean.class, true} + {"Tests that the method returns true if the class is not a Boolean", Boolean.class, true}, + {"Tests that the method returns true if the class is not a Character", Character.class, true}, + {"Tests that the method returns true if the class is not a Byte", Byte.class, true} }; } @@ -222,6 +225,7 @@ private Object[][] dataPrimitiveArrayTypeTesting() { {"Tests that the method returns true if the array is of type double[]", PRIMITIVE_DOUBLE_ARRAY, true}, {"Tests that the method returns true if the array is of type float[]", PRIMITIVE_FLOAT_ARRAY, true}, {"Tests that the method returns true if the array is of type long[]", PRIMITIVE_LONG_ARRAY, true}, + {"Tests that the method returns true if the array is of type Integer[]", PRIMITIVE_INTEGER_ARRAY, true}, {"Tests that the method returns false if the array is of type FromFoo[]", NOT_PRIMITIVE_ARRAY, false} }; } From 2ae907629c6a2454ee648671068ab0465bf0e324 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 16:39:52 +0200 Subject: [PATCH 0452/1786] Modified object in order to with with java 8 --- .../com/hotels/beans/utils/ClassUtils.java | 6 ++-- .../immutable/ImmutableToFooWithBuilder.java | 13 +++++--- .../sample/mixed/MixedToFooWithBuilder.java | 19 +++++++---- .../mutable/MutableToFooWithBuilder.java | 16 +++++---- ...leToFooWithBuilderMultipleConstructor.java | 33 ++++++++++++++----- 5 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index 07449ec95..fd0978767 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -28,7 +28,6 @@ import static java.util.Objects.isNull; import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; -import static java.util.Set.of; import static java.util.stream.Collectors.toList; import static com.hotels.beans.utils.ValidationUtils.notNull; @@ -52,6 +51,7 @@ import java.time.temporal.Temporal; import java.util.ArrayList; import java.util.Currency; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -76,8 +76,8 @@ public final class ClassUtils { /** * Primitive types list. */ - private static final Set> PRIMITIVE_TYPES = of(String.class, Boolean.class, Integer.class, Long.class, - Double.class, BigDecimal.class, BigInteger.class, Short.class, Float.class, Character.class, Byte.class); + private static final Set> PRIMITIVE_TYPES = new HashSet<>(asList(String.class, Boolean.class, Integer.class, Long.class, + Double.class, BigDecimal.class, BigInteger.class, Short.class, Float.class, Character.class, Byte.class)); /** * Reflection utils instance {@link ReflectionUtils}. diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java index 6b72ad65c..2086b19e0 100644 --- a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java @@ -16,14 +16,11 @@ package com.hotels.beans.sample.immutable; -import static lombok.AccessLevel.PRIVATE; - import java.math.BigInteger; import java.util.List; import com.hotels.beans.sample.FromSubFoo; -import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -32,7 +29,6 @@ */ @Getter @Builder(builderMethodName = "hiddenBuilder") -@AllArgsConstructor(access = PRIVATE) public class ImmutableToFooWithBuilder { private final String name; private final BigInteger id; @@ -40,6 +36,15 @@ public class ImmutableToFooWithBuilder { private final List list; private final FromSubFoo nestedObject; + public ImmutableToFooWithBuilder(final String name, final BigInteger id, final List nestedObjectList, + final List list, final FromSubFoo nestedObject) { + this.name = name; + this.id = id; + this.nestedObjectList = nestedObjectList; + this.list = list; + this.nestedObject = nestedObject; + } + public static ImmutableToFooWithBuilderBuilder builder(final String name, final BigInteger id, final List nestedObjectList, final List list, final FromSubFoo nestedObject) { return hiddenBuilder() diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java b/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java index c2c576074..70d364221 100644 --- a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java +++ b/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java @@ -19,11 +19,8 @@ import java.math.BigInteger; import java.util.List; -import static lombok.AccessLevel.PRIVATE; +import com.hotels.beans.sample.immutable.ImmutableToSubFoo; -import com.hotels.beans.sample.FromSubFoo; - -import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -32,11 +29,19 @@ */ @Getter @Builder -@AllArgsConstructor(access = PRIVATE) public class MixedToFooWithBuilder { private final String name; private BigInteger id; - private final List nestedObjectList; + private final List nestedObjectList; private final List list; - private final FromSubFoo nestedObject; + private final ImmutableToSubFoo nestedObject; + + public MixedToFooWithBuilder(final String name, final BigInteger id, final List nestedObjectList, + final List list, final ImmutableToSubFoo nestedObject) { + this.name = name; + this.id = id; + this.nestedObjectList = nestedObjectList; + this.list = list; + this.nestedObject = nestedObject; + } } diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java index 4b6933455..57e519a7d 100644 --- a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java +++ b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java @@ -37,6 +37,14 @@ public final class MutableToFooWithBuilder { private MutableToFooWithBuilder() { } + private MutableToFooWithBuilder(final Builder builder) { + this.id = builder.id; + this.name = builder.name; + this.list = builder.list; + this.nestedObjectList = builder.nestedObjectList; + this.nestedObject = builder.nestedObject; + } + public static class Builder { private String name; private BigInteger id; @@ -55,13 +63,7 @@ public Builder withId(final BigInteger id) { } public MutableToFooWithBuilder build() { - MutableToFooWithBuilder mutableToFooWithBuilder = new MutableToFooWithBuilder(); - mutableToFooWithBuilder.id = this.id; - mutableToFooWithBuilder.name = this.name; - mutableToFooWithBuilder.list = this.list; - mutableToFooWithBuilder.nestedObjectList = this.nestedObjectList; - mutableToFooWithBuilder.nestedObject = this.nestedObject; - return mutableToFooWithBuilder; + return new MutableToFooWithBuilder(this); } } } diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java index c5170f814..e8aa0d32a 100644 --- a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java +++ b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java @@ -33,10 +33,18 @@ public final class MutableToFooWithBuilderMultipleConstructor { private List nestedObjectList; private MutableToSubFoo nestedObject; + private MutableToFooWithBuilderMultipleConstructor() { + } + /** * Private constructor. */ - private MutableToFooWithBuilderMultipleConstructor() { + private MutableToFooWithBuilderMultipleConstructor(final Builder builder) { + this.id = builder.id; + this.name = builder.name; + this.list = builder.list; + this.nestedObjectList = builder.nestedObjectList; + this.nestedObject = builder.nestedObject; } static class Builder { @@ -63,14 +71,23 @@ public Builder withId(final BigInteger id) { return this; } + public Builder withList(final List list) { + this.list = list; + return this; + } + + public Builder withNestedObjectList(final List nestedObjectList) { + this.nestedObjectList = nestedObjectList; + return this; + } + + public Builder withNestedObject(final MutableToSubFoo nestedObject) { + this.nestedObject = nestedObject; + return this; + } + public MutableToFooWithBuilderMultipleConstructor build() { - MutableToFooWithBuilderMultipleConstructor builderToFoo = new MutableToFooWithBuilderMultipleConstructor(); - builderToFoo.id = this.id; - builderToFoo.name = this.name; - builderToFoo.list = this.list; - builderToFoo.nestedObjectList = this.nestedObjectList; - builderToFoo.nestedObject = this.nestedObject; - return builderToFoo; + return new MutableToFooWithBuilderMultipleConstructor(this); } } } From a880061e40c3311b0888eeb5f364aa79a5a05c02 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 16:44:32 +0200 Subject: [PATCH 0453/1786] Preparing java 8 release --- CHANGELOG.md | 4 +-- pom.xml | 4 +-- .../mutable/MutableToFooWithBuilder.java | 16 ++++----- ...leToFooWithBuilderMultipleConstructor.java | 33 +++++-------------- 4 files changed, 19 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 467acd99b..7f5855a25 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.2.8] TBD +### [1.3.0] 2019.04.28 #### Added * Added support for the transformation of Java Beans built through Builder @@ -49,7 +49,7 @@ All notable changes to this project will be documented in this file. - Updated Travis configuration in order to work with java 11 - Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created -### [1.1.14] TBD +### [1.1.14] 2019.04.28 #### Added * Added support for the transformation of Java Beans built through Builder diff --git a/pom.xml b/pom.xml index 95412082a..601d763f0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.8-SNAPSHOT + 1.1.14-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 3.11.0 diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java index 57e519a7d..4b6933455 100644 --- a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java +++ b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java @@ -37,14 +37,6 @@ public final class MutableToFooWithBuilder { private MutableToFooWithBuilder() { } - private MutableToFooWithBuilder(final Builder builder) { - this.id = builder.id; - this.name = builder.name; - this.list = builder.list; - this.nestedObjectList = builder.nestedObjectList; - this.nestedObject = builder.nestedObject; - } - public static class Builder { private String name; private BigInteger id; @@ -63,7 +55,13 @@ public Builder withId(final BigInteger id) { } public MutableToFooWithBuilder build() { - return new MutableToFooWithBuilder(this); + MutableToFooWithBuilder mutableToFooWithBuilder = new MutableToFooWithBuilder(); + mutableToFooWithBuilder.id = this.id; + mutableToFooWithBuilder.name = this.name; + mutableToFooWithBuilder.list = this.list; + mutableToFooWithBuilder.nestedObjectList = this.nestedObjectList; + mutableToFooWithBuilder.nestedObject = this.nestedObject; + return mutableToFooWithBuilder; } } } diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java index e8aa0d32a..c5170f814 100644 --- a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java +++ b/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java @@ -33,18 +33,10 @@ public final class MutableToFooWithBuilderMultipleConstructor { private List nestedObjectList; private MutableToSubFoo nestedObject; - private MutableToFooWithBuilderMultipleConstructor() { - } - /** * Private constructor. */ - private MutableToFooWithBuilderMultipleConstructor(final Builder builder) { - this.id = builder.id; - this.name = builder.name; - this.list = builder.list; - this.nestedObjectList = builder.nestedObjectList; - this.nestedObject = builder.nestedObject; + private MutableToFooWithBuilderMultipleConstructor() { } static class Builder { @@ -71,23 +63,14 @@ public Builder withId(final BigInteger id) { return this; } - public Builder withList(final List list) { - this.list = list; - return this; - } - - public Builder withNestedObjectList(final List nestedObjectList) { - this.nestedObjectList = nestedObjectList; - return this; - } - - public Builder withNestedObject(final MutableToSubFoo nestedObject) { - this.nestedObject = nestedObject; - return this; - } - public MutableToFooWithBuilderMultipleConstructor build() { - return new MutableToFooWithBuilderMultipleConstructor(this); + MutableToFooWithBuilderMultipleConstructor builderToFoo = new MutableToFooWithBuilderMultipleConstructor(); + builderToFoo.id = this.id; + builderToFoo.name = this.name; + builderToFoo.list = this.list; + builderToFoo.nestedObjectList = this.nestedObjectList; + builderToFoo.nestedObject = this.nestedObject; + return builderToFoo; } } } From d3cd879ae8cbf4bb65827e73e1660b28d1ff0187 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 16:46:02 +0200 Subject: [PATCH 0454/1786] [maven-release-plugin] prepare release 1.1.14 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 601d763f0..2df01df3e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.14-SNAPSHOT + 1.1.14 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.1.14 From e9eaac1a1d5cc909848b0d423681c61cc1497a9a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 16:46:11 +0200 Subject: [PATCH 0455/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2df01df3e..a31c464de 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.14 + 1.1.15-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.1.14 + HEAD From 38bc27f30e92c351275bebd99084bc6155cc08f6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 16:49:25 +0200 Subject: [PATCH 0456/1786] Preparing java 11 release --- pom.xml | 4 ++-- src/main/java/com/hotels/beans/utils/ClassUtils.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index a31c464de..95412082a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.1.15-SNAPSHOT + 1.2.8-SNAPSHOT jar 2019 @@ -22,7 +22,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 3.11.0 diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index fd0978767..d46b62a8d 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -28,6 +28,7 @@ import static java.util.Objects.isNull; import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; +import static java.util.Set.of; import static java.util.stream.Collectors.toList; import static com.hotels.beans.utils.ValidationUtils.notNull; @@ -51,7 +52,6 @@ import java.time.temporal.Temporal; import java.util.ArrayList; import java.util.Currency; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -76,8 +76,8 @@ public final class ClassUtils { /** * Primitive types list. */ - private static final Set> PRIMITIVE_TYPES = new HashSet<>(asList(String.class, Boolean.class, Integer.class, Long.class, - Double.class, BigDecimal.class, BigInteger.class, Short.class, Float.class, Character.class, Byte.class)); + private static final Set> PRIMITIVE_TYPES = of(String.class, Boolean.class, Integer.class, Long.class, + Double.class, BigDecimal.class, BigInteger.class, Short.class, Float.class, Character.class, Byte.class); /** * Reflection utils instance {@link ReflectionUtils}. From 4441d3a782ed314d432ba258ecf2d2a21d6df392 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 16:58:43 +0200 Subject: [PATCH 0457/1786] preparing java 11 release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 95412082a..f53e7a90c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.2.8-SNAPSHOT + 1.3.0-SNAPSHOT jar 2019 From 9bd899d1b256059bc4b70aa273b42f90435bb1c3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 17:04:04 +0200 Subject: [PATCH 0458/1786] [maven-release-plugin] prepare release 1.3.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f53e7a90c..3275715dc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.3.0-SNAPSHOT + 1.3.0 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.3.0 From 4a191253b64927f8f8d25d2cae76b47b1f3d69ac Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 17:04:12 +0200 Subject: [PATCH 0459/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3275715dc..76c67fa84 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.3.0 + 1.3.1-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.3.0 + HEAD From 7361cde0f2ae5c4c6f01996cdeba7989c1aa83f9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 17:22:52 +0200 Subject: [PATCH 0460/1786] removed hidden builder --- .../sample/immutable/ImmutableToFooWithBuilder.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java index 2086b19e0..9f0e67e56 100644 --- a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java +++ b/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java @@ -28,7 +28,7 @@ * Immutable bean instantiable only through a Builder. */ @Getter -@Builder(builderMethodName = "hiddenBuilder") +@Builder public class ImmutableToFooWithBuilder { private final String name; private final BigInteger id; @@ -44,14 +44,4 @@ public ImmutableToFooWithBuilder(final String name, final BigInteger id, final L this.list = list; this.nestedObject = nestedObject; } - - public static ImmutableToFooWithBuilderBuilder builder(final String name, final BigInteger id, - final List nestedObjectList, final List list, final FromSubFoo nestedObject) { - return hiddenBuilder() - .name(name) - .id(id) - .nestedObjectList(nestedObjectList) - .list(list) - .nestedObject(nestedObject); - } } From 66e9e6f68161a26e62104958133ea3124c620b61 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 17:24:34 +0200 Subject: [PATCH 0461/1786] restored version in order to re trigger deploy --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 76c67fa84..f53e7a90c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.3.1-SNAPSHOT + 1.3.0-SNAPSHOT jar 2019 From c12edeb5ccec56bc321272af37ffb9ca2e6ae92d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 17:25:33 +0200 Subject: [PATCH 0462/1786] [maven-release-plugin] prepare release 1.3.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f53e7a90c..3275715dc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.3.0-SNAPSHOT + 1.3.0 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.3.0 From 1f37f03d863329ba9a754bd778d3d12eb6b5fd35 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 17:25:41 +0200 Subject: [PATCH 0463/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3275715dc..76c67fa84 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.3.0 + 1.3.1-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.3.0 + HEAD From 891c89a2a3ef3ce4a0a6ce8597610e53f6802f2c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 17:29:14 +0200 Subject: [PATCH 0464/1786] reverting --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 76c67fa84..f53e7a90c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.3.1-SNAPSHOT + 1.3.0-SNAPSHOT jar 2019 From 467c46830c5cf53bce3b904f4e6859f847d6a7da Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 17:30:09 +0200 Subject: [PATCH 0465/1786] [maven-release-plugin] prepare release 1.3.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f53e7a90c..3275715dc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.3.0-SNAPSHOT + 1.3.0 jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.3.0 From 0e00f1132f8a50b844c40ec009c302e15be75beb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Apr 2019 17:30:18 +0200 Subject: [PATCH 0466/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3275715dc..76c67fa84 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.3.0 + 1.3.1-SNAPSHOT jar 2019 @@ -57,7 +57,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.3.0 + HEAD From eec6a5f26c44ec6f6f3b9cb7941a73890ba4f022 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 29 Apr 2019 11:04:11 +0200 Subject: [PATCH 0467/1786] getFieldValue function refactoring --- .../beans/transformer/TransformerImpl.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index b0657f613..f9268c91f 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -307,24 +307,29 @@ private Object getFieldValue(final T sourceObj, final Class targetClas */ private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); + Class fieldType = field.getType(); if (doSkipTransformation(fieldBreadcrumb)) { - return defaultValue(field.getType()); + return defaultValue(fieldType); } - boolean primitiveType = classUtils.isPrimitiveType(field.getType()); - boolean isFieldTransformerDefined = settings.getFieldsTransformers().containsKey(field.getName()); + boolean primitiveType = classUtils.isPrimitiveType(fieldType); + Function transformerFunction = getTransformerFunction(field, fieldBreadcrumb); + boolean isFieldTransformerDefined = nonNull(transformerFunction); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function // defined it recursively evaluate the value - boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(field.getType()); - if ((notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass())) - && !isFieldTransformerDefined) { + boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(fieldType); + if (!isFieldTransformerDefined + && (notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass()))) { fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); } } else if (primitiveType) { - fieldValue = defaultValue(field.getType()); // assign the default value + fieldValue = defaultValue(fieldType); // assign the default value } - return getTransformedField(field, fieldBreadcrumb, fieldValue); + if (isFieldTransformerDefined) { + fieldValue = transformerFunction.apply(fieldValue); + } + return fieldValue; } /** @@ -364,16 +369,13 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie } /** - * It executes the lambda function defined to the field. + * Retrieves the transformer function. * @param field The field on which the transformation should be applied. * @param breadcrumb The full field path on which the transformation should be applied. - * @param fieldValue The field value. - * @return the transformed field. + * @return the transformer function. */ - private Object getTransformedField(final Field field, final String breadcrumb, final Object fieldValue) { - String fieldName = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - Function transformerFunction = settings.getFieldsTransformers().get(fieldName); - return nonNull(transformerFunction) ? transformerFunction.apply(fieldValue) : fieldValue; + private Function getTransformerFunction(final Field field, final String breadcrumb) { + return settings.getFieldsTransformers().get(settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb); } /** From fe250b7991e9eb79eee6bd0813f0049bb6007df2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 29 Apr 2019 17:45:30 +0200 Subject: [PATCH 0468/1786] Updated parent pom version --- pom.xml | 2 +- src/main/java/com/hotels/beans/BeanUtils.java | 2 +- .../com/hotels/beans/annotation/ConstructorArg.java | 2 +- .../java/com/hotels/beans/annotation/package-info.java | 2 +- src/main/java/com/hotels/beans/base/Defaults.java | 2 +- src/main/java/com/hotels/beans/base/package-info.java | 2 +- src/main/java/com/hotels/beans/cache/CacheManager.java | 2 +- .../com/hotels/beans/cache/CacheManagerFactory.java | 2 +- src/main/java/com/hotels/beans/cache/package-info.java | 2 +- src/main/java/com/hotels/beans/constant/ClassType.java | 2 +- src/main/java/com/hotels/beans/constant/Filters.java | 2 +- .../java/com/hotels/beans/constant/MethodPrefix.java | 2 +- .../java/com/hotels/beans/constant/Punctuation.java | 2 +- .../java/com/hotels/beans/constant/package-info.java | 2 +- .../hotels/beans/error/InstanceCreationException.java | 2 +- .../com/hotels/beans/error/InvalidBeanException.java | 2 +- .../com/hotels/beans/error/MissingFieldException.java | 2 +- .../com/hotels/beans/error/MissingMethodException.java | 2 +- src/main/java/com/hotels/beans/error/package-info.java | 2 +- src/main/java/com/hotels/beans/model/EmptyValue.java | 2 +- src/main/java/com/hotels/beans/model/FieldMapping.java | 2 +- .../java/com/hotels/beans/model/FieldTransformer.java | 2 +- src/main/java/com/hotels/beans/model/ItemType.java | 2 +- src/main/java/com/hotels/beans/model/MapElemType.java | 2 +- src/main/java/com/hotels/beans/model/MapType.java | 2 +- src/main/java/com/hotels/beans/model/package-info.java | 2 +- src/main/java/com/hotels/beans/package-info.java | 3 ++- .../com/hotels/beans/populator/ArrayPopulator.java | 2 +- .../hotels/beans/populator/CollectionPopulator.java | 2 +- .../hotels/beans/populator/ICollectionPopulator.java | 2 +- .../java/com/hotels/beans/populator/MapPopulator.java | 2 +- .../com/hotels/beans/populator/OptionalPopulator.java | 2 +- .../java/com/hotels/beans/populator/Populator.java | 2 +- .../com/hotels/beans/populator/PopulatorFactory.java | 2 +- .../java/com/hotels/beans/populator/package-info.java | 2 +- .../hotels/beans/transformer/AbstractTransformer.java | 2 +- .../java/com/hotels/beans/transformer/Transformer.java | 2 +- .../com/hotels/beans/transformer/TransformerImpl.java | 10 +++++----- .../hotels/beans/transformer/TransformerSettings.java | 2 +- .../com/hotels/beans/transformer/package-info.java | 2 +- src/main/java/com/hotels/beans/utils/ClassUtils.java | 2 +- .../java/com/hotels/beans/utils/ReflectionUtils.java | 2 +- .../java/com/hotels/beans/utils/ValidationUtils.java | 2 +- src/main/java/com/hotels/beans/utils/package-info.java | 2 +- src/main/resources/logback-test.xml | 2 +- src/main/resources/logback.xml | 2 +- src/test/java/com/hotels/beans/BeanUtilsTest.java | 2 +- src/test/java/com/hotels/beans/base/DefaultsTest.java | 2 +- src/test/java/com/hotels/beans/base/package-info.java | 2 +- .../hotels/beans/cache/CacheManagerFactoryTest.java | 2 +- .../java/com/hotels/beans/cache/CacheManagerTest.java | 2 +- src/test/java/com/hotels/beans/cache/package-info.java | 2 +- src/test/java/com/hotels/beans/package-info.java | 3 ++- .../com/hotels/beans/performance/PerformanceTest.java | 2 +- .../com/hotels/beans/performance/package-info.java | 2 +- .../com/hotels/beans/populator/ArrayPopulatorTest.java | 2 +- .../hotels/beans/populator/PopulatorFactoryTest.java | 2 +- .../java/com/hotels/beans/populator/package-info.java | 2 +- src/test/java/com/hotels/beans/sample/FromFoo.java | 2 +- .../java/com/hotels/beans/sample/FromFooAdvFields.java | 2 +- src/test/java/com/hotels/beans/sample/FromFooMap.java | 2 +- .../java/com/hotels/beans/sample/FromFooSimple.java | 2 +- .../hotels/beans/sample/FromFooSimpleNoGetters.java | 2 +- .../java/com/hotels/beans/sample/FromFooSubClass.java | 2 +- .../beans/sample/FromFooWithPrimitiveFields.java | 2 +- src/test/java/com/hotels/beans/sample/FromSubFoo.java | 2 +- .../beans/sample/immutable/ImmutableFlatToFoo.java | 2 +- .../hotels/beans/sample/immutable/ImmutableToFoo.java | 2 +- .../sample/immutable/ImmutableToFooAdvFields.java | 2 +- .../immutable/ImmutableToFooCustomAnnotation.java | 2 +- .../sample/immutable/ImmutableToFooDiffFields.java | 2 +- .../beans/sample/immutable/ImmutableToFooInvalid.java | 2 +- .../beans/sample/immutable/ImmutableToFooMap.java | 2 +- .../ImmutableToFooMissingCustomAnnotation.java | 2 +- .../sample/immutable/ImmutableToFooNoConstructors.java | 2 +- .../immutable/ImmutableToFooNotExistingFields.java | 2 +- .../beans/sample/immutable/ImmutableToFooSimple.java | 2 +- .../immutable/ImmutableToFooSimpleWrongTypes.java | 2 +- .../beans/sample/immutable/ImmutableToFooSubClass.java | 2 +- .../sample/immutable/ImmutableToFooWithBuilder.java | 2 +- .../beans/sample/immutable/ImmutableToSubFoo.java | 2 +- .../immutable/ImmutableToSubFooCustomAnnotation.java | 2 +- .../hotels/beans/sample/immutable/package-info.java | 2 +- .../java/com/hotels/beans/sample/mixed/MixedToFoo.java | 2 +- .../beans/sample/mixed/MixedToFooDiffFields.java | 2 +- .../mixed/MixedToFooMissingAllArgsConstructor.java | 2 +- .../sample/mixed/MixedToFooMissingConstructor.java | 2 +- .../beans/sample/mixed/MixedToFooMissingField.java | 2 +- .../sample/mixed/MixedToFooNotExistingFields.java | 2 +- .../beans/sample/mixed/MixedToFooStaticField.java | 2 +- .../beans/sample/mixed/MixedToFooWithBuilder.java | 2 +- .../com/hotels/beans/sample/mixed/package-info.java | 2 +- .../com/hotels/beans/sample/mutable/MutableToFoo.java | 2 +- .../beans/sample/mutable/MutableToFooAdvFields.java | 2 +- .../beans/sample/mutable/MutableToFooInvalid.java | 2 +- .../sample/mutable/MutableToFooNotExistingFields.java | 2 +- .../beans/sample/mutable/MutableToFooSimple.java | 2 +- .../sample/mutable/MutableToFooSimpleNoSetters.java | 2 +- .../beans/sample/mutable/MutableToFooSubClass.java | 2 +- .../beans/sample/mutable/MutableToFooWithBuilder.java | 2 +- .../MutableToFooWithBuilderMultipleConstructor.java | 2 +- .../hotels/beans/sample/mutable/MutableToSubFoo.java | 2 +- .../com/hotels/beans/sample/mutable/package-info.java | 2 +- .../java/com/hotels/beans/sample/package-info.java | 2 +- .../beans/transformer/AbstractTransformerTest.java | 2 +- .../transformer/BuilderObjectTransformationTest.java | 2 +- .../transformer/ImmutableObjectTransformationTest.java | 2 +- .../transformer/MixedObjectTransformationTest.java | 2 +- .../transformer/MutableObjectTransformationTest.java | 2 +- .../com/hotels/beans/transformer/TransformerTest.java | 2 +- .../com/hotels/beans/transformer/package-info.java | 2 +- .../java/com/hotels/beans/utils/ClassUtilsTest.java | 2 +- .../com/hotels/beans/utils/ReflectionUtilsTest.java | 2 +- .../com/hotels/beans/utils/ValidationUtilsTest.java | 2 +- src/test/java/com/hotels/beans/utils/package-info.java | 2 +- 115 files changed, 121 insertions(+), 119 deletions(-) diff --git a/pom.xml b/pom.xml index 76c67fa84..dab40dd7c 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.hotels hotels-oss-parent - 4.0.0 + 4.0.1 diff --git a/src/main/java/com/hotels/beans/BeanUtils.java b/src/main/java/com/hotels/beans/BeanUtils.java index cf939b654..da655d5c1 100644 --- a/src/main/java/com/hotels/beans/BeanUtils.java +++ b/src/main/java/com/hotels/beans/BeanUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/annotation/ConstructorArg.java b/src/main/java/com/hotels/beans/annotation/ConstructorArg.java index 1408293ba..5fda73ba1 100644 --- a/src/main/java/com/hotels/beans/annotation/ConstructorArg.java +++ b/src/main/java/com/hotels/beans/annotation/ConstructorArg.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/annotation/package-info.java b/src/main/java/com/hotels/beans/annotation/package-info.java index 000c0df8a..4710319a7 100644 --- a/src/main/java/com/hotels/beans/annotation/package-info.java +++ b/src/main/java/com/hotels/beans/annotation/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/base/Defaults.java b/src/main/java/com/hotels/beans/base/Defaults.java index feb773b18..62b5c96fe 100644 --- a/src/main/java/com/hotels/beans/base/Defaults.java +++ b/src/main/java/com/hotels/beans/base/Defaults.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/base/package-info.java b/src/main/java/com/hotels/beans/base/package-info.java index 3cd1ac121..aacbb7e4f 100644 --- a/src/main/java/com/hotels/beans/base/package-info.java +++ b/src/main/java/com/hotels/beans/base/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/src/main/java/com/hotels/beans/cache/CacheManager.java index a59846a29..e17e53529 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java b/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java index 6e511723b..bd11761f2 100644 --- a/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java +++ b/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/cache/package-info.java b/src/main/java/com/hotels/beans/cache/package-info.java index 40f771047..d9e881424 100644 --- a/src/main/java/com/hotels/beans/cache/package-info.java +++ b/src/main/java/com/hotels/beans/cache/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/constant/ClassType.java b/src/main/java/com/hotels/beans/constant/ClassType.java index 6c5af701f..0560eb236 100644 --- a/src/main/java/com/hotels/beans/constant/ClassType.java +++ b/src/main/java/com/hotels/beans/constant/ClassType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/constant/Filters.java b/src/main/java/com/hotels/beans/constant/Filters.java index b1d1de247..f13ab1e2e 100644 --- a/src/main/java/com/hotels/beans/constant/Filters.java +++ b/src/main/java/com/hotels/beans/constant/Filters.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/constant/MethodPrefix.java b/src/main/java/com/hotels/beans/constant/MethodPrefix.java index a2217351a..6609fb8e5 100644 --- a/src/main/java/com/hotels/beans/constant/MethodPrefix.java +++ b/src/main/java/com/hotels/beans/constant/MethodPrefix.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/constant/Punctuation.java b/src/main/java/com/hotels/beans/constant/Punctuation.java index 998547a7e..4eb27ef58 100644 --- a/src/main/java/com/hotels/beans/constant/Punctuation.java +++ b/src/main/java/com/hotels/beans/constant/Punctuation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/constant/package-info.java b/src/main/java/com/hotels/beans/constant/package-info.java index 667c40cda..18642252b 100644 --- a/src/main/java/com/hotels/beans/constant/package-info.java +++ b/src/main/java/com/hotels/beans/constant/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/error/InstanceCreationException.java b/src/main/java/com/hotels/beans/error/InstanceCreationException.java index 4a6fad4ea..1807607aa 100644 --- a/src/main/java/com/hotels/beans/error/InstanceCreationException.java +++ b/src/main/java/com/hotels/beans/error/InstanceCreationException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/error/InvalidBeanException.java b/src/main/java/com/hotels/beans/error/InvalidBeanException.java index ceae328d5..4010cd077 100644 --- a/src/main/java/com/hotels/beans/error/InvalidBeanException.java +++ b/src/main/java/com/hotels/beans/error/InvalidBeanException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/error/MissingFieldException.java b/src/main/java/com/hotels/beans/error/MissingFieldException.java index 4e9e1b661..61701a394 100644 --- a/src/main/java/com/hotels/beans/error/MissingFieldException.java +++ b/src/main/java/com/hotels/beans/error/MissingFieldException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/error/MissingMethodException.java b/src/main/java/com/hotels/beans/error/MissingMethodException.java index ce84a8252..27b03f165 100644 --- a/src/main/java/com/hotels/beans/error/MissingMethodException.java +++ b/src/main/java/com/hotels/beans/error/MissingMethodException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/error/package-info.java b/src/main/java/com/hotels/beans/error/package-info.java index 120a95417..e11154bf2 100644 --- a/src/main/java/com/hotels/beans/error/package-info.java +++ b/src/main/java/com/hotels/beans/error/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/model/EmptyValue.java b/src/main/java/com/hotels/beans/model/EmptyValue.java index 4725bd855..d75442e74 100644 --- a/src/main/java/com/hotels/beans/model/EmptyValue.java +++ b/src/main/java/com/hotels/beans/model/EmptyValue.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/model/FieldMapping.java b/src/main/java/com/hotels/beans/model/FieldMapping.java index a4ae8c3ab..fa17b8d8c 100644 --- a/src/main/java/com/hotels/beans/model/FieldMapping.java +++ b/src/main/java/com/hotels/beans/model/FieldMapping.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/model/FieldTransformer.java b/src/main/java/com/hotels/beans/model/FieldTransformer.java index aee716b68..4ed6f4383 100644 --- a/src/main/java/com/hotels/beans/model/FieldTransformer.java +++ b/src/main/java/com/hotels/beans/model/FieldTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/model/ItemType.java b/src/main/java/com/hotels/beans/model/ItemType.java index 2220731ee..f24de56b5 100644 --- a/src/main/java/com/hotels/beans/model/ItemType.java +++ b/src/main/java/com/hotels/beans/model/ItemType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/model/MapElemType.java b/src/main/java/com/hotels/beans/model/MapElemType.java index fdc792b21..431c4b7c0 100644 --- a/src/main/java/com/hotels/beans/model/MapElemType.java +++ b/src/main/java/com/hotels/beans/model/MapElemType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/model/MapType.java b/src/main/java/com/hotels/beans/model/MapType.java index 9fd894ac7..18e241e98 100644 --- a/src/main/java/com/hotels/beans/model/MapType.java +++ b/src/main/java/com/hotels/beans/model/MapType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/model/package-info.java b/src/main/java/com/hotels/beans/model/package-info.java index d8822ad9c..610dabb69 100644 --- a/src/main/java/com/hotels/beans/model/package-info.java +++ b/src/main/java/com/hotels/beans/model/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/package-info.java b/src/main/java/com/hotels/beans/package-info.java index 3fbb5a4ce..99cdebc36 100644 --- a/src/main/java/com/hotels/beans/package-info.java +++ b/src/main/java/com/hotels/beans/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,4 +16,5 @@ /** * Main package. */ + package com.hotels.beans; diff --git a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index 5814c78a8..b74045d15 100644 --- a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index ea8e50b11..6a1b85e13 100644 --- a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java index 8bd1ca44b..b4415f1df 100644 --- a/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java +++ b/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/populator/MapPopulator.java b/src/main/java/com/hotels/beans/populator/MapPopulator.java index ea45ea26a..02bb81705 100644 --- a/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index cb8636e58..0566ded11 100644 --- a/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/populator/Populator.java b/src/main/java/com/hotels/beans/populator/Populator.java index a0eee190b..c7a9c883f 100644 --- a/src/main/java/com/hotels/beans/populator/Populator.java +++ b/src/main/java/com/hotels/beans/populator/Populator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/src/main/java/com/hotels/beans/populator/PopulatorFactory.java index 5e53f1a3f..721006d24 100644 --- a/src/main/java/com/hotels/beans/populator/PopulatorFactory.java +++ b/src/main/java/com/hotels/beans/populator/PopulatorFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/populator/package-info.java b/src/main/java/com/hotels/beans/populator/package-info.java index f388b9779..a2e61961d 100644 --- a/src/main/java/com/hotels/beans/populator/package-info.java +++ b/src/main/java/com/hotels/beans/populator/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 59f01d89c..53601be91 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index f70896227..10a727e92 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index f9268c91f..a188f3cfa 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -313,20 +313,20 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN } boolean primitiveType = classUtils.isPrimitiveType(fieldType); Function transformerFunction = getTransformerFunction(field, fieldBreadcrumb); - boolean isFieldTransformerDefined = nonNull(transformerFunction); - Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isFieldTransformerDefined); + boolean isTransformerFunctionDefined = nonNull(transformerFunction); + Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function // defined it recursively evaluate the value boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(fieldType); - if (!isFieldTransformerDefined + if (!isTransformerFunctionDefined && (notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass()))) { fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); } } else if (primitiveType) { fieldValue = defaultValue(fieldType); // assign the default value } - if (isFieldTransformerDefined) { + if (isTransformerFunctionDefined) { fieldValue = transformerFunction.apply(fieldValue); } return fieldValue; diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 6aaf7c82d..aabe88878 100644 --- a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/transformer/package-info.java b/src/main/java/com/hotels/beans/transformer/package-info.java index 9100b3f26..79093745c 100644 --- a/src/main/java/com/hotels/beans/transformer/package-info.java +++ b/src/main/java/com/hotels/beans/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index d46b62a8d..fd7699150 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 261669ef7..9194fe598 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/utils/ValidationUtils.java b/src/main/java/com/hotels/beans/utils/ValidationUtils.java index e1d2cb72d..9e34599bd 100644 --- a/src/main/java/com/hotels/beans/utils/ValidationUtils.java +++ b/src/main/java/com/hotels/beans/utils/ValidationUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/java/com/hotels/beans/utils/package-info.java b/src/main/java/com/hotels/beans/utils/package-info.java index eb3622d9f..dc86d83d5 100644 --- a/src/main/java/com/hotels/beans/utils/package-info.java +++ b/src/main/java/com/hotels/beans/utils/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia Inc. + * Copyright (C) 2019 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/main/resources/logback-test.xml b/src/main/resources/logback-test.xml index 55cadbe71..4da7aad36 100644 --- a/src/main/resources/logback-test.xml +++ b/src/main/resources/logback-test.xml @@ -1,5 +1,5 @@ 89OzFyiS-2s#UQnJh2W1~J?P6^lAi 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�i|Zuv0PJyAuzVcZ4DD!5^r~+^AGI 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
      BcYAl?&o+bFAiTS} z1$D3kUUs4VeyMX!g5%KQmjut^Gg_%%JtXvbdNJV0%!Stwy|q4^2F;yq?6e$hG@LHa zkawS;>)#LUJwcOkpAHK@9d#)b=FUy6?biNh$D98G1>TjEqy0Z+15E>Ub{ASTZ%%LH38$JBl8YUx&PH?Ky}OXP3v0 zp({Qbqj*Sj9Vk7w)XvHk;FvdbuBpxpg{-xS7X*y=!1FhfapyIXqff*lKjURJFRJlc zy#uyvO+J59v^ic zBz&0<6?71r!31{CFVZp60QMIE@~;^5zI%L#WBa5j<2n^Mvu=RjZNzq!2aCF+Zrt~F zvrLYg`=ru-RZtS5zjTcwUROWWobfcEg>&)k!}?2cS(ci*)EQFZ(Kp66gNg~6bdJ#? zIhS6@c~vHNtRDJ$rCxVGskfDHX;N$Zh3CL&SyCby1TaNF$s`LQmCm)#_% zrx~CSbOf)$~taUy~^l;9gz9oJYBG$2gVN_AVH?lShD`g+o5WKb8B~DUG1+ z3wj~LdXFwYJJ*b}zhzNpZ|yx(*7uLrPi0p*n%%_fe`11VkPQGL?>^wjx>-J5Ut*EN zif5Os-CmzBu%^l0P9yQZ?=Mx(kHlG!MLh{R7d)%_T2WL>2%+lvI>`{ zBE9N?RN8I8dzx9J*7d-4APO2F-F!OhBq$)rBjf9@8h@&7lF?_@_^k&a3y4_;y<;*c zVXoz>P%^;4Kgbb94gk3av<&hVT|w}~lLb_@jbc*Ie&+C`bqbM!ThXA|=65kH@#)zd zy)0MwOy;OC=83m8h%gaS3(Ii@qF4lf4cGg)Sc=WG| z+sVN*=r!$+)(%-?I&SRhS^Q8L7@R*_>=*w+<5A-ZE*7X9W;|BqAvSWX)0%==I zO=U=KC^X+dDYY^K7MT$yo(3_?!-#*yins#D3Z%&V91png>=9pGtnms5TPJ-pnQ zl7ZGidLE{7Tz3J|paUJ4I0XrBa#twX#(){2`+S&!Wam}*vW>(s zpkgeb+yp<8(k$ik{GJ}!h!yNe^HTzIALv)(o@SaTak4QB%GB-#MhSu+#(LD}UKX5;>tP0gg2$S~o z;{Ey8v_5H=p5VdzUZhgwamc4|uXKd!K+ z4N;wr3e~HpYdHKo4(DBEjDW`hEAs2+^k2+$x1o? z%`2Jm80_|!H+om9ahE?b4uzPd-^lAVSNUvNJHPP(X30p-aZ%-HA}iVcoHjrmzodB zV}htL$*nYqn~|SVa$a3SU(KI=kfc~2u%0g;+&?w;yEl@7hnA}L6O8kXBMH};pni2u z&ThoQ3eTVDfeIZj>^P_U-x7$H-sA^d#H%c}Q))X*D0 zfYUrNSedDtdY$XgXeu`qyWHsZUa7=0yp;7oN0;ai2Df#@a^MmYNO_dqRUZtD2+fyT z`Cdcpt{E&)5VB_;yke&O)vjSxczyD;Pl~x|V15|k&$(IdLzm@SczGVJp zHgAfcZH1diR&UE+Y00J9R(8ruc6W|n3z&RZ)r77AKzFs&H{t0NPtjtQX(wqtZX4R- z>mC@L*{I|y`3T!rioEZ6xCG z_l{YVH7lb$8!gAZz^?q2+ZV+`fO?4w+_(RCZkPb)hI{j}*kYJRUw7)kf9J;R&(qC@ zakn#G?EmxJvzI|E94F&?pn%arQRo1udE!yVRUj_y!04SCq0ZjMaoYRB<~YT<(VK+5 z>Pgc3u}ctxOri-jij-5rX})^kT~V5Z(oHi39#2GuTPw( z@a#QGvQiy4i-6c_l_)c4%%whZK}$Z35Va&ym*g9pCm@)>McRY5Q%|AY?TJG%IG8(K z(gw^Z%?`|{Bo>i55V5W zoX{hW8Z$@{^Jj=8#N{=v)`gYX*POduDa_0=xrmF_7{I~#>m>K(-uqYNd5%EC4*K!o z%jT)LRq*sM*q7wL&FG)*HOH#Uc{#87REZQw3b5Tm-9o0L^Z8=6VFj17jGo8a;x=zvY2V~XxanxW4UhsHeK+02kk@2Xf7<82_(pOXDAEjbhjJG$6h zQ-$Hp)jfM~nS9Bi7!D=A*_gPuI;dqsvQk3{v!lq`r=X z{f~1QOY;1<6+e?!8`5fEj3(kkU0U^}v03!P!bsbn-el#6>PCsJSqod`$HUg5@g5~$ zr^4%bt0TPqj;O}WAep`eN0>{L-76Q7!H6dtdxOjZ~;p<0J6(zGuu50R1>;1VwJ5Z38?aZ^cez(K}iC* z1Vq(|PQ~F$ad56K;tno`c9fD8$6<9#A%ctbOYuI)*1q$0T zRk!KiIvALGT|r43$scKuhSnq=SY-u{W}J&e$wpnF`hLLgYS;DqbBf+*fZ_)Xsnyx0EX4t7`M17RJ8Fcbr8z<9=#tEG-IDjh6X3&YFH;T7#HaKzfguHNp^#W; zDkNjsf$UU&hnM~^hx%1E%n`jPltPM+$=MHfB-U;@<>^M};*B+7hk8m<&iLWelC?{W zWFbx6tnj&Ha)ArYjNg22u<(Va4d9NJM?NwH?VZbw=+lqj2s6{A-Z{{ z09O;(>2`3%IT(Oczr0tpiV@>>J8^Qb2f&8BOl7K5`t1B^v8L{)=`LaKt)tmz>SVM| zs6ylE{+@pYQq7K2kn@Urw$CJB0pAN*lsQ9Q)zDoI^#Qd{9+Zm)FRZ)Ekp5T))eZ@I zz&UzlNcJS%JQH1URv)>fnEb_Xs*JDTa*HqTZ*9ASIN_k?#-L{fz6Qzppn&g6>VJ*o zt8Zvl6tIHL#el0UzzR-uraujB`iwgCvcM(#yEJ?03(pQ5U-I90MguzMdzqCfB;|w7 zQRKhpx*nkAk>_nW1F5FUA!QfY=u(byUx!f2f2ibC7ho9?ZW6_c5I{mVTszsVDJH+L zhMs~BPJ@17PcNtH?NEfaqzfuy2%EFUOBB=6@Ni9h{Fj=jED%f42JF~3OGxjtD!!Mk zENYcVbENx;Js`Q_akfHGvQPXUf90z{bZ39AK_4RH^D$3Mlz@$?`u5W=G+)x}(Fn>^ z9`?4TD2>9DSi&tUq zo=078=zIRU09tCJUbW1AIpUH|V_+QrJs0=R&e-|JY2mwHz#1JP=Ee-53Q1oo-=jHn zU3V2kQ-HnR$V&Fxf`CCp10S#^_9EHQa}M}-<<8$#P+F(Yy8{r3^3uQyT?>dyj~$z# z6xo=Q8wF+}W=t_|0073E{r$uMShEY+;g%NdICJAC8q5)8J9(X{aI%I*)4nJ$<&$K> zJcBhN{BTQR_F*o7>pBUaN^%vp)vN>%3Sv8qQn&k&-&;iG3fG&o|EykghZLK_6%3VEmlSdN{mOB|O$S^Te}btHuk8wx{Tab; z@!P`HmJC`0@(0(R$>2Zfx&!R!9D!!yg!NoaWhzA={K263j&#JbmGl%Vrnrhb0kt4{S;SN#3?7uh{E#E8YCI495$Rc-A8~&h4`+HSV-GXRw?`94 z^LZ>@zMSh&OEXM^#ePpH9&5z&V?u#wkx*a6y!D|Mcb~b4xrB;1eTn`N<WSHD0g^Y7M&K3?oFC5dO7B%aigg<$FVPyA@ z4`VW`xCkD^g>`B=*XD>Mv71lq! zPH%OAt3n_hd3dGtqe}Y6)`OJadtifX%@)c+r-XY-MWL_k_cEFD<^>`-N__X8Eryx# zpoO{FTH-X80=E3J-X`kFinlWJakk$KN|;#+(~>&5HGZ8VyC6yH79U8cf|gxlYi4L= zqP#V8nR54if~8~2R5>#9TkMv0qD*$GU%m78B-ueUl>jgbQ^u-iu%UmFtnW~rsV>wY z=Ni@i*e?$>9$dWmMnNYj`(~D%ya?X7zDzo^^70jAJkkKvsidxd>w+yGtBc~m^J0R4 z8`jR-#9RhFcqE@CYkD&oc*+**5+^BqdCW@#9{bE?+VQ{VWH&LQ`cEZ(w5(_;Rsgt4W6>#)MJ5d6VtjpDw8Q)OD&RR+rJujQR$C0s>#Rp@NTjX&cs zVJ1i6xxFJl5g8PZV&`pEHH_w0(;Lm8Gpk(+uHoc6S3_JXtc8tc@sP@V<2VAiE;C3K z0u6B{;P8&Blf5&fG^$hiI|u$$$}hfQe%j-Yv-qYXC*0zjLsUlbKM^6Ys&@Z%Q{hv9 z0T)04jtKE)3Sd<@eQEjwS9$d@kl+=Qzsl`nDkLonp$s^--YI=YyGyE^2OeWNUon^G zkrZbKF>dktD&163vZHC$YgV}s&N!RKD2`5HfvyRwDuoMBkg@oy3Sf&WOq(QKFpd)o zb$VUN+vi+qMNog!zB!p+Li}aG4i0&-%>X*qbNl^NYIG_Q;>xKMh~Wd-=#!fS7s{Qx z>ZSBv3B3c%Wq^}2Pgvoh z<(!jyOg&RI6@5WZ>{)#zbV>#zk0A6BtMk-8;Jp2O1CFT2rzAYC~P{(iTrzo zEicTe;u2MMoB%E1=mFv(*k609*Kgxezi8k68f#&x6^=+cv_&GSk5!?52O6qrSj>t2 z9%gUr$>RCX?|kCUF3&dM;W(@S^GllPC2kQb!K@z$ZJj8rj$xNB0bBhO%&NVz!+2~K z(8#4b9(Q{A-*dJc>+~kF8nsMfDt1gb?9psTA2tQo#BXc+clg(EJ&h-!N-kwTW;xeP z4g&I=JLJ^{zR*@C9iYm;zaKKlrkeN|=#NApDZZctf6=0K@f|>!V+A4H2Awz3iM$YT zo$(3>8N*g7))q5_8O$WIUYF}%1I4?k%YlVSBht?77j90DS$q)b9JazrY`G9h0pOG- zneqJwuoyq@^tJ+Ua3D5u`Q&FH0E7~H%HDw0&7kF%kY>H%m94lFfXQL+51BkbT>KE+ z5s*IF(8l^$0t17D;ab-^#Ye_z*3R$>1+y?s2 z&r9E2e) z*K{Z@rEa5oYL@V7yzXlQ7EtzW_6*S^pH_(sTV3vrNM4pXF=8%Xap$(uj(7liT#D&s zZvLxaAMg~jy=4l(z=inSnm8cI-J(nAe=GdMeMkS^FGNp^xEL`5mE1uY@XZ1lnWW*m z&q&mOW(_IeJ62-LKT>V=8Aha0zarivndx_Tkv`oLyg({0P&MpHeL^?O$VE+2efF%x(3 zHT&MMKdj7G_BuW#+f+Qvkq*b*)J-U+_g5(jrBGmc)0V~zmFfHqh)9-SC{U)_JKo1A z17{;3V$ny2MUZ#uf~_Z=G#DWh7@8vqmQKl0dONP^@K9)UH*QTE|6a87IJ=A1|R+c&dw zs6bz)Fu>0-!{?k(|87L3szW7t_p%${^?_uN9nd>nm-l!Xg$ zkaDTgEQ@AS41sQ(9hx2z6ew2ba1(0-G2BSPzg%x(cYDCm6oDyitmLKDC>@g57hplv zXQb|QbqHh^zy+Y}W08SG0jT2e@1@XcYa73ztkcr}| z7Vgy)_4E7~^JM@V*t92D)A)H(l&5x;$Njw3ZvczIl8)#_o3QhA4y@p|2Y*zHC4N?U+!p8WaWjulc@_Z%QfVdv- z20?nM1GTdjycY9M1=LkwpYXDGB&~89DnNigtiSNO|NDziT64PplO0+CGdtjjInPSj zO*+;>*{~IQ-)VXaF?kYE32YvwbtX!QO|mRov}-K4=0-5bgpsx|ARU4q33(Mf(-?9F zYM9)+-ZH7%Ca)-mt@)+1{zd!xkZFOMusX+?;9@jHaa^w_S=CUiUJV0ah#D9LG(*ty zhKT!1{}CGHq>qQ;1;o8tvTP=YNUW7!bF$_YbK6e@UzfoMm>o-}Uay!R^~`-23%Z0zn>W4*V|@9v?di>Jlt&o=xKO z?hRv_R0h9t$`KWR{H7b#?Uscg!`|OakNeInSgACR{9GW>B`J!H5KQZt==Ej0W!?q~ zb&#l5$&7(DhITXX&=s=&0f0zwhsD9LWbL-jhgzcM+T=8{QB*u(xB2*HSh@I#Bxlv* zv=n_|8+Z?z$_CFY$#I`@a-6ufD>DC{OGp1Su1-GSx785sUB05(X{MEaa_jZH$By(n za#`uC?H2ulf`u01g-%Dy>ZR95RVU=N+_y9u^Dh0)f>W?F}sdp*$<;!3{MB+bKKtV)( z7)wheM-m{4n-~zdt@KK|>CbibvvIxTFv;$Pg}(eZgzAJ>hYM2UG-qN`uk%o3Oqr-A z8OX-Y3Fwvzh$EDYd5v4K=C|j^p0Ek24I96XEyQ)Jb!)DS9LU!<`^BjX%5R$ z=`&IsL)jc_pN#;$eL*aR#3jwsGW10*X=Nkh#Ic6E+*i)qX~TZmV+_Df#E?^7oY?Lw zdfk%Tl%DwVlsBCkWMriqXN`WQKOJ{!3+b4S6Osg=Bbxg+W`27*Gq(NpP65JVZt~E` zPTb^8PGd^LkSb6jn-{Y7_4^a;NauQF4a6`20xnY){wXiaIdl7F9@sz33YO*7PiP(v z?Q3>YaQ&vx**{|X01gxp8+3b*B6b;i=>C@}Mo*7H=z)&H-Yl8JNQPN}!hFN=A(H)1 zEkJWgIXmxtBEa>HVh5SeBH#?Y*_l`j_A}SJQ@AR$AuPU&M0#KCwt4U4d*XI+{+Gdr z5pVG2Z`?9}<+MKv03YCAeEM8rQmLJ9GbEEgCg?E7#25ONyz9E?77uW~*wd=U05Qk-9L6+4%T352?4qe)l@uO5>WqQTi9b*Q?(tJE+sCWSuXTaj_-UW@+r$TwN@SQ zUn^{OJf3e_2JN`GbWl>s&1%QN4@Jv5uci}HE7Ovr#Oj||@uYBKNkEDx?eFM89a=#9 zjcej!m7Xd??61s}p0#E%wi`q{3oI5w)yaf|284{oBe(7Wa$LR9s03b&=pguVH2{Vj zo=IkgI1bmx5MjuYI8!h96K5j0IdJ1feUSCo;y;lt)x@D&(duE%s@;n+*P60&&X^0{lMZ(qt8NU3^*33IvXod zROe};!;f;)kq#jlk;wK_pV1tBjVZzbVF+b?UHoAjsPW@#HX^BtgC)?7P|8dq3ggRs zXVKdtZ?vAW+QpBvh-K#bJWfz&W4eA8Fh=H?v`7aYU9p-&pDkjhS8MWv$v^- z&4&Gzw87VKoBL<22iCe(?Cu5ri}gSyUG&?EgXzM69m(AibVHq?o@e=XlaUGK?rA#eE$i`P1+ zC{=nVW1~Z;QVe9&5tOQg-Xb7f1Ozl_OlD}IGfHpCk3kF&dQ}7hNgyLtx*$S|pfpJ= zaVsHn_MAWB+?*@9@$r$}zH6<|dS4F}sT9gWjfb3;Yo%e8h?#qcN3Kq`O!CNjX_{4B zIVgZAIuRJJI?!YMgp^EY5@9yxC(OW1p>&Zlr|LZGo+sr0wk7XB1z!Hvdw{n&=JyeK z(o|9&g`k(~fp2NF5XcIM5e2@CD1(}CRaDGyFS=aF2bF)3OUMVIIr*xn7Q2O0{j+>9 zh$XeXsxiO2XVw&az5n?};VBFIO12Uu!PwE1sYO%@d>*P;j<&=V`p?!-zj8~T-zqGB zKU$qlvpcLT)#O=G?N(Ro92t+OMVOH6{ie#R96y1euF1%YTWr`G$VhNAxn?^v4qnSg zdY)bBqLPY9-@fmN?~6u)Z)9tZjN3sr*d!76WW=PR9g^5CB537#co;U-C!YciJLosk z1#8#2cTzZl??d0!WoKY6kB*TVE2W(Tq?I zoT`KtVtU)C14aXikv_H^oasJoM$e2d6{8k|D<|W=s(B95ug>aCrFQAdTpf4~@A%aD zR{Q2c|ARM`(RyPtKFw#0sJ^Mwzb#hYR4??ZM$4)f$OQw{oV2bixuLY-wV&}GDQ++Yc9-2_FE-vE;yNa zoJ`dLb5@tl$V*6G5EnXq z=)d`n1Fto?_!99de081ovRz2irS9&M?+Xhotr!DoPjGl_JUn$&J5Vz}hnZI_@0{B9 zxZb`<`SGxovqW#bZJM%~Tma^QTLhxSRD0<67QwujwVnei3l-o(LNvbf3OuMvV%0Yo z5=awh&f6b!jyLAIeg@ak{Dv=4D`Dy6q%_b9VpK1Lk4&u;qn z5EXhf0DbE<`a)b-eZ+U=W7%9Q_U{EF%K_Qe>20Jp6SZF3#XRGst=^)Jx1HvT*L11w z^(kK8QtDwk6A_5&ay`@ai=l4X?v%w^JIGF@%?tY~^s!@IR;c`_NK4}(plZhy|i0le>eH!WZceUk6yla7LI8W!#qlaV< z{l5cL3F|ju{|UDH_fU&?*uRJD6YLK?`1g>){uw_f9Zf1}H)!%LUAbi!4sO{wmoQbHq0E{*nV$s|P(_&%!o`;b8lQ;_ zP*&HQ>4J-0BQ0g_6a>u1be4tqzV-f}KPM4Hv;{-cBqG~KO#-wjp%DlIc=V=%pku0# zJ<&KB>pS$tlR65U+p6=-(XlGjrKr82u8)7#SXX?A5gm8I zu($m=Mw)Lv@n!GG^O532>WX#g#ws+fL=lx;7!;4zkQAo=5S&T*yn-{HK#T;{AcP-t z&qK9{ct)I8&J}y(;V{JyBptIGRc(orl23!GXUWhQ6S)n*Z7;+aHYg}=ru`69XB!70rlJ{kz* zuz61x2F{>;ICfxxsd>g)xlDu=YNA9LoGYO-RAjDA?Frq z1OHaDu}CPd|U`yJj&&XZ~ukC zh3WI85d9xBHX|BcMlD0YG)>9lK07RZj`QP_P?ia-xhGl4T$(E{WK2MOkdKf;rJQRriA;pFGWKyj<*ggCW}{2cL6RA2oqlGjmXt641Qo$;ELF zI+W)PQ5RkrS5AaYQ$10Qm#JU_ONZLXOTUpiZr#K5q)jcC+yJ;>ryXBggIRbTxhDP} zah|}r4wc2c4mi#Aq#|?WvBwjkOYw9JSHU(aen$2OVhT7=&J zbDObxOhhp<>57d|jopQ!uq&YULTc*6H}uqrjBZVtiWlrvxNlL8bq*pOZ)NdghUB1>o;7B1L9PN(xP8kKx=^oY;9nfFl+*fUXRuND z=WZb@&b1aHgvdi*BxX|QuBY1xnp|084QOizDf=QTFC8yco1^p91*{KNs7A~$s8>^R z`9(U=_LTsk|EJ~EX7 znqd!^d?lX%R4ACU^TYH^ z+KnNX6sYJ|fHS9xZeJp0H4VPGZFds(j`5MPYJ=C!JX1Q)^8$6EWKsOW znA|y4vTm9fw!5})ZY4tL5jhBe_r8yz({=B7`M_rZ#=?n=*B->RXEMN*f)KU6@HU*mrgZ&73(D; z7b_b%Gt7vSjU0pIjkPaxhQMf!;p)OO6}876!_&h7%CfOZ=5jY#KPZ`mP7HANYsU4gauI?M!KbKx6S3`OM?E_@qXlSe__dx1|@^y@<$vUF%!G-#uE z5O4&zQMo>EysUHu)^cL_M@jm8T!6ldAvH+*^{e(gjp`A^tB6}~(2Js}qo3DtY%v>Y zMaMhG3~M*npW91b7;F9dw&n2@t#AKmZf$nn>8{((uG}y6e=%E23m5KZzY4qFOLW)0!mY1=-mHT3cDthKTDgD~u^QEFF0oGjjeF*3$@;)4?kcj7 zxgeu6$jz5#d|uJX1(6+x(`P~MPRI2(4k?p%x7 z>`@M?loeM{gOCf5tGo16Hz*9(t)AFmd!y4CzmyX!?b7@>b zNA>0N3Ol(+$&|M-sot}DHmbf`>I$N>V;?-Bi8`ZISM2hU>LC0KD%R>;1rwH@O0K4y z#LP;)a>e~j6BBpLGn&+i>jSb>UCs^3c38Upbo}tfoobsy+^Gw^tEU0|6@NpyuoA$_Rc|*>LL+=RWf@d0|MI;pb~s(poh8Z%QnyG znt%^sMZfK-qZXO@IJ6Pd0i?1|{1-rAdUcWIBMAz)^f?BW0XZy0b4#E$rw8 zMBKGP6bIzT0&e&-I^ZF>Bjj(zehyYk_$bv-6RmUwy^W^g^>6KKP5YK}t%)7Y@?+eS z)na5BD*sF-OL<9F>xDZ@3?jv~_6}TyYB*cK!-h;zS3*l2kF>tI%{B&m{ddj@=2-R? zl{UyPYkX-ksBRJusw#r^LO+JMx4-+BXd(9Z)$x|MCZe(sCA@qUP3Jxk|J+Q*yK4;W~RdO;s@R6A)kpw z^TjGB6kUOxD?Xi3oJojb6Z(rn7FTK``}!p{rNfmyI z3Or)F<&QPVe-A~%MNwyXkGbR_xFjm{-$O`l;ydv5NDga)u)?x2N4EvP#B()i4?>B| zCM+|p(8i*l)9d+a2Cv+2BSYVi8rKT3to0*9DsP7CT~S@rr!M}Sx3Ump75@U(183|^ zh=1U*E;=o+L|FPWgJ%*AG^Lqbz{GRf&Fi&wiJ$$0Qr5bv*NXPP<_N_7H+Rwt-d$8X?644qZoufwQ%RLp0 z;CRf%Q^31KwmzKK;qulS9$Ey5vhQ(b_*zKOH~E0}3i%fm9@y4Oi=;- z^d&E`0o+fzXKJy6O3FVUF4LL>@|b0;;@7Dq%J%RoxPq6QiE^M?L6;L+#0GM?m%)D( zEF#pmAVM~$z#p&k<-lFx5^U!qT#A{$#CH#X8Ux<8ALlmaU=Hd(x7&Y7wd$@1UQQXs;v< z21A-(+{Xca`!dwWg3)Tci@{KAw@&fp@{sEzoS?I~a*OM`cmjVd{1_{3k=3W z{`kAjjiqXiL)zwy36%s|gt`^`v=X*4F|1CAWT5ezo7~cIxYWAhxP-2F!Tcc8n%|BG z-v?3#miJCqf!X==33ZWl`DR@OPa$7TI%8r-3u`;Nz!xP_O>z20TU*2=`rE_T-&$`9t1DdYT-56(oWI zK^NAJ2qxPxi{@~p^fV%MU&RZxEPez0dq4VqC#z_59n>bQ$@uaO+W<*54yGjx4;^NGZyt8$!S66YSKhA z8w`YrWutK2^eVKc$a|>?|455bRhhqnTO|+MH>;S}j{x{c?_70_g!(?)Q`m3>&%0ab zyz4))uwOTW+tD@(*&i}S)N43!=Hjjc6Kvb_9ssXMKmm_Bzh?t}?}or9l2HS42L>#` zEk$9_wh~1+h6eEi9~Z&(FwDz+Go&wHkt^}{nkeirGZS`^0blwdP(UNwI8C^$t^<|f za=X;8WVJ~A5w1rHlg4E3*dXno|3$d3SWX6r-TaajKRgMdKVnWIRZ+gS7BP*Z#`U=I z))noFxLV~h8+p`!8UrH>{w!!QH0C=8L&7r7*rWI%x6Q7Nm_Em))UD68O69~7mbze8 z*tf0qV)~k5w$jhA%B6kxOjL9_s9^(BCmiH(h?-=Z%7acYEIhRg;hhGbOcGz669#%n zgdMoJKQX@urr}4?5QPkZN`NnY{~~B}T5uX84A8c+jkgFN$} zn39NxN$d$tU(WoqD(ekAbKrs!Jf<)(UdhgkYO8w9HVtj?i_KI92S8_M8n64B4Z7wK zk0V9`t6>_mmmG!K~hXW`5ckI?-Wkx z(j%xxV@{FjP+2Hn_6jyET9+M?Te7PV_w=n`tPQ2%uX*i&5U74Mn?BL#i=qGZ7T`AP zFRo6KW`@__XwCoZ7z0bFvkU)g2;oe`zL;hBym3}*@puN8`ZL$yR6RJqxg8Y88Dh63 z>Trw1tXMi;y>lE3*b`Hm`)S(K)#+oK?!=uhy%^Ov$0)=&8<*$gkS%{X8+W83fpqtl z(WG|h^l)!y@EE1}Iy0?`;&o!9ZmB@Yid$kN|^+IP@r^DAEitZ^z13Idya0MJxr z#(*zF7%e-i1ksSWJLK*r!X@q$Uk<_Aqmsz^HmdzIofCI0K`flRJh(2EaI1oD6|-}| zu$@Oc6$cdu0h%X#bVak$W#HbRwF%yE8DuAS+&Sw9O`nKeg3N(sK--vZh@zEO&a5$I z{YNq6?AVt)J$ztgnAZx)u<=MlVD*Su?3coo*dGucMnOTc@l{Zq#j0{G&3Ke+xw6%p zQ2l3p8Ebo%0#c|-t!5|g3e@tD%3gYJPi>;b!5DZa@SU;u1~Iq>LHqAVqb|5~9)Jyt zJJBxeknhx%Osx8UkbId)hywo{_df6LG&Xb>&WfQ);;iVY{QHnBdWr!ox)G43Be}OR zdfad61uTaaDI{v`S}%9!!S|}X;xGx>36tjVW+(+jT-`fgET5~_-LHho&1NhGqei+^ z35PH5tEiM+2Tx8p=R*o_w*Tz2ywrRi6@Dw>l*`%l!|zR7M{`;eBj<__14}eh!}+)` zPv~x(Wu>)@zy8s39|^8+TurzCoJeU;56mRFSQUnc#F&hOd?I#O?q`>rRsDlbg+XxJ z*@=)DVBB%=0_MwY-sW9As4|19qmKbDO!)G5rfo$tW_Ed`hV#}HAd%3QfSUaa;j8+9 z5@Sz&^Jdfomn?x4=v^5Q&tLkqef7yT(->8><-R6u!hUVcsNghdQ6vWNU>fJyQ!V@*`%%Dvsl%iaf_R!5g~IJ$dNX8!gTqo#uGL z%?3sv(HttlDNQW`!?LuhaXup52O!7I{1EoAkcq$r^7hBnAZL z4d3)vmaj)1{^lnZx8^r~v#J$Py<9TaTEy1Dzg4ZhTy!O#@Q){$IFF-i1gg@|l zJqMK-;Ixpo`4y8Y5(YHBL*e%@O_u0Lz)>{lUe8X9(aof!SNkJDXqIU;hu_ z#;~-^2;x4d3k*Rj{@nDp2^spLGF87CNMi1WBmq8Nd`aOz5BaR>Quq3ENZ|kO$JYN7jm>dzL3}MtjuHxE_*>Biv zxY~d`Dww@C443)Xqr8V(8(9ocXw7$<{r&S23US@ZeDGD<8p2OEZzK@(v6UP~%?`bI zcDhn|I519hxKbi|$aTDRPHQsKnIaZ^{{2=B)WoXrAR>Ht_ z^!7!1zbEg|L6HCi;EQ9y0wBG&8~nh6|GS!fH=u?=9vpMYD27A$5HPGcjqL_?;_54? z{bBfF8)Z8dL!7$6vV)SeH zNJn18BTPvS+zl^sebORDe+u=8%|;wP=&{peO^I>6GI~+ZnGJJzh$z*vIp*=r_~SFx z8RMV%66X*tw*3~K`)uAQxcD@cLg*y$WfWMN6n_TUg07+#T{dQPlJh)fIBhE7W|+&jOr9u)Q)?;D2iJ?xvX!nJ>mni3MhNl zM6SmXGjNa%)NRi>Of^!R2I!&d=ZD;xTb2j64HU$wGyibo>JhrcqRUdADxUk7bsIk~ zJD;R24&QYJXL?@49z91xS_iK+I>zsm4@f7G~p0fI)d8rnV}Se>scldhp2vG);0Qb#uh$0&W8s({pj~h3!WAzj*Ze3Bwb&!3^#c0$-6%M}lZKYntl@Wx3 zfP3eMZ$@ssscbPCJFwBPR~qmxy9I3C{P5>UY{Ss{j}V{MJ1Go-BU{eFa41ll(Pp6- zc3rSEPNZG09#+CiPe~Tu^7?U$1I7!${X+@tElE|rBxtr9;>z$G4vP3HoC;oEA2;Ad z)c!GG))`P^>>ZxMp1}+fe%Ud-fJ`1ZHOGh6hL_+a3fN}NOsYyg=tEpJhO zDj%4Abs-d=F(WehA76vv?O@*=V0uHgezGy%zRwbwbvNg7!sff6$dP9E^p=cQNlEjL zSH#Txekt-vD6>#j)WM(D0eUTT%5GWQ|8t6~}Mwf3@9i7VHpvz0@HVbtB9>z4eQ(B6nSqfbO+ouMLqy?WbNVic4>*F~v< z!L|3cLE?%b66$s9nN*gEh*!qOn|#TR<-Usu8H7G4qg)sYeLV`g8g)q}^yItz#iRRK zrFZ0CwML~GJ?~RL_Uyve%!G%!Hn?k%2Jg1py$HU{&mT0Jx<~;+;0S~{m5mg|hPx=C z3V89H;%Y8}4Q_Rrp<{q(22=?p=?+erGtibyLLNa<01?cC``X!=k~w`BIXz6_UF~T0 zS~mDPL0+C0220f-f%tU7$`=uopE`7?aijTkZDgszDF&LF4f@pqWuUJ_rcxzceAU=ql%+hilS$Op!XWRs)?vz#igc%zP z#_k=+?f!eXZ;+)u=EPoFGdBF?ga~WO=b>o+^4MjdirKO(KFB@aS&*O6t2yEi?%he> zzQgYIu9;S#Et?g#1A(T#xz?dG=USgvZMYHbr0gqK55GNJG%Bgzgri+g2rFiWU7WAS z)w^TEt&CG9P6arqIT)iFyi>J*(*6Q3L zYi#zx>~HEw7UYLm0QN0e@PzssAgnQ zYw=2M)6F$#BI2kj{ilDNW1_r|Ko zf&}fE|8XC(wO|Ii`c&K4I_{DU#G=X7vsP6f767U$-b8Bq5PK@>3s_r=gipb?m7G5O zYND>4-wEQ5%Z?DKvmn10Y)yKgR7BuF%3L-ueWYVA91KR**I+INnbjXL+*^pPeF z%SqnskwRaaW5G{?^})6W=InHWxPNEHodoISs*#$gJG_>-1L2ATwT`|9^kFf0Mt~gm z2>%*OuLp;^Ly(Bmh$@}0`=UyfDeU_o<&3sYFX5>p%L73PZJxR4xAH=xZYqMh(D1B= z(a0(QL1m<^(vK|T@ngEi!)`^2da&5%Xfr>5C7p)O@}xZVT%WT0))sbBiuTTKY$X#S z7tWU@@-UpeKhY7~)3f$KK5Oa(0OdUdF7DeqJ!D2JQ16>;<9`8WSrf>i0j1f_3;xLA za$S(R-sEcweymd~Z0FzF;T$jWP|&?Di)Ou`FQ5NCRI{cQ+%evRi)0zA_Lz#!kq)}6_mYMb>F|50$3)vHgz-a);+%CA zD6k8~f!rzmp99gQ4qCNY=}|}p&{k>SpEelOumD~l5A&y6lPTU4W~og%Ey?4ph4n0B zzM5Pn)wYmZx-#R=PNf7QNLsx!dFox)_9LcKgXNsuiccqm&(Cq;yYolacA}aEO9WvX zxk$VPXX?*R0t8jS3Zu4U;7=DY_Gr)};cF*$`fh-YfYWT30*b(*s~5mAn>?v9;jJiJ z7Ta;A%ON|zvn6{s`b?H@%M|dEy0e{({%sVHw4jA}Wp0!a#TbT50;k-hW|y3yI1E&m zddqUv-L>ergVC6g+ZP{;7tX+gInLLubN01~%EI>$ndxy3hI#7v)9E39lCmfcdc(6k zxxli(Gs<0t7QK0{KPzi5#WsmNA-YqS5yXsI+dGZnkAU2MDQ@moQ{M9xlN@ek*zD&P z+>`af8nSNW!Orf79|s$q4G(?Xww70CDs_Cm_rTnm9zmm)dHc<17dGK-{51}AiWe;xTK%AWmwL9&0 zQg;kOXE+GRhqn0OuZgiwq)bG*Q(V&_>g(w#P1-kjXuXBp$M4iRAI zybvULgmw2-LsBv1L{@cXOUYdP`|EU9(9vmF5FaUG#y+<3!~Oj(WZqLYc6Mr=lAY16 zIc!A1hC8Ge$AB~482aI{6OZnBn=gQ&2$|wq?METZgM9s~W~NVHw0|Y%!i5v5EbiYR z>m#ZWf}5Uz<{v9zw}>GLN3YyjJOLZf+c&5;4^OF<#rktxI*LI`n+XMH8i8@!JYh#FOw5@qRJ5MGD zWe3TfG9H(di`_6cVrF=dXwStAl8S?j`m7zqcQGBFFv`rZ^8ms{@*CQ&2XCW@a{bvK z6VBdgxO*2VN{+y$z~u*2-=VK__VUn{fy`Wug{|+j-DaSKvQUB%?d+aQw6?s1zIFTC z?jLR76@i$3#+r_SC<_TxE``wphpenWjKXuRSF=O;-zvDfq@Fj1@ zj>-;$2{3p~V`q?XgQ0-EH(o|Oe{iyI9XE3AbV^HUHI!{4!#O)t0!0$0^@hMXE@Kj{2wRia>^t=3L z^}bJ26ImQq7vhGc^P`v*AMh8TCqWk1EX?k2|5s5azVGa!8#Wa@@0nbSj#C+mQ;mN) zWDIjneXOLgTWmrL&u*yjARb)_rL(uKa+o=&EZ zB(Bgbg=Is&e!(bD8RwlEZI~n3;=>+qc){L6>wP87o%^+d4dqD8b&s^)Hy55Y#Ltw+ zmgf}MO%Xcj6zrQ4wjn1hjeOe$2XFsA4A~)qm{A)DaG&=Vr-edRQjrM@zJu3Y0Qo?C zhjy}|-LW!WIN#yn)8E>fa7(l9g}%p!lf1_1xb|@hJ~*F#>jx&P_@*wajva?;l$S9a z48hMRu6UfrpKfGkQg2#!-*8b1_`A?>by1g?QTKymSZUSPhbX=kPg%FbNips|DBB-) zI9kj$LEHEvERzx?Nx@+$6c5@o-o{JpeBw8>BZ#`!(-(XDWD_B!t z{L#jp=#bxc@$n@KKSy+)MWv9&5IT5W8Casy=XusSk)^Y3av>fb_4tu~ofp3K=6VzE zsT}+oULxSUO!jl*q`M>FeU=_l$ZQv>v~Bb9`=FDQC?P*IC4(aobiTI1J!+|dH^Zn< zvpn9;phiz#r=l6J-WYgpYQ!b=JVvLTqrW!nf|DOOKbLr92HZUoUO}x<4S~P+-HS&T zU9+7!U!R>@^msmZc6P5Zrluon{*(G7Z)QC>{7&Hg(c-wmMS5RDUPOue1n8*5`#XRd z>3sLQ>)N5Rcxf~BGs}$N6Jtssf|yz3{FJ0sca75K7d8Z_jtLh8qgv8AWdngo@wCAZ zugWia)n&nP7UO2BcVr|}2j_?FWHOqvhFGz08qIXvh*odVw(4EytP(dTAMlVT(USG3 zMPDE~kkv2pg+8D<{dE@`z)4lk?d;_h{k=6g9r3g1Q)Tm=Q(e8W)wga@8hQB|w7#y0 zuhd|UQm)_I6RE?2ZHeuEwlYGM%uTm6@AWs8^kdvNdgsrVzpOzhB)igXq+QuxHYzNd zLz>^6`fNvVNLz?5891AMLrmbUJbXhim*;>`f(P#CKOL<-(44_cvPh zU8X<|V}tkJtT_Np+!$v5V9cM8j^XaMXYatR8{r&`Ec#bY%pc!eWZr~}H*B}B0o@-4 z@hWW#FxLeIWqeP)kMFzY8soLC@YC%dh9Co#dr0iFEnGU}wYB3tz_HN~Twr#lcUqo9r~lOm5Gb zPR5HAMNJ(o3JgSAO|~VHUb#2d)!Ipw1;4N)W{^&JR7QGs)-DL9$Y7ufY&)E}&i#{WaEH=iYbr6#CI#UwL${`EP<%fY@;v-uZK?x4FRopq-s?;6)gcS=cqaM7;v4%P6-SN!KsRplj zYVfNEm7ij9R3MRM2_t_)pLM-oEb+^)#@BB9*kkkL*rV3UGk710v9+l64#z9H!2 z%{J6+s<^MHDy3Ky@(RkUlu(X(67V6Q?C0UnkX`+K-~1)^@Y;z1wU3YvI{n{6%LtbF z$OXxa-bFBg$vFm3mfBjrkHg4cVeq)v4D`i1{(aESZbDfof7B?j;!G6P4iH#so?ZjJ zpNRhrOY)k(8u< zaI0ruhq_{U3oW8es&FzGA_4j_Q6>%}G zFJN%J&{Jy4W^HaC8ETP5ZHju<2i;bA(oM>W;3oVSG$P=cd}YMv9@m8zL)xRozjznx z6gf&9!)tC846_cZ^h}Lp>U9#dU8IS6rjbE~?vB>l9_|g7Vx22>EH7D0!_qaeiBCyqHH5~fb#^ffgF}72n?A&`hlkJOMy%4@ewQs zHdo$m8VzSA@r|Btc3f_BVLMs*!(p-^x!x0AXE|lR-`z5yz1|qUvhjSYC`7MCX(woN zy(l8&>*j`RZ8k}Xeaas}eH|&&5MXrR6e3lT8nrRs=31LhyT**1(xbelX@|bRcH#`e zY?X2)cUGKWuo^wHYgX-r^E$1y3RJ?fBf#e6f;si`+gK5P1ZST{I0}>DP+1}5EZAid zAnMNPp~c|V6krH$3I$a4LepGQ`Q9y2KF(&yWQ@LGcA6jc6bSZiPxm*t5o~&2k87(m z+U=P)5p|JKxBg?|Hoh;;T`Nk*GF13H>Wy2CPm>m7J&iu&*>|$GOPePvAxzQ7`S1U6=4+Mn#eF&vk3W6} zZ)8XeGaIVn!YyGs+K9~!C~kqFN7Fqp5GF}60)oJK#v*R#YwqO$peLlornT37k*X$5 zMZS*d!m1A?Lemo7TE|>{(LY~}b8S!hHat`R$ItJJ^;1XMd!O4YRSZ+Susd78kKj{( z)a3D22yUcYJTgB|8h>gQui>S7E4;o>ALFFW;3l?xz1!>M=j1mflRF&p9Nk-`TtHtO zk2Tv2jC(F(adn8L!;VFj&&2|b`c`*aF7^AkMN;H66~}To_)q^z@S5(kW695U zK60^7_rEmCdw6v@WK725=Eoqe*DLyow6X2WlKC{&t-9+&K{_LMiI)|8TF$}DA|Dei zFI9z|m^7@o5vey?rPCFssH(4%s1wv-55g>b(}^csq)Nf0Ch<>jo6R(+%F$o!yctaW zbho;h_VlnOu3l@w`DhtD3c3^oO}@78@M_;dFvS&28q1#8|Lq!hHAd0WcYm(&&s>#Z zkx)4(scax$aQ3(Y@{jd-%4H>mbUe6j2=}H;i7T(< zf%*#U8gu=clSj?|GWzxRj3Ha^3YuOw)DUHsU95kzV7N~&Rw|zEaI#J(FKdWmT&zF$ z-Ya}~v?JMZ+YFvZKGGR;80ElfZsMjeF%=vteQ`i!7A?wE->0w2b#pXxp@Oqp%9tX~ z=P3%tpu*irh~{ZyHTNyrm`XXhshs;3$lJc&j=Q>ltHhABdOG*EhE2L>R;{Oa8LN%3 z1l)cpbz+(xWF#2rKC@*STO_MHKVqf$;9Ifs$;2uvv#@{ICrVvu%xy;0MuP5iQ!z7k zc7zo#;vR?)N*|gfDVrH3a$^hYZcq_TuCl~{+N-X)-XoRIh*~27_1-EFyZ{EaW%K!G zfJghkV=1_K8+CNx9PC0ZItXyzw*dBexwEEIxK|tq6AWc=$0$F|b8Mvfa$NVxHm<@o zprrvt98osU#;B2^Y<>X{Z1`ay3IPxp*1E$2=xeB%xVNcw`>63aiOJb=5QfbVPcnh{ z?F6no3mqnM>qk14=H>Uy%SW-!)%%Y7lenW-@+Qv}g_Q14abI$9`t)FnWN_{_yj|uh z7#}=%Q0wDWYbR8^vGhzq$UJN0)(hJ>nkj(P8;|#KV~?e$pE0W=c~I)-=<7dJh_n}Y z8DT0=sUDJXaJD6rVqX0f0ut+KA$u@KKaGRQr@LJ41}5F*g|v$ zgE~a!46}0D-0PWIlYN_k{}m?x+n&o&)z+E+=o%lj>`s*b0C71x8s{yDFMN+uu(eqE zU^2MwbuCC^^R-taRnFnW#l^Zp&}GsT-dk{^Al33|jjk5K9BpvWWeS%;n{tsO(0syC zfsTMe5JMZqFtY!F#q9?Jbe=y4nbvnDguVSZ@Nd6O{I7uTz8yMfy3@b6X%$!F6vdvn zJhYs)(7}opb(n7a7Pa(=+5S`Pp6I@n+kX$RPf}qAI>14Xh$qp(pi>G`|1G^J>?UG-N1d*ci}&=G+^NP zmU2@MJtl2-vm37TVfK?*I7TV}In2U!bpwR+MG=Yh!we-nT<#U|tzUq~lj!Ov?o20m zU?^cBESH$xP4>e3I?Kf?Uhg_+qY~)Ve_F9`C8anjV$0^O5#(uJsT1V+6y!F;s{+`t}?) zYH#TQm9dx$LnML_X1;GfaKOQXLE|ibRB${t;voYBwV`-ec{gk{h{O!8PCVSCHb$ zq_>zo_V;Tf=Y%s=&V8D;s^;3%45EiY<=qnqp3RKq9C5V0{$h|Je_QpV#r^~Ho-W+^ z55tgUHqRA+U=wT6kq1P0SWBvMZGNihT88;@%rGPuA})ZeEdiq5i@ubfcDbJ#`Q9ui z4b~b(xh3;)--TzulUw<=1B>pR*}j{JhoZO5Eo@O)cPrf;&qXSt{Zyae6{IpZes+od z?%S{YChyw5h`XDn=aYa*<)G};1%?P1B_n%243{L-X%$8x4nP@h^4GWB=~VJF7!?(v=+R5jY@pj;UK-|17y3rH1o5_6pk4wfX| z@m)D)J;N?afU86FB`yriRD@2sH9!fT#wDfrZZRjXMNr}&S@x|*44#1ZN6^t z7zj+OwQX{AzFyhkXKfWE-0vat6~(;^~{)L6~kT-7jrQsfhd`O3)Cp05>?_bqd- zwFp_7a0xC9m8lF)o`|}OAnmlTAR^PPi0veMVh3f8WME(T;f^=GqGMKY4t-%B{fGrm z^Fijr)at;Zsb=3d3zTZb~~*R z*ISe6ZiH)dXWH>$omB`CL@tU|d+A1#s)Rarqr`^`GqMuxRV?w%>m&Hhi4jNE355=-dJ&KCvh(V;U$( z8+VUH-If;;!sXUx(1Y6&>zIZpl+6R6e6HShrqFqueALs39%v{V8CW+55=<|dai2HZ z2p`4qp4=!tqmnl~SDQA-XyxANhAL%|9K=(>f$!;lpM*e5`Uk>NFmD3H!(M3S-{7cy zpg?j69gD+jsi0=(+nN$Mh2TbWMkUpk0RfVLnX{U%?B3v@$%3^U zE(lX>BuZrziJ{=EzG>-auoLI_;zkSSi19k=4$ox2)sPlT< z7;SzsL=nU_XVj!leD?DQEL%@#D|KmdrLwf$i8-T2*TJOXij9ovpeyN*mb{_B%}_6G zmJPkxB>uhRaxf1ZT;X8|&Ki@B0}T*~V2Pp+MmWFI2&$<2OwU1GWSY=0m=u&4I0-rC z%eUoj)Hm>>z+Oq%VC$xj1c?h7REKm;>%;sXv5`{S1BNrvFf(Sf&$4*r_p9r8?MtZn zoj5b?kh1%{W{~H5Vj)jK9CnEsxY^(~$F=CYbN*?Z$D&pP=2aoanTjmv*{H9 zGgEb_zf>7#*{yJnYTFdfd+^oM7 zPVV|ZQL|rjUhEp%UrQGV4S?rN&3(rJV2}0nI$C?0ugicaY?;f;cjK+wx$BcDO(;>C zmCIk}xat+Gx8lEkbbT4|Gxe`6L%-$WO$YHCp+6?C3A@OEzr#M=l1pA73#}BrrZl4X zNn;EQ1-l?5*7c(OY@z9qH>#aYYhWRcQ+l<@xew-}5ICX6>a@|gMD6)%)tP)nFgVa> zUFFwIID%kiy;$kc?XfMgGGsk)<$Y~fq*Czyr9nCi>B<%lo@XO4GkDd$gNCp0rH7RA z9*U&wb}@*Z=tFWZuxfJ&^p;<)a4VRROOb1mI~bMWNBb9Sp*Fv6t4jg}A*>c@Bp96= zNivNA%gh+D2&>!EQ8K7mr(&wAs%ExexvoYqRscq&9j~aP?F9=X^G(|8Ui0>TH{7;pmNT(dDX3^s|B@gE>e5DekDyigG@h76QAi~zDmfP_dCDO@AHebSc^r;OP>4Q&)(No)UW4` ztFkkO`VZjtP&}6sj-OUM44lpM!8`s;(};e_`G{Y5>7~zIWn*TZzZwhAzV{x6OZDc& zl07TM5{n$;PnDn;R}G7dMQN^swsNTj)&}Bmlw(?qytgU*qJq1J=Fm5fG->}Dt~RcJ z^Vj_%c=D${vI#fmrPY5)uE{=R-|y?w=~_+bTQ%$>g*Eq)w0{qDlx((e3B*8iU~aj8 z5xq;`69%co*bUEqDbT-$<{Ho|2<#I2Uez&QTLMRkpagt#;HxdA z&z`{CDmngc>FBAVlWkRBcsOMy<;z#Ws|u@y8&)Y_AckZ=sU1g;Xp2(ceEkZ4uRT*s z_NtpPBjuCcbh~Kw>JW!_{71_Io+6PVX2s#TQ5-$i?d6E*KDwjKDXS?Dl87Q$M)~~o zJNz8zCRp1u7KHLNwxsw3dcU*)63o-sjRLY_mJv{V%5*PbSs~>pkb!Ii>1kB%;cW&| zOyE4(i>$>tZnJla@AJ{lul08}_EAXL4{G3BYnEp6PufS-Rwku z$~O?AytAS0U9N_&DgYkSDXA>xlQctM^Hu^~KD%348*DBz>=tw&7dRUelK*+i&17;7 z)_}4jxTPej#X3Y}hAqHAbdLWuo!)+_p%hw46lj<+6W$Ij8jK8gSk7EYADdPqB$s|0t^$!UD`WKE|~fmb{#m4c85hA5lu^j9Kgvjus zWKeTJ?ul(r26C6au7Zs}X- z-XyuzK+Pre(AU?mVqGdF8`QOrGe$a~qGO*q+`Q4&U*5XlU3cjeZI13rV?x*AW>!x_ zh=X%+T-2hwclj-^tN~PYMmqlLkYjeGib?2({cCGw;oGId9R&-ows)TbgJ8BW0yxLB zLuUq_2fJkY4D7)oDh>X`z|sjE!Vak5Kn{S7cI61AErWJQM(1J`qw$>6WXJ7-!}_&} zgyp3Z*dKuhUQF-ggZ%NL6SZw$KRw53=<8e1f{v{R`Rw@&@S;PK*F z(xa;(C7!go!g3>-YHXW#wtnD!aNSDS(*TdzEa-1ID(= zY1Djz8|jfpk;Gwt^xk>hNL;Ya%2!fat=|LrvX(K!`ErTcH>>3_kCK4UA}lKH7TJZI zG}HY3l+}E$HAM2!RZX|tI?w7m%qyU{2#?1`yTmo)dfTKj#-is-nI;j-I&VPf4}RX; zy`&xR8VZ!-&k@@p3V;Tq43dk7aT-;Te35j44?7?j$%hbo9sXXQZ9!vvKiq9vGnY#W zY^lNCLeUc`>%Pe|Lq%H+E&hJax@T2qfpUF~!ZP%@w*0krVj*f2Uo9`8L{La!2sYw;l*`&2xXgU(7h6_MlQ@fv@y8u!q5 z$`q*(;T%s0zTSh*&@b=sU?oKz#r7^;Nx-TPNL`sC#qT*F6BQ} zwR|*Nbu>Vh7@dRqpZW1DBjme|L5SbUjMSAP{7LQdHpZLW_99=S+M_R(UOZ3d(Luqu zRA{!IV(=zKBIOO@H=+Ip4AQr)w455naEvT`OVj^ylvl(xC|mMD zE62xT75Q9U#Y*+uI_<(ge%8@Mo4hn#Z7Z zvX8x3m*W^m2Pqt6_u2lV6fJ?}|Ku_vqMa}hmAQ0OAYw+1;#Os+90K}zKR{x^F}y;| z-`=)$5wCGnrVz%Lt!5V-8-Ic+k^PlVRcWd7v3?u`H&4hp+*_*}l3f^Wp>0`d<~q32 zoqd*Zc?{gOc^;o_>Z`TC$9N=ax|0<7MGEd|D~CPxAK$<*O~p*HpDfBNE3}J@ugj{g zcaJq4FZ`ygu06i*Cweip z-j0zZSF!f0@(_}L0~!elF^%TLt*ypBZ6}U9Pxps3kOlh>@o2~D180nqW1jE6?}wfU z5EPyS!1YxjfkYic?}R&aPqLK2uhO`_@;;OGV$h(hBC{FMNvd0g;{9hFwr4a&-)C6sCgLa|5_zXz z*7|Tbq1}U(2S3ky%TCBn(FeXQ_ooRQ_^_cq$=7iNC_tqlRCW{Gw5=cX1+w>eMqm)O&95oo!)|rl&{5 ztUrcknV_)p^U@y=aJfq&MW3ukVQI9zc%J=gfn!boU~w)^w}hqBGS7jXLFR-{X@SFf2yum&*=2A^C`kxpLDpgS_bBU5yz5m zRGxl^%w=DyGMoT%#0y8oZJ}aLdLykae>`hhV6-;0oqQB6jQQ_M_h#5}SNe+g%UEsn z!Xp^fz1~UY+49YIZ%t^+p?vSL63tf@#47QX()%Kvsbej$zgtI@jfPDo&$#|spxgS-plZIwblX2)=H36i>{FT#y`XWxOD*Yp^t8^^ z7^tcpQKiUnXMOxDtw`}QNNy^x%r;E(ulX=+{yNhpUPCO7tM%$8SSI>(#d4S|Kcv&8 zW%j@!pey8dRY{dZ|8iqhTS9@!whE3k6etbQc~0!P3`A&@tZ>9* z467V|c^e@kNCKRn;6zw`=YiBn_PCi&fy9Os;KixB2R0gAnvR310IH}-0VJvH<#bXM zs90l`+Z2lo=bx=wo)1(YmGKIrAJy{Jk8~;7n-++$DH(ZkcNn3TyXL1}wPuFME001S zhgiPyL+NoOj-k*>MR0nnw;S7jpUJS)8~~EP&U>2$TZ08Uz;s<2?tw zD1UqNM;MRf!>0@&lm*t{6U{*6|LV`MwzdlfppAg)0HF<;mjZ`ChxthVt{FV+2`-T3 zfmZrlX}}Y{Bmq-&75RMTxwom(4zFo8FBRxU4E-}q-YxTkC3cP2g(&EivjURkP>4lC z0M;A-^r=d*ZPmwx9hWnMpS+t+&_gUn=F3Bq(<@yo-;8uW15=`r%5a@2N*eQ898jhI z%E-0x-l&n_JW8o-1-!yH(a0r(kKQ!j$6CM0AIy{#6I?vL_C)FIF1+$W%Iy#~+59;= zqJ4EBDy^zrBQ*{tkMpA~$@hwadk*Y#iUN@O6tifMk4FS?l;pRcyy*?7!6>pa<6asw ze4`%CCUxWypV#}o4WyeGF8QApRSZ!~nGp5OSB2!zxviU2Q`*(&qVt_Fse9vJH}x_1 z>K*GGO;u5%IVAn?*bANSEng|O6~`1IBMRtq^f}tq)^~3$hmGd_F9nGKc>3w_mgib$N@uo8X$7TEXO`bJ<7!OgSz<}!tMil8i5 zX-#O4#yWPAB^LYimM#73*hZ!Jn12trjkEx8da=AecAT6bW?}CWRM*W8@oYLZa(JWy zy;bh%WCM}P9-JDOWU!Z?w&|KhX8vN$e$5T_T-%S3%o^OYIziEjO}-&t$X1L67y9$T zYy^vXw@Rg<*SQui0Zj0!xYiZRROt_Z4$~YI@r0)V1V^tV4Rm#~Bo@Js&hg9p!QQDh zeCsO7q28{ZV|BY_jWx0KGrRX2p8453)>UT=S$W9H$tg^TW<{4Y57|9-t<^mraog%m zS`EqE(akkdeG20Q^?Y3KmR&32TZnl@hFbKrvpuHsz*ItlCbQ<*jQffj)ZFojSM>dQ zK9aLaE4W)JI+LO%xDHhCzAgWt=N;Y*o&(ha6rVyA!f+aP4^b~uou^P9e6O7N^Qtye zRhOr4G&bmZei6#Pc-eh#R`T1ZqL-=Tba;ao9V1h(om_B_jl3uP)(=LF-G#lfV!4yM>58Z9#q>ipL_A5%h~Aa46>*P)zg#W zSnj{>Xqa0{!%=ss`^CK?)!@=AwAd$G9{|khXlb}!6R^te&%}H23qbN$93oRi4D{)R za15kz^g+c=Do4i;0tNi&eJa!KTL}UDBdIZjnl(k!{o>kZfqpvL}D%VGzwwt%Jv zjWp&m#pcW;z8|L%9ST-sHmpCz5bSDZlMIo4z%#nN-=w%7+6^nBsZ7}JTj zs9kg3P!;{8J)^3FvN_J)0^JQ6`n^Fs?4Cb}pKEhy135xEO5Rb_UKEe{>E8oGmoIQ9 zj`=M3`+W$ANP#}|oYLD0BXS~YvfUGUaQKU0dJl6Mj6V(Eso$}Rqrkn|#<5e?Mbp1} zuWsB7_1JJF-Ko;hKilXV2eQsrkCv}@CUmVzL=URXOl9_dy^e!QkS{m1B%LxLgaKS0Apjh|UTRC;W+Fg4LRO0Sv``;F+CI;4e%>{UcjhgQ`c*M~ zWs72>8rGx-pRJeaHI_H8mtAiebNe+v>Wv$fvxR2UnBL|3M|usr-?^N$nl{9h_S`4J zpuS~A@blnG=}pV?v8k!B%GUboESHtr>|toqa=-XQ6NXruJF3M&Rilh(uC;DO{+>sm z?jbpJw|Ymib`fu#{6DGfL|LJl{MVj@EyAAKhAcup-dT0`$$mw=v+-`??fE_g)+&KH zK`fa?9J)4jtuMp1fGhdFD{G|-2>pd$45UEUag)wcjn}5ONmao-=q%ZM^gp3aQsnLzd<2)VPqK!Xr@~>8d@ESHz^t2(%ofS*Zx$d#7&?R{KqbIe zIEj$8-FttKI(4|cUg0u1qtRDCPucVA(}47P539Hq%XDQ)_^VD4h?{>)V=noBiibOG zDwZk%2G^h4SR~SJrpsx_51DISAwObjnXQ!Ao~1rS!elydnql(ST|9K%T)+^+4p09H zW3oaM^bXIXTQBz0qvQo4RlDT<@?`+Q+a7`}6Eb1Yr=T706@vKTFuw-1Hroo=GOaBM z(o`bcn3MUXBk%Nr0MWQ!?Awa0!@TZz_TbloKf})3B1oIV;kADgogv?;&2&jK>d?Gu zF((^Q7S2OgjNEr|1dZJ+B3ij zRjB{)mrwcW2eb&7~(JoKJ(i^h}riwMz+r}!bh)N|;v;lpkG_7_05$G0I^!Okm z?%R_?f}@)YtKACUsftajosVg*FPWj+DmZ#4S!^B=F&yBmciT$l63?A{wDOvi@wjL; zu-F((`_($SroDHVbf0EhxTK7d{wF*MZ21uk!h!FQysD!+6Zw6RH&6JmoD?xI6MF)# zR1046c4biZj;03kVf4p(Sc3fLG82~j6uc3Idef+TP57oo^jvc55}y5#d6~&+&f+vL z+|sTTF=Pbw6KoIWH7d9iLzFyA&cpS!8?;`ZQ;D!V5YVzsXuX`RDoEMm${Sm>rl1r^q9pW!-{>Rq{ep%F*w=y&`1a0{8 z{7pSl`W~q?XdMi(UNv$X4B~$eQ|#6T{+Ui!2-4*Iy<*d(ZCZySYacJKt9zKHY)O$H z^>S>8JzO|abg`@_E<(43=42QLPM1(mQF2z?M!;>wO4ftMIn@xPm~aNsCX(L^esIsY=TW^JzT`L(&=#8t> zd{4V^eu)mr2K9jyb8rpuRGTI0t^1}7hss-E|1Q%KFR-aFa8bX!#hmZsvX}e z-Bi!dW_qZYgozKjb-hD$sAH>RsNt;!@vo^Q;JTf{RK5np52D>3&cWEd)S8Ts1~RqV zjbvv20(nkJH}f1#gK_R@g=-_O36|j;L!b)F+xa}_9^p=(jl!Xc6^@TGQxa{HMB-}afPcn%un+EC*g6;?OK|?WbAz6FuT^qtu~OXHJNsvL{{uu zV^_VUfQ)j;U64h$t%6Q@4VD)i4&DQ8qBQGsAgK_+N3lMDC9B+m>_vmT_GD?l*IT_O zm#Y-9zYtlb`;m?KizM6IPu3KZh1DU1gF3T(JRG2W0JtY!?GOt8~=gb?{X3+Itn(z)<;@19t28R^=vdkWFY*RK4n@0=nj zgBBF4U4*@yACSp(j1p14-Xas>N_LblZMd{H;_c)4lxvxEqjAqJWg-bOv=7<6J!gGR zp!lZG8dv40_=6}ESznTYOHuG>{xPE4?uCZW1W5zafAE-kjNSQjmt&sIhqo;hHouIr zXl&Sn3*aHSmHL$@44|lk$hX1l43~DE`*Y0bB8Q6v-8WxnN%~16QY-b&?`v6)>!Cur z{h>@yDsEwagJ0q$M&iBp&MVX99L!PTck8_#$oD#%Jg$&{*Lh?+kBI7wras^A=)X2a z#dQs;z`)T#1mJQqQsHWRab{T;cma4w5CBAS&^ZQA1iCL~+o>uqsduj9-QvG#5JB|p zv5i25ImJ)2i*GN2Zi!@4gt=n!N(JZQYN$`1Zr7RdZ$I6rIRn?8pL9`W!X;D#qqMv| za!J`W?;Ya;bVIaWdu#9Lpy*!3I^x(j;DcX6${69t$NEz>sNnDv8dVn5idP&{MTsi} zw-{FY%J^28d!mTa(oRZl6;`N*=2-7XlSSqVDtgNXfEHnMi(3U;d;2(tpnwy%-KX{k z|9e1D_%=|2k7l?oM@fKX5k}~VsdRHxm4GU|hQ1wWu`^!d&`DT5mrOKa2 zQz7^2wLP?YX3XMiFW)QYHu5rrVi)(+@d^7S9f-wx_9_#dZk2F1?xn2KxGy9NE!QUt zsNv-rH_CQNY=hr`+nmb&NYH@>#InaH3g8|gNA9z0carUv*PWj&R9G$k+8TO@`4 zL+MDkHWF;Twwa)LmbPA7C_T}5a^I+doMPOH~CgU z!mY+Dini8og%uet=o^STx-q5)=O~4=r)N7Ay?rjTLZ@37;|!_dmT+g^_*iB7I?mr8 zQ)l`aMJcG?!9pKosJJ?IhS|fkTWRbT3#*?!lytBIzP~Z(YXeKp=4LwXGTAX-+wzvI zw;)hj=ChNyr+n^nm(H_=r@S_{VZ!O9wu!-l1AsKgp0$)m067w2+v0+YiYL3$cMy41 z(s(J}gv(6)`vgblt8;X#(0cC4So^7t0Gv;0NaQ)^=iSf4Bb)Ty)Vs3YC-J)-u6(O| zE>^4T5~O@f=U_(l1xFA5O!T9o^v5*t&sgAL^`NFO7-Y6jSL?XMxN$~f2#Y=^kNuIS z*nSoS4(m=pee3pLp);7TLH~?WmRI!!H4PD~hk2HcXICD!fP)y=Z+`eDuWHi|+>w6_ zz6}1q48OYq!gHV_rWykiPx%9MyBq;+))xQ}g3nZ3CE`)s3(E!~8y`*qqsw_ne?IXc z8+HW9U@U&92&#VP=N+De|5frfq?5?zd~2S;UNu$@_1N+Egq=*o{RE2uqRA+^^pRG< zk)Tp;bK!nXojdJ{r?thUi;m4C3vM(}Cq+grFk`nF+Va0OsSzpMpb#8Nx+ zVbW!x-sN5Tw5!)%j>Pke4Ec=9?G%S)z6Jizb=rvs1@CuZ9k2mWc*3$lD)TrsN1;6cg)F&zGeriGr4RQ=&@Tor0i8XQRlwOyZ`-88 z&7wn;)LIi0nS`HzeXKj<#M8UODF3b^oK0e4wzWms+UNw7#(y86&H%>HwhQlByJVFFHBqi0o=aCE6Bk+BqZ}jeWy*8&hVCUnx3@excOyz`uRCL&6b;zbm`O3 z9t{2WfG6WJovU*Gw$=BaG4klz7|3znmRw$%yyO&9%qjXfk0N66Mod$>}82?1Qr3@jU89F|KRf5tVu`6*A{ zgSspE*Z|D@Xyt6LXa^0 zy;$+Uzq9{CU$6@n<_2K0*2*c<=&s}+SwiIxet1jZ8^3-KrYKaxyLR#ssnodhHlu(3 z-zqS~-JXmzQ>3JA6M>dM0*b*7SRMY2nuqUjnBH^NsnA^h#yuh5WMxV;u;#0-^=~gN zg6da%iW7Hm&wKh8<^5MJ$J&x`-Hzp!h8q&~wvf!~z?iyspJ%GK3i(pB@1Hy{bF2{P zv*+$)Br)1DP^;!|-hA(|1cvw8P+h)$gAV&!xpB2yPT6i@%jJe=&s>WLkFNJ$n|O;H zNjdud?xkvpOFLmq6aba~?VIQwnYZ-V~-9Sy^5LgoX34v#_$IE0*?W57h)-O-09 zNT1CWXItvmHfke^eQWN&^$9OaFCW@M)JEV+*hjpwc}jBh8Mp(}otKgMb$uZnzWoOq ze-b_c{`BO~N-DTBxV)L*QABCJh|0IVQ)84J zQ`>X@1UmGB>A2o#5RH*z}-y7D!RI|LT;^(?M=L+u{Lh~G`D&Cm>E?BBi z7WaZJtl%x}<^vHtI*lL#SE6E5G@F|NR02tW><37E2whUPgq`emQfI&zs0!e_bS?kW zelX#Dd*A7jzq%()Mk9WoZW2~$|8n_QRF5+)biF(Bb?g;x!3J6jdU@|N!B+H2l?-*IQ}wB=nK8qM)sFE3 z1n1bvT04De3z=cb^g$kJDU{)Q*y}Tb!{HN()2Fn(b8l!{T<>$QK8oA`*={X_>|VVv z9&8BKdW%Bo&rdmo51;MRS;U3y<^c745=*Ge&!grFmDUO3@SrEd-0c%!#_R+>mTjrZ z`|_kGgSb2u86~icZ1kImiLI_FYa)R$<6<5wr}S2E4p&(&s~g)gY%y^!hz5;$caW|O zyC14>>8tS6V2q1vLB2yV+agwd{NDp?FPOEF`-&YY5ahHN4AEv@WZ1ApELku#Q#yv#CPN4A~JPQEl#4QV8;Q1ArgA zZK3GQ-Ua+`Zv+ZtLFoS92rL@Fh!-fZcpHo)xik>}VGIt*?L{SdH=0ZznSyV*r+7k2 zJn!3}SI^TtlFP2y+=sK%TLaTua4nO@L}l1Hjs|Q+*^h(%E%dp%w8>yJ;V_b}T%yMa zL%7vGW@W(7u|5_B8k^ErCKiy!W8qg~ie{A#ZGE1kTHy#$ie`-}o5b`>R4Bvel?K?C z`#AJxW%7PSMukJ|95d+i^0Q^|Ol*HP*x>|mZ1e@5vDwZe4XRt^e{2Y!|4F`@hxEvk z*|)iqe0xtA|5JA{_OYL(1J&-WDV^rd`>r+Ydzs{N!f(+v4dvy9^mwzsdIwj}Mr3wO zETY&Drjy@$S%d^|h}}O_AhH489LS9}y~n1Un}&?lK+*yvptJDFmg<^)pBw4{7*UeqyTPs-=`4+xcyBMS* zn_F9VpQ^p&9aGTk{;sa-Afx1tF z@V*MTssDNJ%as>%aI0Aic8H^?;RHn4sUpPoV?jE&#Ml?~LiX&O_z>^M17&lm?Vybw zAurSquhe?Xv_4jL%=+fc;Cqic!uE3F~A5x}g=`_KZye)#P@xKS4JfGfgul^{I3gY_+ z?a}(huKJ3klFP$knWJjC)CVCyXLT}T=EHfNO5zuIJMf4!9_Tg*LCm>J+^|1SmN@O?+|h^*2uC?Gg@;6twa%sr8_ud#`9s0`$c`) zDdUSEjnVqx`XSHh8(;7zscRrkt>8NWaE^?!KC@AIE)8$@_yUib(a|ruZgu$OR(eK; ze!HF*>(;F9}Nbx|Hn` z(8jd&@K2;kDV2yij=$6 z5?|?DRYgl@y)vATbg9A6wV7|Shr!%VC{A>wfdWsOv@o}k&+ZEY%UZ(v&a4PTibE`6 zzpnzvl(}Oth1JporO?uRG-F){Mi{qQt4v$0$^M9~{(t3AM8 zNgLPVMkLz~BQTH!B`!L*V>|1zvm}{pW2ZjbKp4EVve9 z-^RiYqL$%Dq;q;DUkPC2U*B;$ql(#It$yYQF-mKU8%jSe*lAZ<=d0sg3uspjfpW6| zl!$M>k{No@@u{j#F(s35wFr)`R+IKM2QpKu=0S`sr<2At#O9=B-q5JpU`edJ;Rko}|4cA@))%DZzzl@mEqq7DI z%7~dj6`n|5-1edd2g2~%l3RYKav0S7;0AwxPWqI?uCGVumGm%6Vm@JIQ_k|wEs~q6 z*?#d7ix&$Mx{l@QdTq`UnLheLlIm#7BZ-N;81DvaCmUko<7lC=PGe!vN(PG?9`f_# zr6Xok=yZ{G#K}i&zDtEf@k^`j^o)_@M$wUng&2?l`O#-d@aJN$3(sG^JD#T}k*$z> zbL8Ix{NrKe_SW?U#YdW=r$8@coeb}$$Jz?Nb}Q`hO#I7q&DTZOy{NbvAQz0MSRZeD z9S@OdD#d+JY2`a_?N+c~GzJ9)Q|L|TwX$2(XA5f&{4;02equRI>sM#Q{nyv|be%c* zQ7_ZN@xe&#a@{AX3eh0;qgiSO&D#H>h9_8-)C`opF4wGk_&3`ofnoQcp=6gzowb zDUC6m8}0#wEwezd9+<{i9YC~$N=pJ8l3r=_*nP&@NN}5%LF|(Ra#)o*{FIm6yrlQN z7b1DTmj2?y?h16Ga3v**xXJH1_2;Gtgxm39*kAaNnx3fqk8V90+~s^6pm2LTZQ57=5W@37D)0%j(?KxE$fWyj?%7A9daA*Mr+U}4&ECGc{CQ{ zKUt9!Utw>PJ!%Q{zp#@q@OV4Br)tn3^;ZeY4-N4aT%S&n2mZIeZWW}(ZR~5%W?|9> zc%!HOz$X^HEVQ;RBB_X&6~gg}*NHqk`R@Vm>FrZ(*=M@@o)^NYzbbEMj7FEvMy3se zVsnVMKT83$uFl8=!*3iTo+j&B8_|xrK5dDsR{j%H>%Qyytai`0x2dMzc{s*mGZaLf!tC1?;Xtsz}P~GOx_$ z0OmtRxQt8F0x!xud@(;OQMRZd(C316(Ki#G8Aq(N(VcALf3lqST}H<a4Oe6cfPJ$mfjJH69&#Si@^K7Il)ctI={D5~S|MrVOInSuCpJ1@=;E&kx$X@b?JV zZ^GjO^_~J&zck#B4a-y!nMpZ;_m~x){($XS*)8Ikb0~QP%+fKu%_I_RPpdouhC}HC zigNUq!8V`=#hwi8F|5zdygA2v6W?7RQvM0$J_}(W#DVR_W!`sKCwaghQ_QzE&?35C z4C&T2({H77*FzM>_!eCyo=jackwZmOWH0HwZ*2|dl@pF|yCXy$^_$Go;BIWoUi`*Y zj0Ns4P2NR*kW+Ux1~sOkYZmy~r4v&!Ip|uM=zN({8Y(|y`&;W0$du+$cSmPHvPL!f zcSJbi5ZGp2Y>K#x5EaS@0s*yW5q(=cv#JCzhVO-&nUT`C12U~i>$Nn&+A-MU` z_7-*~rVzvSP`00rZD{fdgh)H$)+Y{SlJW;W$(LV$_PXMd%gG=WKh2IOvdTM<`;Gyy)9Ga+UH{%Rp|I_4%1kJ-mB@&1jQW zLDwC_p8>uP>uK^gBuUw{9`~>1`ll(P?B<0?$9XFt>3L52by}rL;->cO0Mi@3A?KDm zYvfiLk-3>4u>%$y6?}uogJl;nW4)JCrXZ*di{74sER*j1G(%&G>lJq1z(;Rg?xDiz zYGu!33a^lNDt|K?el|^KW;n#|iQ*Hw_aEagSMeHBB<=S=vd3=!Yea<8_;0YcUc2S3 zQ*lcQxUj)Kc_0FGHrwnswr}6{Ofj13Q!_{toFYv;y8vR^$OsxiYVB(T45YDwgdZ)A zR$a$FZ6o-AC;<7`J@a6J8WCgd~;^+5~ivJF#x$IRGsV(rsno53ncmH*czaNv7brJ z$Z5bsJ6{VB{H8fprRE%5nv6dWx=r4?Ok0}+;xvgVfe}y|!K1Lj4iiMKm0AJA88wK8 z1kc_uX;dZ2@~RdET3&~KZ+({!KSyM7tQ&WfnKEDVq4`dEV>q<9av%ai?=H6sc6uA) zg9Y=BJ}OR`^$*w^vm~3ed^N?dquo6fF7`RE>iGH^dNhx6zU6hWuE-+4DdO&EcX8ui z4W6;-)ptR%yZ7S#;-Iq7IIU2No+7?!jC_``WKQdK$`JvWH@!0XQ{G^#WuVAT5IC6Mozt@Q^tBs+Rdcta9gRI zp=$!vF|D!M=*gj(#*8Y-l}9&>xz~SWwXK(4H-_xIki0j1^ZHxSt!VH%i+&_lxZotc zqe<4CJ2m+6XR(|-Tel-rEPA-@nCh>mDn+JXxO^F}9#F`e8duAv(v>ebDO7~a*Wn~4 zj7E&m4gHYbV17RX)}F8>&8Er#b}VpEJkWdiZ@kQ8%5mI1?#1awxGi_-6Lr3uwEsJ*L!jy_=!)TH?H1+|1RNI<&%Q2$frN&6>j^#Flx-n{mjM0 zgd+3@F0bSUdu15*8V>^R%px?lG^~n@dTq=2W&x0!X_zySK#R_xbRizaYedA@?t_pp0i&ODS%79z|k9nU^KO7SF?1MddVO^2@ za!62Imb^dWYp-)5Btg?Dfro3;W`y+`F)a0^K!nVk`q)juxgqy@dx?6m);k>aYslB6 zewJ)s8L>h@f z%H9h{cZqBn@e>9D|L6giiw;7D^=UpKzt@W|w|n6Y-jz2G*gH;_Fai~L+xG-e?q_`P zv+CD7d1%^EX-3Buf97b+jf)i_?b>j?z*DT46GK6KnNwb(MOR|$EJ7qam1OJo!%T;m zluj~ApK7Z|ccXx&R#HLHrO?wvxnbUyMt#W%3y?X%^!}x+Lu4=3HOds>SC!~)m8y`t z)O+;?bu06_bSal2?Vo8npX77ZBtkGw`eU+aBAv5ieGXI{+98a7K)vK1;#!nw$}2<* zBBM97gm6fp!=AbIWg z4cI}v*599RS)1@BL<0CHOVai91YuJ{$7x}fpS<#DAS!XBS>Q^4=aD_ipU0Z4xfVN= zuatgll~6zNcqk}hS)GTNZ;zR=t{=UVuIw~C+2`j}k{%4tIWyiYpL;{yha4!vagiDQ z=5M0B!HHEl!_G~RbmvIK`#u6`M8`A^`&qDJl!I-Wf-{FgEqvv}@@Vd?nepg=iLFC> zRw+{{r};lN-|zh?I0Yd0)PWojU%b8W7MvaikeO9&6GK%w*5`SvgC~z67p>5Dt^b%4 z`0;*l`icFa1&X-Tp(S402JCm#pj-H_?SZO{M!q@wNA6BUPK6VD>r2JI2aXEcKwG1} zc9q=6Y|!C|kOKoNoz&x@3eHyVY>QrlEmWHiszIg#7AcxNYW$3^t_ovVO229zH5~6w zNRQB6ERXgG)6YE_pFt1NS(u^C4g*Axa4dOe=(eu@={$*kg_1W|YV%Xx^QI$(&HUkS zN7*q_qlVp^KaM<`Bc81YPgF116BE8(ItEVwUyb_7xTxP!MwejL^1^}swj4Z^AI31q z>6ht^UxsD50rVk|-4Mj<8bZjV$Oz81?mtd3#of}grS%;G2uo5eA;mY+78IRyfbVk*@=2sK947Pe#Pfwi688h6mIrVErmuob}b3TtF3JNA-w7OdYv23hJO(;zbqcFxN3ZD09fJ&-pFheLo*uG9~?XH+erm zl|Aj&(h(4=m*WR|rOvSs@_4UWfjhtNB?qCfh8F2Htpj3uwVtJnSQ`Thd=a*8rPV`Z zPmUwcd`pT~&+Xd$$rq<31+VFFPO7qGD}U>JgO3>eueQ8|XAnxIYDPO0kF1!avoSUu z*Kb5s@l+tG&$z;VUmQN=Vm3+l*r7c)Z@6c0@u#2aKDw1Y=f!$2R&cq+v2M7{eo-Rb zu4?vKh|dvMkOGu(dT{w>zBQEzZ4P{uRtYm31#>6`!cp2MZ*)V5!fpiEdXHO-H+&v7 z-8adrq8DT)d2ONj4>`q@<*EfL5(wddziib}xDFc$!=Y$pGgVt29JCA$=?kPMata`V zAb##{%V(=4T7l$Z#4oi8nllXfvZsGCJ}-jRy0o}ppBSn4?*Z#0XTc)x^zbQ)ZfFb` z+$|Qha&M7$R5%Y;OImmrl8`;Vc9rva1<3YqUkj0?zuJKgGgJ1Y9!`_@MsSxXhBVG< z?hn4jbx&0jqB;?#Q65)aI7`1cH>T-ykpA)<_OM+9#r zr044Y@i`CA6JHv6K;X`GeaGkX{yaPi{5Wp%f%`Ivd+ZM&m5!uZq>puIq7piv=VQx+`w2L{&?~M#}xX%CX z$$5&FpP+oMk@my80Hk?YlAr=97hV3av1P?a{a8s>_+(4xu=8%1CzUj+cbEU|{e@5T zrfM+kKAv0=auV+)obypJV~4b_C7)Ft(@3k$Y;;ECCZrWcH(%6qlvj`OwkwP=AWTyX z8%>bMn1Z%4S8VP`D`hXpe9{ANL6WGj*HdAC;EGcH_A0l|iWfWOB;OQJ{Z5OAb-Lk@ z6@p-u$&uKK-t?(OB^xE5XnUOYN8_U3zyC$$_L`($5DoSdZxBCv`K%a`LpTU z_|illDY4bQ0+lpt5Rg4#}M^AZ^5`lO6{sP343o@HMhIqQN-N7A-#!#kPesq zLB$VD-x}t=Jo$E+*_c{vLjE*TBA>^f-yc6ud6SWEk1a5b*z;h=)Oc=Vc_&vCr zj=^1!r|&e%amN+!3y%8}*#GVRN%h?^h3V`ClQu}XWJd#T7}S3xvgieKkB`;L(3LUP zK&0^GiCE{!u6R|v$=!wJ^Ug!D47_@_+I~Gnb~o@i&!l zy?0Y;j;a?LZLelg1OlEv8%A_gCM?(IUvCPxK5L*@>uEm77gX>Uj+)jx%jSy5Mz0O^ zx?=NFnW2W^Q;mXFzm=~UF306s;vCeiqQlMdwTq1@?8Wx(wTc}#U>>VUrMe3W(rXT& z74TZH1kgU!zD4)CGLnk zdBi+rq&$dG@WHC100TnuzivQUbn5lz#k~P@G4k*|w@)Tm>A`HPYZYESX`1!KsxCjZW6yPIFHk_Xj`J$*s>ArS-b4Yz}Bw-|#4MS+%N9FEVmK zT8!XP?9jxXYUdE*)IajPV*wAbHWp@zLR?qQaJ920XwI#}zg~=6)o&tIMJ0`~h?nWG zE@u6lux=X-Tk;Tj3o`JD9ew|gHIO4Q7uiZlTO7D2`e|BxItJ|N)?;~?RNwOD95MPo z*ZN>hTAN6JMtm46GVq-tXnd?ThwE(4bCN(a4L?lge`CH9XCB&66(RQ>eEoog@A&m}pp2bNE@ zyIR$jhX9*Q_*csulrQ@=$FoVs_=>*|-)P=Tf5|Ev8_0Nt`)2jxyIg!)gP#6zZ)cKp^#dJ=5Ynh4~aF(!U!FM5uVhf7QvJoWb$2ThgC%IkY9GC=RKYtFR8i29Or^Y zNLMFtr1>AYkEZMMnKSSR`hXQcy*;UlVrQUb>ISWXSRv(&Hdgpwb+j9&hH7)t^}_wg zmKn^Y4GWH|Rh$4_@1|g2QR^)K4^WAKY{iZFob$Wobng9|zBx2?0#k*qNsNont+s<% z+=4selT*O9m$;jM{UiPyq{A&3e1-(LzP6Krm%Fh>~Z_{VHwfm#>yG&!IZ(^&A#@jEW-uBe{h_pC3&X`3pXT zqr4r8HB+cYPwY?Hzx&mHz5`9p1(Ki}CsB2~H(h8!9;dLL2OPlc<~F)P|R-FG8|i`nrQjoUi&XJ@RcxuMf^wkag-Z`u>>nUZ)lt z(+nq^K~m>O-Vv)FUhT1$QU>xxl+_8LuX?z9^oP|I{ z2S_VIok5zauz`%fJoD}Cx019H#I$&HBpP)kCdXt@Nb+R&NPX7xWC=dKy=a3s&)_#J zdppYe%Gw)_^icG<1eL!&BxXo$CAn($yP+B!_m_vKR9|6y{dZ487Ry!f(^|xLmB&Cp zk>(o-PwCtxF?&=!IgzTP`48aYp(4WXT}~N|tPyNhYq3IOmdZXSTAz11b#3j<@xh2c z098vt6x+S~7;gb_9HFWQn2xJyJ65Z~dcydEt@A4G_q?XjW-*vUC`;Z3nSg-knITgr zI-^2gqm=#>ot?qos(%|*@@3*21^3xqJU$4@%}aRag56<9)L3 zF@sX0<7d-(PHI3DC{T}4>gbyrjSa}V)nk>gZIgY!l4pZ;_K7?v+!)+Q1sV|XVcg92 z7M%Am5Z=d{r>`S~O=kgYBW-ZLBwJ+9t1<|OX4VRJQ20Y_&@yxE@Ecfyr4lTw-d#XL zthO(#&{P2c{EvFr)^j}h(e;;s{;^}y0joBf4Zkm06SOO11lL3k#NdXm#}FLdyqGEc zTCe0v)entXD3(@mp0^IE6HlqV&ikmxk6iS?xkSVkPBW*NJV3b5(SOm_)e6V>HHYhm zm_Io>V&<1?eE6Y>q~qaY4J$^ooz3i;PE&AEK(g+c@(h2x3FNqaYPU5UKK}r32ybwS zbIt?5Rx5$)DQy)@=kou!0d)wvfj2Ez+2;Knp~?0Gn6>i@JUkFkohQJ|IdUHaD0g!` zh0;Gmiy0QTVkw9G;ZNJc?!p5N@zBzr9TQhK*%S3y3@EoQpnJL}DFg1vNK|Y%?~rj* ztsxa3&wJvY&)|mzB!@0l3Vk%>3x*pqwsA5wl0LY&Un8>$O*zcSH7eFn!HiLAl z6gm*TU$VzQsRxsXx8Q5WcX~bIyzv=H2vREL6S`C+-7MLF9QxqVn0!I~`@_TmL$oDM zhs)_dVa~fUHV{b6s_9tH$6Ur{{kov|N_0zrNkt>zGCtU~w8_zTv~i=;U-*=Cf-G*4 zi9tLOxG5AUoTfUfi+xq;PHz`xX3yS=CA_u>(d))p83)m98^;E zrPdw+V_@qx(#H^mQVX(1(#pac7!6W#z_3)%#3;J-PK z;DEDb3;}nrd}8@-YB6`UfQ4?5Ce=yrNojbEm*(clcWy{U&Ezl*K7T4VyU|dTuptBO ze*egmF;Snv8$}LZGcwjdI4L|9qzwSHvY(5@(-y4CmbxnONvI+Jc}q0xRg1Y&%8zj{ zZ7hxGtq!+h*FApQHapZq_G#WN);`P%O%ZqG7a1r=>?$L~*N6Jx`BaxDy!6O`I}P}pAl zf8@vLm>QtZ>Zjz>4uXG~#w_kZ9}*dWzR_dHR~Wf&EevB|RJZ5|5mAU;d%>rx!u&Tp zTG7rAAp5p>euhy-*thcS28pVIVV_$Q|M>8E19pXG4aY!1bG}#IgR2ZG?PXp#BkXPJ zi^uCd_o@mEE{K_p)uGU}YHe!!2aD2Bb0;8lKa%-0@JvzAdHwfEg{E!q*ftkloTPT| zwdu)*gMLL?u~2b@7Pr+>mu?JDRz&%NElf)sVCuEVBnPp(3~=O3?}XUBdLASjdKUiV zE?5@EROxI_OrUM>t}}!~D>X7`Exga}6Y4GQOGi-oOkV+x)fzd%xX=6~T5;T%w)X?Q z1Nid9NRh3ufN@?Gmoyk`2>-UIOfv>h!ML`V1skDB<|#W5p~y0EQ+@!Y?ODM$xD`;A zhn0qB?o2DlIG#^k<5(1(G4_xJHIKi)ZM?dS9A3HPT?c z(opf<|Co!N&8gN|xsyC&{Um0?`Xgf`)R85!rI2zTQ?JDN7|LhzF;6^R8b&B8E9lpv zY5*g4X`B&0Yf?ey0;E$bC|u2-;H7tqlZgfN1DHr`+D#J%0zMZ1-%%om`%c!8U;l-P z$@MxHlv2<@)6^M)F%qx z7O+-=Xu+{Efw>g;Wyk$P13B$(l1_y&XY8J&fluGN-B!HYjxOQV;sNwg+&!L3dh*y| z+_UYUgqVKJceD67;TXsE%Hd()pj!kDNapW2b3S4{o{yZX|@oVvSyM0u*op2nTO9z?(V%`E82C2rY%*A#}4)JoR1!dk5 zyIXx(=#wW@_ysEN{ZsVQIQ75b!JH3=aVT~{rGSCp^={c=ec_g0KZLDZY7FlQ@C$mT zMXDVP3K{gsH5zvjifA?H* zQv*4YRLsHqB?AN{;W0YXEkpZzVQK(ga>@cJ8Pyj_qWyr2XN;kq_MN>O)2LcLn-YpT zO;V614|1(A8K{%I+!s9P)nJ&Ou>>@%$89Er42nlvocuI@)iodb8!vbKneVWfRq0Hf z)AL9t>&fIM9?VawBiHBfjp7x<+C_&e+thrHrpz1~J2m*4@AV;MCG64k;AF9m)wbf% z)n#Rh>*pC1-M{JgS&=ME2M=j25OJt%zXMm=iz_q*n9ijzG4mbUQM(i%;za`IcZ1M) zmG8Uu62O0_k^4A#R1HXD8>|{Ll3MU;bYUdNd2x=@-*@2o&My~5o{(dK$O0PX1fwAU zyqiANa?%QwxX7@2ae1@fO~vP031U)k@ZHv=*DuP0un99>|CZM4&Z>P2Wbc z=Qb1~r%ujBAXk6Y*njuk+*5^lZhM@7B(uER4m{-UPX15q(_U;E8Ji9I$BZcQ?nP)i zZn@YQ#GV{E(hs{l)8{pmJ1b#HR;k72Hp6XRkXm(EVJIE@!#E8ci%}&QMhBZ!@FYYh z-%}vYKslD7M@3beyXC(YIX>?d=5@2OP$}p?Uvka3_wJwP*1-RBBmdF0xNZWU1Mbps zLtH1P@9SDba7SEC*2(4}CqwgV{o!4vS@YG-c`vFp%*3zquEs}~Hjmajm0E}Nnht+A zX~<6Ag+EUK-&=&WvAKzRB4Ax)jrizWy1)NyZjgL!N=I~CC?r$aBnsoF**po|7{Q(Z!F#$&C4Q9b!IMPR0!<>0djcuTAG~*~MW-0%~ zW2MU@t?-eP@Pq~5_@Kagy8aBtvp^jp-6$0jY_rWZ=RK=!(QF|?QIL?(&(SD$uQ>=! zpC|p5pqk4usP-&`*nT(tugGvD?=+=1lnTWCx^P$q9r&e-0{FqX09p+MDoBPY+*lpz6#T_N_1hKtIJWfYmK_dtw@`Q1^ z8cGS028={IGT@KC5g=qlAOu|=Ci8vh0+Rw_r^sl zZj^Vuuaa+;dDhHOoAvS`p+jgpm6O$B^!~x7Mc^qQttV%uBoscLWL~PT3|$KLzv`C% zVAIJjJaeQ2ziIZQ&8pGc8^H8Zd}TdI*guxO9RX=viSpRQo~!>T{#7~8$k_e&rImW8qINu)3=UZlYP3i%wC&1h!U~5UBj^z8y}YRIWh$~~ zp}bjMjSke6slh4!sQ#E$_R~OgjA@>e|7CL{^x=GKuiQ<^GhM*PW?qaXA$L$3Ho@u0{+8-2QYH_BC{*X9SqO?2D5L^|1!x4sVz;Ij%D~Y zUy0iL4#F0**UidnyBKFHulW zswFoB6uEe#Ob%bJ{7Li2n5ltHpP>ZJpYG)ANR)F|LpD)0ryCq?nU|na(T^*hBnf2s z1Q^Uk^9*_7RoI6AvmcFs7PGd-q;WA51J!ENc>7xTmg|H? zi!XzAXku;+WmvnSp4akn;T~^TIo9s*VBqbOZ@!%VOXb5RHCV-TG%1d7p!hh5i!T!h zaZajlyPP`vKIs9R<-* zp)V_%a55&?cK1mO%HJ}pvp`u(1-O3c>kRPxW#~6Xwfmim4p-@?OA%h(G#U7XYMwBE zeV;FM4Ywb!OL4Ri1uWzdmFpiJn<+|7?H@W>_tKl85U5;yI%(wS$_#UoHFP-tbn=wT zDTAqmy3{J@y6NkN)H;W1xk5e12^Rgy-~+>3e>9Rv%5IY40Snh^ZL4sbWK*nfqx0d9 z1FpCs50df2Bf}~-ASN`qerx#Z{I9<=MS1$)R_tWO z%O3}muJiOCeATh}qrt~ZpzrULSntjXcB-6T`n@H2WZu^|`eOamgSVd1ag}wqpHPy7 z2MK>Ib`zNxG8Xc2Bh?&6YY;d@*)qWAgC7dw!mdPyQRR<1{l^euGhSILBA0vF(9FIh^}F zytlmS+`G5-0na4N6SsPuh&bx z9uqHJ8gg>sSC|ZszsIOC3QMWok@E%}V3OyQC}<6^WgRiXAe>N<8f_ z4^?%mU(QsA=jK^CU~zcW-7*j-g6#6;(DP2Wa9b>SGt7;-88B70<(Ww0LN%(;;JXI! ziHm{TMHS4F?r%Q_Sdh}f?_;BCRH%ptIRDSXJ53$2yrxx+RaxV)^RLA-E50wIeE({j zyWZ$sj8Ws?P)mI7a>Y@t50?88JU7xkL`gE!JE_b?OjwO@t^&GIg3kD|}GOJ>G z%CDmx_oe!wED<3gjuhZ_M`E99Oo=)OX^96$PS zA2Lu$Mth%z%+;SN64r0zrqjBLJw}9Or^9wBcYWO}6XqT_{^9w;%%joOot418&FsC_ z=zyDb+1Azb9!`WMflnkfc1g9=sp2`%W|;?_w%~3`p`dSUsR#PQDrcm88Id^660@Zy zO_@h-T)KjIfY=pL0qxti0ayU=nWMKAuf_RV5t5pM){szYoJ- zfPvj4TPzDZLsvd;%sC6HzGUHTp7Ivplz?bT6#F>K#x&z8$Y}^4B)EttT@=6JJ9+ z1wB_&yb`_IrW?0trGJ7eHNzV7LP*TZccz>q-P z@&k@`ci~LGrw z|Hi_KH15f!_q_BzqU;zU=@-&bV2$Hr^3A;o^{QdRD z2@1oXU-Pv)lL*%0 zm;92dOCfhT#xHN@GLTYb)J@c>SpG*r+gshzu!PNJ#`8hk5guwv%nhAL3 zFbEM=sKD%_tgAeX#Q+yVBvx@)7$zvrY8EL$R~iN-p1vYRMs1nE-eT=3delK<(Jf&Z zdnQk)yufgFE>POl7=>n==TYadCbdQHt-v%Je@I}&Ir3Muy(Gih*qs-tHp6e`nEZ7_ z|90rJB29);VS>+h&rx&)!#Y?Qr|Ez(6Thw2IR+(BG28i$ENdlQBggG&cm9G3kkBXJ zesaYKn~BnAYTBkYlzL}ace|-%jwXDqQ4jktRTZ>~ELtjEvBvA(A!!qKBt#0jY@eD# zC=>pUBCHj*pS-Togbx;)b%6AX_^m}5=bf8`*EL-Pa{XIJi92Cw9@Cw4X?#pqcedRb zuKzszDPGay>7Uac9KNjQyJZJr0K@Cyr0Fc-`xjQx?w*AnFB5|I!ehMP@a*(3IqwWs zA|i86+s=FZIlfM!+=p^Tb>1&X&XSU;@vy7hCZ_QXDx?_ZB@`SYre(y&aNn^>|+IKic)(j(5_;5iiRn8PLf$TbeA z?$h{+SQ*q$e2kLF96kpiUr0&Jr5Ysyv)aODxd3GW`EmjlQ@gIHV^j+?MMlCPtRy}W zC4@B?!P?WO++>U&^wp5iX$lp3LJ8FfT#%fCLMs324}zE;13x%W<@a|%?!|CiYY+AQ z1G^T@1Gnw9`f=1cq*J9~h#^#Rc)3*Fs%K^-a?O%6m2XpNDs03eG8oX9+&ef3b$t1Z z#V4#n&t|?MSEy)RtLfm5MX+FeIPzvu4Boed*Wpxpv$cN^oD1%-Jm|XD;3Do7;x=CB z%ZvsiXW#1YV1Ka3wj#5^!8RH2Pc1M0d%O!Ms_ziSF){?(D1su4>id$mwls-W$D2ai ze}Lt7#>|58)Cm*2TB@XN+1MS_0>9zONku0E z@_OV=aU-2Xx%%g~EbJ_NW%%!s9>QCb}JO1&p(Wo^G2iFQ`Y z;DnmCF@|a~=i)WoWJ&KRu0^N=j@9obn4V4ld8TUw3sD_LV`>JfI6;RC1I6m=6n8d` zeZ>4mJOHMdV{@z9DgU)QqVJ&UZb-#{f^YzD2A_v=wx3T^J$0Gq?Y(EHC!janJ<#R8 zlC`Z{4Raq4jq&a5`RoGTFe6E5=rYk94r%sHG3Eo|j4MXr-w3D265hIlM?rX6Mb=1H zRw$RqPMMO?LFgA~b*L5TgI=-W1fw^VL zx}5+!Z!W0(7EcD&;6hkZxVgQun?sD#a^!C}39!hTc}t%7-VPGRZu=JDW$)uprEwpK z5kl=o0Z~~zrapb=e(WdFb?7C9u_z__pHL!mw2Z&&?AZquVr?0-DE-Os`5@fw3L+~Uw$tbqIb_;xip^q3|}_PxJh zAHjAcnHPKq8a`9P2=HYS6>x?=!qGb67rsLcpMrp6f0}LqqW@dW`IdUlZ@5py7VwxE zn&ja;*tA2V@R|G*o+Rr~)7~1j@E~8;dK^D`9Bg|%6$-g#UrC1x&HS>zPD>zsszboc zFyy0LKfJ>;dMvWLk`94;x0Y(Z{ z_5JA;S$u*a@Ay2009mX5jTTA;_*8uBte5y>_^Cv>;RSr+({E?TmxojlnGj z@WF)3bs(nQf7({9N|2};chyz_t3;|cpwD2GK@f?F65Qmo+i5Ja24!Q~&Bb&vnlN0` z7CAsCV`Y-v)I@GD=D{1>@V38@&KXmRv9#gji4jp|xDMX=dR7TDevd!?G)#t8FbeR! zf%5Kj-qaJ6+M|zR^@&rmx8_F74+4sgRm}Bco)!%FO)1>yh75QR<~ch(L`BvXy$n4j zGF-oH{$&{~%7o>i^0*I7$5SVOHWgvWn38B!e5{ubFbI8mDhz0vB2Gbb4C z%n%_K%Mkh~$d}CYPlEEH=O#@B?HA{51+aR3rEw9_ZjxK-LI!{3OU+*Kq5nuM2Qim1 z`8GCi+V+h}dhDVKa4?h<5M)4nH^Bko!+G{U zgZxz{@$eh&OooV<^k6ZXrZsgHAO8pr5k>RkG3FKdfq(E$lF#5qWUP~HVCs*pR+_#u zJ>BM`9hRxX34V`1Lq(16<|+n^&Z>occ>i@*#_@2Nsj7O}Qs&sT^5z{y+cyj zM&|t&7~aK(DnQVm{;9bFu>~UYwuGl*m({{pHpwy5O(mD7K3;~UhGk2*QM~_)(`^E5 zKnqYl#=jwgsp}WP#zCCQwh!F#07h~wx>p*KF6}BeU zg&wx;phb4V?i}h*e@10No6O?!f{d>98w^8YSc~7@n_pfV*FOBZm7rK(ndlvK`sh<> zs8~o`FPdke!+{dM?>xbO}HzB-RO%I9B@0(#`vN0Os{V(d?0{V8|V|W3Z zNt1s?kiwZT%YnXH3il8pKT=*YxbDd}8PGbj=?l4K{F7{wIrD3uxL3L2bB?(;uHw|F z8S0UDWBths5(oI;L-5@%)xpO z$^kc0;~z_!mgIq++mYmx+GyU}<5E|ZfUk;X_U(absf)3>3Yj&{Xg+?CRR2fB?ARkO zPDIMpz`LQQQzu0PtR&}eG=?~!kBQyLp+gs{q_;CVg$--dU}=D|*a;J}>0RjT$Xgrx zMV>ilb}R7;bs$&H8u}>ymQbz@#2QCoB#lJoyc&tO zL9sSIc*FeqLU8GKCh2+QA0>tHivoyq?G^QT1Mr>x-bK0aDKph*?}1CER@4fO%wec3 zJpo2}ZNA+f@RhA&TA%;olc+)ENw~8@;8E6P*yZZ+PBWBwzb1xMm(^%=LZ&gHB-7eW zHBzqXX1rS72&A@Tq-^jIX~gl)mo^${GcQs{PbZt7TLr-d2VV-1a^P}^%#L?k`*I&H zU?95-M2ZvJ_h6P_OwvClR1iGoe6_y-e3*e$c^40@powT$Km zYmA!Cep6g=N^1hxjNahLG3!26N(;ZylO#Xhf|YlkuP>cqyjOc4^8Mjt35zx<6A6ddnyt@cj-`8#!_`*j{llRO|>L?PN6{7o}lmfg_2UBBbzD3jWzLnLooKM${aNLGKZ& z{3bFJ*!ofR>tR=uym>+kUs|o@!L-Pv;f3~tYV?(i;^+ZQ3&uaqkKXs*ka&kuDf7BA z-9K1^NKigIu$p~xHt9icWLa-65Mh85ivX-cDl!Z z5Uks?h-84K3wAg!kLe8Ldjz+>nxSNe$cU|7qK3Te?*3&EfgU&f0uT!d_r~_hs2DA6 zmHU0Ob}BwuPkcNq>3irSFo*(pKEV>q`Oj&NDm54kJsvZ>WLJ1N*$m~F_cBJHFR*Sv zhB)pck9=+IifZ-}CO^7m)7jd&vJ>FElS~{y(XS%szi=Jb>K}bvP}#kUSJ?@|AAn3a z8)PyT7~P{53(AS9sC`$2VFSN{(4?xQLG2$WF%gSOxG;f9dRGgAF|RbnHc7*(gK8Ai zr?}$rSPB>s@sXsXZPaO$?~|0Zj-W3#?D0g>MV2+HeQi76d|w)8yiwEV_HU!Y-e7ZG zHp)TT_Jv~WRv6h0OhIVfj*{7po^!4b)kz|21Aj}or82qGN^RFqx_luexyZC8*WO_d zX=46(-|NKTntPvlsQUxoIA}(NJQ&*OG4cuKCYJW_TZ>j~+zaLidb?Q!v)FQk=&+-6 zuaM5riuKz~rRl;ZY`RABj+>k##P~({cQ+Yx8Ig8Y}B$@wf5KMep}9n8PCAxl45rMG5I5#V`)CGt^`N z3tXXa{f>|LFMz~r5kC_UbHPhGLJZG0iyprC9gH2AUO4<3Er&-#m$jwfXBt5`;|VZa zrr6#^+%VS~QK#g|UB+ zK_oSbf`!-t%zWepsD@>D-u67SMIHo2OqloNXAMK%d}-W)b7kRkG_^28^kF7c?Cg3s zr>-PKNKMM%k3=4~z8$EADgg14Dp|a^aqCez|G)j-=V+{7Tifrq!L-nenEmGWO)*mQ z+K82}X)*d*9eJrlE`j{5c_p;{8;IbIV_4@a+|wH}U$JO!_Sr`+x~W?3_txjw5YihU z58AM-vAKQQNii8|O$;6|Rn z>rGJALbwz;ghZ^$^i8mzBbcl##`Ru2Yyq9Fc>i~hpR2zW4|X*COPFj(jCxl(@(sjR zPsUv8z{}m{1l?d0gE&J;wSf|);flBhlfM$I0%9Kx0wk1 zKYF5DegHYw0;~AbeK69y(TvNFR|MX)h|=O2?W1mppZ*myFBUb zzTM|2b6x?grve0lz}wV*474`gpjP*? zF3OVP+^~9KeykRkef#DyXSFMx9|%)7cCmRtmSDtD;JT`$ufUB?-8q%+#UVl>h`vaF z?9mTR@JASFn^C+4|9gY=M%yW*!>W~i^}h%b4h@{6p4aF9*y!;!Jb#4VjY~Umx1Vb4 z{QH=dXRcxMS>L>&wz6vX^9xN6r>wXQGOPeOk3t`HcUMm<*+{VzONjJ=EkWxZ`I|@= z+HeC+u6P)`pLRTE0U@j=3)H%h`|-aDRoFyT(Q$YH5^$cL2BE&DQ$r@Tt^Dl0TOkNj|p|^npm3Ecyd*ADr@E4VO3Nk*4mi5_7W`oNp3CFZ+ zXaiob&I{q;;WpSeXXHqQRoLn+mxu!j^@00=*A|W`3g;9i?#DBfoF#nHk7U;MzYVO3 z@H!&l+J*W;zL-p^J?F*zPe^_HU`XPtI-hujt+;T#VKoQ*r-GDv!W(4Qjcl4Wct?wj zF-^iCQk7;Yy0LqIi=JLB4{VNU7vTCPFqqQKplU(&1bti=H8%WF>`bu9r1(hS$ETL- zArC&@?8-0QR)3n7lpw?Yiaoel@K^yg8lV< zNIpLsZ&En%!r)cE=dfw75qKv z-W+|A@Ol8{W~?D!(G1+UxtC+DhU#q;6YyiwbQ$FJU1Ov0oq&N?5dA za(~s6R%1cVJ+%`de%UVk+1Plg<`Y(4gn5B;WXT;Ix@Ht{r8L1;Z3Y^)8q$w68{lnb zzcuG;hx{@A?P;vZ4U^_DT}!Z@Xd~s+B#{P5<5VSO0K_7-3r=ZNeB!(>7DzU=n46-UP4qU43hQHeyPTqbkU3 z$YB9Bf6=wa*(Rh93EK+hl;1d!5Oc6a*I6rTIQr7c1g^5nN$tsjCs?dTX`jEg2|Y8) z@x%ZZ^k&17`Ux}@Oy#D*H41rDIJLR1vWSr2t~ zlfTFb#@^&tEjs^1qZgmtiT@gMY^8!Bu51 z-OCj)#$Wbee!Q+DRhgeskK*Kgx@pchOEu3!UGWP$=9H&4V^$haYIHv6RK3)AZP{i2 zi~g^#Z6`1jB@mp<*1Nl(qrHmMtrfxGY|;nTd94tOWmVvZQ=XfUQd4h zy`BF>10H`FF$N(gx(uuF-1guW-0o=WO`!KgBbD(fTtx0ZR)WX~&f-c?VX)YgT>ng0 zdW%DF5*fU)>>35M2E5GpLX(>QOxJ`l43$sOzuqiSzLCzpgiF$>bhrlS=JC}DPYo3^ z@?^qYO6>mnL_@ypaP+WuR2Ld{hr)6^odvkiwrNB+k29f@)uUmYNC$rgLJq`dl+2H15VYaD8%)!Acwx97Ej#rt+pr~qF*rTbw?%HLy3}xoujylN zFZ0-UfGfn6-yICq)|J@8-v`t~Q5Yw*F5Ss0E40`kH^!rOD|<>Ad#4_C1t_{QIeQ+D z8NBR31+qdyiUf~6SiB@noBZhX#yoyskahY{18KO?CojkWTfhMpj%?w(R0eM~!moFt zUgoTm&oNNu){0CgQCiRqruH6KV&?+hAE+OzBm`sG$(Xc71QiLffv-VAWVv%f^uKo4 zdFSj(jUqXlV1f(mKaUx#$^MpCz^JG};LU}L%o=4J$Z5RSf&T&e!n~+H|HZfaQ&JY= zNAP2RX#U3S*szr?*=kj#GNcvvZPq45LM>s}Rge4C0O^$7=4Lh!k~kR>TxE1o zD*59CbG%6AXB`g%C#4Ur6LmiN^Y!{qZeFA6MxU)Q!qLT2@(^QSQ8RfXT?H#cvy7oB zLXNDl^u>-1=El7FS?J511{i#aV3A{p*c*e9MjwXTZ!KmPBUMZ+#uUy9BYCG3;F$EWsay6*|^()Q=X^@$K;3m+B6jU z+l#G+_)7Lp_Z?(cW2G# zT;WucjaO38xWcyAv^rrF_joo)Ht5&bk|nczV%gHHF|yIkq5`kGbJGvU0SM}{9n0v& z_T_c==*J=@VZ2C(u8KBTxv4T>OH8FBu3z*WY!P7h;x^ocl^88!3&f!hNO_U@_U*u* zp|LwCTmE8>Hlkzl`YlQ>MwX^Jzk2g5Ya`F`)PPrign!k|d;OQL`A1w&!aJPKi}LIb zyVm@ebR%I6O<|4bv0{3vo3z<|9C zkR2)_MNi(w`dKiQJb;t_8P?r7i#J3n(Imi3z8F5nU(5xX#^gWYK!IcbMFg`3fwG7f z>I?wOYBu4t&^0gqi8Igw-s~z#6CcBc^@OSekk?UYoT< zF_>(`Ee6zDluR>#|3Y*6Ns^oKNW$yFR$Tob)Q(l}`zsE`M~h@!%;U7;+Pm;}dJ$lm ziQRAWxwR+D<6Go58RX(^%r)>#GSMcuMOUHgv-%I;YSO6Y4{*Ny^FP~cijU$) zC&$LrL8FUK3lmBi{UHgZnhbM}K-k{g+G9jF9Pk}6n|<5{mMH?mKEEJ4U$EgH3^UhE zCWfaDxB89zs)HakZIaq{2+`Wwa0(B5D7L2k%X(xTK14Xf-dUVm9Kg0eY5ULlgkf)} z;@u|j5-lRX$rh0zKhIa7RI)bA$L{yTABV=W&`18p`@RAbsvNL}j&8sa1ED_nwOHrl z4Vq;4YGX$8^j>c0W|ZJsB?Cp-tx?;2Hy7+#G078+snlHHIPT9J(&u%IJzna$kzJ2i zFE67b`0(vzwfIBtaBD=gb_Lif1*+NjU)21LG5_#nv!SDwr`DRXKY4iCYZC;&gCWN|+0d&Kv*-aW;ng1aq*{kDyc|Ll^}UnF5ydzk9NLXg_pKbz;5) z)96zH%Yzs#n7Ew*25grb(Movl2~jeD_9H?B6(BP%*0&S3j>n`0vKJ&Kwtjvt?9Qad z*5Z#(#EXx-$&vMWYN?dgf2_>2_Fe+}mc3T`U6Km&H-VhCKwJN>VD)Otm6QzitxxFh z`7S=EN#S?;yNrxYqdM^ z@F#{Z?9biE@_380<#i8A^u4ygDvONaGGV)bcl_C(xB>y-p1Vg1-3F0T1R1=KkeJOt~02m*MY?K5Kp(K#VXmmWu;b>+2Kg_-7UsGw^_3MnINR5c}l2Jqy zP${Q;yWg0gvB;Y+;O|ChfKoSs`JRQHDW+Xb`RjS!(bfa>?U*g#JHU`mR55N;9f`SUJK5m;b}6d|wKn??+mEB+L;y*ludS3ORhv1F{@SdK6~8qj_% zn3{g(ZzwZ{YWpnO^)on{{$wYgi%~foSaz#~aHSwn|J8@kph@9yy;E)eQb`x=sa_>; zk|B1b2|c=DId5ZCdg5+=!Oj(+f{r-WIzS!Jbx9vwL{ZSSknh##N1Pw|U&3qo@At(_ z`O{o?_7)7Q(gvCCUc#Vk1T;2$PJZV;nD5cqeyUJZARo^a>4VMYIYR}v1vZ>Mg7Q_U zwqEFD+7L=Vf;#~ouIwzcRRUO~8lhql?Xhk$Evv;g-WH5G4VWTdlZ-Azs-8ATX zUE}Jz*A;pF1|NK}#^wW(Y3z_r)BV<3ykaFM87aIzS9VO;s3aJ46TNh-Fw<)3dj>aej4Ndv_?q{aA`!kWTzc>7}odV z(_M?gocpz*TXmmIvT8l%!hZw}eJm+GqPy{TLOV)R)vsEqTy(6;tEDd3+(CAf=|8V4 z>qas)?pa)SW^i01FR%hutUGyWe^SSG3O<^BVSl@Lop>%c27s|#s8$lqDnSzPDJ{HI z3d`OpC%jH@r{L^0hd-TC^3_jK4o~pDc0XC^*Mk?fwr|91!o`s4x1x zreY1Dr<^>ZTbBVu1Vi7y#kH46t8C{;id`tRjG6i9Xhkc%##<2f%gk7 zE>wj$G)xwU*4qjx3q%&(igdfP7SaK4qCk@_6a?u1@Rwmt4Ap>f>CO5lV@$VtJDJ_J z;ySbK2Zg@C!}EH5tk+6eWdLS+rsny}azwJv`mTwhTPWYdVpw>5mxCoqLWj7tH1y9P zOaR&xo%bqn$FVm-Are5Ks`D2Z#huO+%!NhGbW1oUklRAio&d>&01ye0)LLQQqqAZiOMFrx(FxSje0}O`^FL4AcN)ztFC6T}Uh9E=L>(%L&J8RI zLR?C(S8DDKnk|gVY3KG0u>2P7WkBcVQbIC}w34*?ICETE)y!M(83ATf!Y zZ33w1eEhL4l~DINILOi;#a?UdRMPB;%IG@FU&#a^v~ea`s&&tlagUS{!P5|Y(Cpdv zzz4Z&(Vn`4DdMLa9Qt+_Nm*|vUmw$@T7^DD08NJ&cDa|BXR;4d+@f8=9%~ttHL&7r z(I4$uc!j_Uj<*0B2!!y(Dp3%(_{C*;qPevxS)h&$o&I@)uHP?<4y|>iI&=&*eUQBF za4c6-GHpm7Xe_dBxu<=I@*FaxE#LhnjmDj`Nn^(J*{H^E~$1E;8hY=ih&gA-7Yl{}x$UdNm{V(+fPfw8` zuGe!@Utw@qqt9PX#C(9SFnHJ93jPxQle;1b7-?l~75Y61mY&u!$O=~g?OgsE%*h<+ zdTp#EC|C2EjGh4ij{Fsm>*q~XnXd}t9(42cJ#cMS;A)+ZH7bRxcmaKKF>e#jcW0{| z78Gq%aMsC0@^Rr={_=G1+*T^`HY&#r064pT68eq6d+@S|2u=w9@GHS#r1Tu-$u-bB zU5WMNUu;W3T!Uv>Dtz*Kjlo}??pO^nj*-=KIg#0u93t~{#av2Ta+3nokGS9eHsD&! z=)~8IQ!lq7f;~4Vh07)Ok;5A70Bw{g%E0xra9$B#o?6QG$Iu+0cz&}IwJ=2mk=P^k+}$UE?q`wv{%}BcK0ehExz8=8t6VBt#*}JK<0U} zm<5OI-n%^7x;jxgwTPAqzj5i8asK3hV3f%>39fUjDvG&#+q(SBMD@Bm@Hb$u4GB$# zCTpjjHDG9)4yy0MZ-&3+R&E5Qu%?-)xnZ&U<_?ER7cT7gyr^?x1t6PhMtT|11uBRy zktXQk(OwISVRn;u34NbL=il$ywiS762Yob5==jr?R0CSwG@O5?74Uu;Z4w|O75OZu1d=Yi>HfwLTxvoJf8W< zjwT4dNR#*b^rPSnpgLjmewPBdpzjWH_190!OXpEC`)<|-AZXmE&2b)F0#Ku$c53h` zJJx%D;E+Poy+8I9*WohpbYS6x-JyqkJm}zSY-F$QI~M=iSB7W0Daj|Y?|QMx)!|bX zZJC=1^uu$P4iQ=_=T_xQ-?fUQw|s<6VI&-svkdRZ4qeRkMr&5&cfZNR4o-Ix{=phDZW*vE9o#Itm?-su^3F6o7gV$XND{F3E@eg%me zJA1PM?oNH!H_2GWp6yk+_NeE+%4iUu8S*OIKuZ^_NmCUMnVe6{G4J$egAEjMaOF4L zE$EC56DA^z255kf05JTq4&w|WpZlQ9oi0NUeWT2rKim$~5;{;zE+V_V@)*OZq;u_^ zP*$KI_KUB;2rY+`xrEFRD)RGs$r3{S8mt{3z`tRt&^>5fFHEM8qrL3RWE-ud<_4*3 z|7|RoSQ}vqRDfC%@}FAbnyq!EPZaUwV)qzp8SdDJHNP+z%;QY`<3p zijpw!oliur$flt{d;~Xwpt0U>iY%7F4`W3s>+_1hhePKqN%Ab^!IJ{`Wg4Wt%?n^gyzz!6jy9Q1#xEDyioS zB03c}C)P*U69AJ-Htlxo?r5sd=#RVJr~g)QP};xd)@;{}(xutdm}X{xenHd5 z?K`R!X&6CD3(KSDH zzUHHC0K%5@JJm31OqN=gFVz^@Axn4_yey)HPJi)gX`EZT>um5rQz|aEz6g;0&RCaG zoQ?l#FmQFLlC?1!HrQyEK2>3c3=>o6X#VqkOin1nIhCV$IqD|@LFpxpRsN@HUnhgpudqrUVZbct8(%<#>z|Gw&+Mo;OfPa!f zZZgdh!gw_3w2!5!V7W+ekcECJlHQs}1Wb_-WpHhSR{G`*e3f?|Jmp#!Reb{eT;yY4 zx5Ph$`st5sm*aShQs3N4s_FO?V|>S;GL^Ax{N+$zD|GNDFDPmw_w1mY=rZ1uvymKC z$C=cjiHKTV%+-|9NbNPdkrU$fLM>Ojry~1y&E=HI@f*XPOtojpQe-s3i4 zyr9UnLb+Un*R+g6eFb`uhrU5(Uwi^ z-|)wvDCcBN_YO7fm(5B+Z0btD7Zo{q&3A^A=>+X_Zy{wZftYJUW7$5PIooR28*uKU(IO=Vo4XCV}qQ1y(ngO&S#-Y#{h zKHUntP4G~>S;wgxueWZ!H}+#vcKd$aKg4WkdgmkbkxR>1;9uR!B_9;t=9C-m{FgD# zT;D&+e_78*0S{<;5zj3r3M4})yu?k-O3diK_9|IE0WB3;M6Cu5)Hs<*?7@&lnzWaf zUmtbtr5|$Q*N#W;ba7qo>2KS==r4Yls)j27LYjXLLH#GKmeo-j<2z0ktbKmj+5xLv zLGfP!$Ja)CCMecVnD0``uQ;i>UC^&QFGnd``nop88snB_onm#`Wq+DxE_Ys%c+p&S zSv1+NT8$*5sxXltkY*)^r@5k}_+vSEJk$gJ8~+1o@J)A``0^VifS;SUDPFyXm&W}n zG=Q#w(|wK=XFo-xM|A&;5IwG&fcgotU^-3+BdUcCf?KBRA!;Shq1|q{cqf`q>6t(A zCWYx|Ao%AY?R|LZ9dh538-`iF8OvXM#`K)Kpqhc%Q&@uPo)ocADHUqIzI#uuO@PZ{2~7o)!1x;Db0y2; zx1vmbCK=M!&KaSB1oc1SM-r#$2Keg*MMeqg3^u(0$dsN5 zTH7bIT-ra+88;3a*CX7}09XDB2b25cf}!LVV69IUDz7y#oh#g>)2UuB4S%WC!h~9h zUN#%N8{#hV030ulU$76{7q{6pALd8w+yZP@B5>4)>|R|*w&GKOOkf3yPmzlu40{nD z=sg7-uI@eEy}(OM7os^^^56-3{N%>Z34h{xMj{k+zS0%fOKG_X@8_X&?#v4?rRu7v z_*Vf9zcZGdyE`T#{8yvrt=MLr?S{ z8%hv}^r7cEqIzndBjTfs=){+nmVA0@ysrqGERFby3fc7T9~<+Z+D2!0ses`3>UrS> z%G*D~rsNN@j`@XsGSgAT+Q_b8FM7Q^R-i&AHhw2gfm+fWti9AZ{?fh3b*-h0va|dt5yYPqEhtyBJIEtj!_UK|Dz%>ZAvu?I zGtky=Xo4#?+a|GOcb;P8_NmHg5jS-bfG7=z2x~+n>^)Ag;LEnQv z+rjAsr;JJAOcS;`<2X6UUNz&*A~s7B}%*wMNS1xVH|DkBjmNn|1w<3(Fu z?JI`8EUlW(``b6-dWWFz5f(;4OgF?iy;xs@zi-ilGGE<_R$RK*`aNv4T<1NJKfeHH z@GCN@mtUG9T?5?@9$9MW3ySWu0c7%$k*bm)*T&aeSDo`Adyk!EtUbOVa>ENWyq>EU zuC#AIsw{V-Ipo)HVn3WS9~;z%d&S30Hhm9>08q~O&(A-T+@Amn&{;YWAF(BlIoQ3> zFh$luwj}lq&-{CUjc*NMOzl-5RO3Jhhq|~#OzYAJ!;4h%`!+B6^LP6e_{FQ1TCbr3 z-7JI#ELA9;@S^n{h5w%Wi#^xw_~^Oni8m_2-Z}WWh1ufH*V0y}nV6`j6GJ}wtxeeX z8Ui_zsd>NJmCPI+3pP(sru}5uvsKGj4Zdd7sA#RN4D-*c5PLPo@(;E9X|I;p$Dx!g zWA8J+8tghU0rq6!!6!~b$(zVK2W62_b~*#ioeM;M@eh8LTg?6>!!f49TlRA7cbOeW zunj!jpP851D*@8Ld(^&|KXT(Syc?NTEfXOUGsW;{Xd%O)9C^(eyRURzGBQ# z8N|Dp^~{+wQ$3DV8(*|aK1w*i6x|iwa@9zu$rE}rGd#^K=FR9CCG-47DW@Donw}1&FU~e#vTnceaJJZEcWL-tjO%0{Idb-WFGn4dD^=;c(%|V z(JWbTgO<$LaLUD3bqM-#BXO9+%Jx5y!c#OZIO&Hyt8w|A^DQN-?}Y{< zWah)`88#-2ohJ@7><|I##vrF?ItMGIuE8FuAXZt|M=lMBpidAYQu-DJuDhQ&G2x0| z1(4Tw^pDqte}4yw-wwP7Rfm!;@C=qAHj5qqTvRf|X%1Ua5Njw;AQpP2QQhUqR$3LQ zz3)=#t@1+I2zTJ^c)fERAX2w>ynz+l9+a59=dCce2&9uE30oYf@8GjDX7=uzSk0rc97;>q05gp8pL;p`A;9ARf~y+1d$>0x2o7ycvWenGi~FT z(=N-4RL64Lc#4+su@%bMvD7l9JJPpnRxVTPt;^kQ>qVTj9C8vArm7caYAVk5+DCp5 zIkR(HdGcY+{~rw22mZhP5F+R5@qY!{{Cj{V83L}I@wNxRuu6Wn`T>H@LVi~01h_N& zo(ACo^52pF4BJcpMKhYg42 zYH_9eYuDKR2`g@``UKWEk)xYZ8nh1G{nGPzo=J<4pMDIb&R#lP##VAY8$>%t12LtM zzQ9J$+rL# z_Eo`Ps{=xN@HYz@@r1dmYAOZug!%FZF?IXu*WqIk<1?O=%oi`FoyWJWju*ZB5tLh> zgs=7W|2_HF_N`M4C^3a%r`|Whrz3_9-^qIx%D}y1NcU~)5!T+hwN{3VVd(;nn!2>J zZk33Q3}L6Mhf7JRBrr#cp7^UqJ&$wW`OJ~PADXD&lqvV2!HdTGt1@bbMKz24qmS#& zL~2~EN=rkWJLD|lH17QEzae)JKW`KE43ax%)k{8#Q-oe~60_@tNqim`&B%#z0JgLo z;R){Xaov^+JI!SG(S$v5$Fc2AacBCd@gCfBq*YrIW#93;e1>XZp>Eb9`e?JmFYFcB zhVQ{PEb}PoTQk`yNX|c}d#3vULeLW}O=Mq|tw`%#jG4h&!&K9lfei|SQb^GZ2Dj#N zH1&+_GmXj2?h$s7U?9Asu>vLYfIU*K1oT`>Q=R;(N38L(D0!`zTDSa9u2pVnwytZ| zF0Uq)@)7R63k?%tyK2zWor|Eo&)bEMBJQ6AIe?>Ik(uaYmM5W@eLdl20lP?WcbK&< zKzfnBLgendCg`I=`#Pxfb~sG-ZA8uLoa^A>d8CNX+<=N(aSU2*1rgMjgj8N`$I`_2 za*Ct7v_<~+R=a6okb;hg2;k9KUwXV0o#VBwrx+|nabij8)q&~pOJ{>IGj$0u#bp;QTt2xwRw&%4y8M*Mn5eaVPBnI)+xsW0 zQQELPlS(R?(=Ut5=1qSA8UN+{sy4$rA75-OeNXOnqHNSUSKZ&Wh^E~45AG!%_ivyeO;dq-pxT`YH|~KyHTd$vgeyLhnDq=jC2bbxHyQ1B#(bpdWbu z8{f6}TT1JZjn0Dt%|$wMV2eOM9)B@dHPKA~OS3#Jv>$I7KDv6)bL4OS5NFL!TqhHA z_Y)$McI=(jv0A017x1hTrQ`1mg#TpLDw*e^HA;6QPpdgnwpIGha)evr7D>xCh07kv zhA7C5;mQa|{tKo3Hnu>*S&)@^FD^LCPe&J{`Lj)Od}4cnv(Hf0=k4j}=8qP@Lf;z^6`*}bmj zS-KQMOQ)esI1-6JO@jUlTTC`mjMtuZf}2pt`F^onbU>t-|IW_tP$qkX9S|BcBc>qh z=IE;7j>Vm<_RsR@$Z>kgzEzTQ&m&=@h8y$!@D&u%KzJqS`9@Q_tpY$M1G`(9uP1M9 z6f@&bb^NOfEQ5ag!*fJ%*Z2i1NA5+-gVZNDwErT6z=imikE015!YiCZg5wK6?;CuA ziyB4ALQikBNBz|G7};wVflpC8{`9x$`mf$7u{oa)>%m`oyi!fw+;-G90j@;R?PZed zI8%eAa*6ZpSYQpi937;RNSGmMv;ICFy*Zsw%h4XljtfsJH=m+`r%3Y^1;yl=YVMv*MbKzM?oR9Ye36Fmd?90kEQz0uLL``Slv@lN? zML4lhOJI_LDi_nYhmYbJe+yn@aCd2P7*y{|cZ=VC#6gJ;{N=WQ(t#vT!s)KS-vcoB zI=>ry2$72sk>^%e>*aVs|D5K4I*+pHU)HZVxP1P!^g;efe`;tQW=)}l7jC8c)~i6v z$1|#VfKqhr1|^$Pa7+3xJr{l4_^fl9)~iBwSjja`2$AZo&*U1yZ`-@(H_Z-+q*Bo5 zsaF8!2;01f7Rn6tEd0`?g6l_$Z&_Z%jo=mHVKZ%9)uP<4p8;vLXwm*fBWF+Z>K+Mk zf7fUgF0uWToJ#-MQq~Lew7Wz8;r=O1k!RDJDV;l(r+lF|8&L_gbg!2g;fRa672amF zbTG@P^XJp_Shv0x+GqD#8}oF6bOzuL`&@gc{%l0LR%KVHw23}q?l};Yk2E}fQlCo8 z&Tp)YtJU%xQk*Qm8dCfmc$bI&T2cv8J5kBnZag0RM>Qp9=nUJV*fpWnIJwX&z`<1 zEzs@m^ZoY#L2nP#Fw_f?Z=hP$HzO~{a7sc8Xn=FkkcpEagFj?nvWOE(7SC}0EVM!y za1m0v#2AGVe>1!>e<7vQd@!7&U)F>Isz@iiO%*7265L!JdgQ_jgq)eY(SD zA@VkgCCkNLK9I^z?Azq)a)vM)X^CNJXK80WMoh3_X2bsylqD@}s{>Vnuy@6>>)brN zj6$*qH!hbWhINL+lHJ8sT(1r*K8hJaI?;o5Q|fmSxFNvB@0OdaZ{2}_tBB*ykeiPD zx;+-TT?pM?^cC-^ubT_AJ4LPb4i~XDy}Ki>1Il!qK3v`R2;Q~S9hR37pk-oCR=H(z zrG9;9SY`bN9p&}=kfDUNv2#60*C{=h#d#IP?>uoTFWA76tRAqIl1@7p1?r2-XZHj_ z*G+VfmwVbsXH;2B)4U9576nU61ujd9Ze{D&jMm;c$3Ff-%)u{~)1?r%1x#~_NWJI(yDg+){^Dv$irMi+b*s|!_fXItTE9c1>$3yveh4Bb@u zj-phsus;QhiDai|4X8hOGo6Kyt#4h)B4!9XDSE6W17^R0$LdlGL{L10cstR1gVWY) z7C8(nx6`cLJYg$MbH2!x7!bEombj~|Gu-^4FTJT>0U@~A2%$n`-Kw>WLT^r$jC?jn5dbq*5nh9hmIEdOSCo+8HU0;I5fq<3eWYNS>i?G?>}IWa~RY1y?_=PI3lau!Kv19`rYUXGd8d!>r`gth)@GrCfMdH?^{i8DwC*!V7N@x|iDVDfGp1JRe1y zOWBEmcpS2-@UEbXn8=@AL~by-QM1UMSpMMxL8mbKB?xEWk3!!#A?aWD)R{RkyC-pj z;B?Pi5CMAi!eOjNMVK4>sPOi#qtHWeD{*J4%L1CN11$;6Y2XZa^KhtfvT0t6wbGt_ z*EFLY6ecfUK+w_$*O&8`vKPxl(xrO?8x_7g^{)oMBHS*4HNSr`F&b6Cq*?^=j_I#jEPDe!*W0MK?Cz3ews-3U|r2k17Ycnn#LrO zi9&e$a9xli)4w)Apjh-#sc7TU;=)nfJ2hP}&G!`)?PLqyJ>^DamKL#-mAQSnmKt-I zW*&-3gIftY-tRnwV(^Q)vg>||uSa#h<~{uH2u7D^W8lRxS&S|X{<{(mU3Aq?Uf}SA zyQdKTvV-=-x*U+qiK`qCKJj>=T$xIFG~~l^H|!l2)mlsV62ARuic;#<#{rceZ3aI+ zDmt^5T0>H)_Lp|wd~LKGRwW0lfXV{mQKo4{PJbPnvg0cul~`b>$zGbht>k)UdLX)i z>5$Oi)Wba+@L7ljTA!Xro!MVbRJ*)M;B*s5AH`ne7iQ4*r_ilkuLYEDq)IDnPQ81f z^-e1{FQt^u&O3~?ne06HLU?NOoKRzN$ayhmVdD*lP6WLNqF59cO)Nr+8=+_C2RL5~ z{eGPif{WadRj9tsPiRFRtIc^%LT?{#s#$Ep_MKq${k($xqCM0cUb62`;3~D(a;YoQ zwWMSlBZiJ^nAI8TWB#(tDS~%F^!|+^|LB#nPk^Q#!*c3#83?a&DA&?HQ_T(Mj=Ucx)m>p z(PXN@8i|)IVD=JI)iV0MfqaaQ+A)&)8IBJj*VnonU9%YbLUM5*xrluNBkUB^1xC1e znx=nWitK|I^BTYB-hS%X9sDZSP&&IX%-LW-MyYtvL0&nN=JwK15|tH}9K_Dn@FFYx zd!X+47qNu1A|*yI+eY;-Z(fa`v!RhZI5k5TW~? zf=_ZJT-JsAL!Yu&<*sa}Y9ZrPc-Zv}l*T4$fU$gML>+QnL}htG$)jdse}K6(gAWxL z#V8E=-KhYZ?+E0XBrriLd1C|i{xHH5y~wPEhjTb^3h;4$y!-dMa}(Df5W7fQ)L=wqdAQ_omsX0eBgBdhe~ULC8g12#akxj_x_lf z&WkE0nu@~=~!@}r1=^j}ED9iPNWM#w3xu#}(D9|Dy%tzEP#^ekD8@V) zkU9i^R-hk5@2gBYr&cdL_W$ya1lNqKyD5_!hUj}38x`hv&i@T4^vI8POlbJb_!hV} zF{s7Wnk;I@fKNWS&dv^~w0H%F*%9^P-CK8lC#YdeB^*v%_M5}ZIhKQ<$-8Q~dYbG$ zyGuqe&7{A#;Y4Nc>*7W%wfOkWS0OxKb+%GshUH1m^--)6e=83s{fREJO&7<#dwH*q zuoX`uS}Nw*HM9$E7iQFi&1*HGRM)-c+Y(im%Gbi=_J3(8>i@L#7=Tc;%)4~WD@qt` zLhVr&s4Y=!RXW}{mQ9h6^Uh#0NX|q@v?KG?c%}9L>EbI~ko!5V4qSSql2{%oiTM5a z=edTO&q)KPoNv&aMI7qS?gbjgt-RBArit=G6l}kKkmfq!d-S>#p%icqP>F|u(TyrF zGQx89b)k<{!XqQz+;6P%D9+DdDi!hvZh&-Q5~sEQt`x7s>Jd`{jahYfpMaCa5Ek>1pTI{doSmkW=V`Zm6q$sE$8uQ#ZQc~>kh(K2;lgPm7LKha{ zgsxLSISQ2ots@d$=53qOiwk*e_cS+NnX**jTz!62rlm@yx6t^>P8fdn2EsIA5w5Vl zuhhU_!@a8wp$y+88Mo+TZPO69uS~>vI%rAXD0BwmN-TYTKsDuEL_poL5rE#!kIP%T z2Bv#>nLTfo25mVQ6-&4-W4iLe4>tVhr^#9+#d)RJ0x!i4gE>sy?T#B139@SbGUmuw zuKd~vxE>Qwsq87jd9#{;MyL98npnY`RQ^7Z-?k$LWaD(9H1JQM{h*v^@=uoH`y&fK zcPgtjK8IqLbcO1>c9?G*G7F^^uBL8+lW7F;O)rozpfY#nWnPb;8vXhaY1cLN$7FnR z?Am?tA>F6a1m-knBT>RSlevVMm*hzOvQ%l&L`(Y%qx~zDnPk9pV@m870-n2nbXP9nBYh#vQjc2BWm zEJIxV^}h1=`;l%{*3Zx0$k*V~k0BTH=|?Oz0H3K0AM$i72i>BU1FRJZkSqVm;u4*C zK{@Xs?$=RpCv;!@6N;?@AC}dN1Mewe5@0S1;*#~eza+XC*2iEKNDj1{70eoK{1a^%nuLu zV(wX#V!_0qc2G&H#9?vKGXIzvGj797*CE17D`z6luQM9TrXt?PwAb_>7ZeL$r^n7E zIRx1#)b`x08(52wR*^;5va5Za;kmUBF(DZxJO4EEgUh96oY;J~n`@bxWLoWIhC zlyc@stC90Rv@;q7c@wme?vIg0K^)}0WMFsf{;=iG0@$Xh0LlBiR5R!H zORO@V!cKN(@6dm-G+p197l@=GTm`6JyjTlL0n`TEn+9`$gqj?gUTMTdEhB?$6Hm{H z!4J@B71dm7$>lW98$CSjrQ!{qXwgKam@_7c+tlx&LRZZ|88L4e(w;C{B@QKVP&Ov) z0p(Jje(_nCZhwJUu3RsG41Ns{)Cb(E5|Aq^G`6kQ{QY=yWVLzOnMLXd=&@h?+{u(B z<{HRy&TF#a{A;Q**Y?US5khT%2pa|q8tmvAy@A%ZFcY_PmA|lgh>HU80|sd1+Ly!n z15ahurA1w_k60~G;)z#{=u))XI)ptlmY}PG^?L&?2?D_FUdqTG=^!{a@l8!#?eu2v zvVyQrJcG#-%sjV7S`4?_nQ$Gn%RMK!AKoGK^Jp1WzQM+)R-Ff*4t{w)ES3xUcan?6)~MmgA&+!(+RH3!$7{_g)gf1;kHtJ%X@?K~cXd2UDbijSVuxYF() zy&YqwLOZDAi;(kv$PU!QXko(5N{O`hU@UEbRjz|BaQ}GlKkTWQ$| z3ktZg1^E`rUdb|4FNg&7H~2Km1DI*1`w9!*?C^#^-ZQT#Ks^-7b7oHyIW%U}p>>k- zM9Zo_-;&Nj!~P7tX5468=ilyq(BawY&Gw5tjeLKerr&lS3h>U9J^I!9(~Krq=PyklzkC=ELxi_%S#2*QU_3Q;=X`01~`G=oLd zEOOk;aX%OS93e|&JJpJ{XD3`m%+q%AL!ejSR5!_|gLMHb-w2iOUdN5@pAiiA&_#v* z&>c%Xzg6JV$`fjmkAnB{ZU_Ih&<48CJEx>OdsjF0hw6*UDoCB7rZy%_;OB9QK%6P7 zR4S+9_E^`6xizJ&%vMSK@UWhT+OM7;b#PMo(b#KDk6iiT29GfA8KwavAZ%ccJAZDf zwq!A;K;OAGuO6k-cM}jGGd{ZwPzYdt3tjC8VsnxBL&i<5{&EE6;#-J#HsN^qbGrUt z4Q3m!&&O2UK%BQIS1}37w%c_h_`5p1u@M_hvmK>v?3?f9eWgo7?mG!12vI>FkKA1! zwG%YH@fG$Hw95$^W`MDQ#c=9)&)u#=lR|Y~vLTq>FyP?e0mEMU6MAxOyoEaC=7E*0 zUcYNGU*KN{g?R9VBke`g>|ohAsq?)txd!D*Gas0{0i=*3V>fdL|CHf4;ggIwl|$i< zRFwoVV?#^T0aYCbbY9PLyxs`QKP*_f5{P89tOx!4k|?p8kd3HPKHuC`hq5cLyczsO zr&9U%TeDuezfZhig9s<7$m1H%NU-vFW(^ud6ZDyDTsxtf;Kt$ej+B(7JJ%j^gqCp8O;ypLVhO*5 zQs*l7^#py_C8w7OEYIaQzm^C_W$&^fV>CWC+vMOm#@|?*Jt9^Xum+Hut^B|~urK37 z^JIXpYN=Ilr-)~FE{bbHegRLhgbRuoAK@IgdQQ~ryKz7M3+kUjGd^P`%m8Yd{%ry@ zt$4yzBJTaunjrhJYAwu7=o8;lrhpZ0>8>uym?dc}-G&dA?k=Ve!k_6bSXG;!>6Y}tmF^ot$J=zH@(fiU1 zL_Z4j4@9md!UI~r%P55ou2t^KE+S`r>Is5THki7KRSq@JG;1nFHPr4@O%FC!&D|y_TX!Lk~&epir6?9~j zX`p1q6iWSqVFw9}C68=U{Qm1l?7yie`}Sg;3e{B~=7`1L6quF5V16FywgozusSfd5 zUUFp`mlJASgHFDC;|g3$gYjssL(lA zrsz=Vt=4E4y;(o^{ODkYET7w;A=tJlxA>2^Z=(?E%A1 zgz#7GV(m@6<9zp$(L(=6eQav3wmy5gQ`-A|z{wiN%6xvB*JCE1Ga>s;i0{Gg*+w+HhfMxRWDWQMgl>VTVS6VMNyvz>omnh?0SXEE{1b6t`BHuZt@$MOU*r# z-OkLLQ^&fbo`;V0aH_21>pESpyW8>b&?%8e2owiDL+K$M-)lzRUPzf&+ByBaA*d<7@V;DH*BH|ie3UVk zh7ZfB&B|QHV14B^&hYzS#9TYn$sN5yIdjU+8{4rJOqsPwp+!>e;e@Ken$Jt^b**(b zdA2#)yJ0r+I_Pt{K_Pv3zBPHa608QTOVgWA>cIV0K!H{qp>@C&ESf|}KZ`(%J?XZf zu@`2inWd(Wu%bNW^*uX|6ctpGy89g(JI&91y$JkAI}5PtrfK6h5m)&ybGYB*7o@}5 z|HiDnI*514)@G29*@77*k2bF=owhw3M>s%)ibPY>v|41ZTWXQ~?ev)_6+!Wb!$_U( z@gCk8fDmZv#0EyU2xhMPDOJX=1t+depqs%Ne|!s*i8)OSC87sG_T`zHwK%2 z=(Fq&5_|e&t(_B2HacM{KWQUp0(}bboBe zgupeX*aDM~PEBL_3z{mksy=aJ3IwtcUQtBi^aY~cXg5c{-OHs=UB1X^$k1m?ylB~S zPWDp(03g4&7>t?mv@X#3O*6gL)+58e3W4Z~gurF#mn4w7zxcKmwMd&Y-FY?fPdsdP zfDO(}#0}nmUJzAKAt6C-TmTkmc*MQC^mRK7$o*Ep72lKAi`qI7gHGe^qRf$YniMftO3yD+cxoL&YwI3J=|<=PYLLY7Kt|XerUj ze9cEW*Pk9N3JAMd`LN#mTsBYXYhyEp_f#^KlEMgS*D<1?Bw31Z*;{6H*LwH7@)U!T z=H1JA4YBzeXLxJQ!;Qst$5;sKW4T&|ik%uhMq2(6yY8E{yQ0|hd+nX-{HIJ{El6ac zh!$<#TiIUneJFyO8RUag8REhuh5s`GJY#rK?*+R*gkHcS?9F*Wk1!<)(JyA7f>evR z$9?6J%~oHvWK-A1)=md4{T*|*xS3O}MRDZmn8E3m*j-N=(ddH7@A*}$gG+iKUw zQ|tU2kH1(AIDr;%lPPLt+D2DcpwGgglPldQDdDesC0%k@dEo1f$eW$^+IwPz&g+tZ z>;;s?6&C&gSnU*?Ih4(FG+!u>OJ*XEfe;M!}+`f*WEBk0s?^VJfIl4i&hNP8KwJsEj@7 zKg+Gk>yKFaoU5&zw_~(ALbc8jPYG|0w7+vb_&h}=MD2t#i@OSTCZhDp%pgy>r2lxO ztwQ+h9j&B!twMF3-cgpnzDvzw;d#-m=Z{@kb6eQOSPGHaI4 zre79@=o&N)E3%e$ADSSzmtK)P9~e8BNBkMl^{UmR>HIeGz|k2L9CY2` zpbk#!_e?|A#y6|B$f5~(N8A;ZQRL%#V$G!@prbl4O*fVEQnQ?JwPGp4g9dL7r@1NS zx7?P@rWI?qY2-EJ^I{-PEq(xJ$er?E!@czB)~|T?DjpVXTdO|W8h0&OI7}?XpCF^uJEu`c*88yHBimbV zarZm`gS?~IL#_7a__m)*&Sudu>J4+yU<2=rYWYoo?gl2ezm*(INmx_Ix!Dgp7YE<; zm+Ah{cOl@GoSAvLHN(ddH#Q&8XoQn0uw3SAB_W{=aw_^kEe0bI*egJ@ zCT=rj>HtJOBe@oDB2vqh9EGq`ed99^YXK7hc{o0&#!$k8K8)RJ0Ic9$PsfW;9V@L@ z=}D{8yk0LOJ~^9YyOj8?(6QBN%|=wbpqjvX&v5#qZ(va=m;0V!!2Wha$@D2bzZHrz z%x5VlhgIB>Vn_FSrpzMXPetU93C1BVez-p;S-N=@O<@)64Z$0_$;ULH73=9YBD zuJ{Pp{8=TbAgtdqO@gW~0n0`3paT%(N!F)DwX4q}9AyAs4CD zBt|?2r4So!5Aa7MoQFMAi~KVq8=obzch~0O%1`Ujg$HqecXKD{g>}XJwNsY0CFjRP zlBZnzY$3nW4Q}e=J|vh)gM8=TcM1dYYLO@dLwd&GBya6G-8r$XUbR`&IkuwZS|3dw z46FXNSf-yCt+nO6m)x@gm>%K3&^fZ5@~I zYqIuPPv4a?o9Le_d1kpivo^g_1&Th?oC}P-+JclE6Y}-5IX4kk186O-1FT{hvwt}M|6h*%;(v1NPk!5HL}XGM^9m6(MsVWZ9+_Pk zag6?WLiCznQ!IE*wYn8|7KB6x?bHoFp%GGp7CL^Ed``p%uC+9PHRp_RZ%Djkqe7$g|vooN;H~B8M%VNelH`Zo$Zs=yrzZ>(mMO z%L!|X3jgEG?@NG&c0198DYUXJ<_=mGGNoZMZ%Ax+>9*8tlfN%R@`k-)c|cVtFwfc7 zKkaus6!8KXf9t{JKy1PFvsaXU>xk*L7oPid;Vou&rl9R~wk7k-6;ur0fQ+|u$pPVmV+!)hc#U&b$vYCatHz!cu~zGiRv@FNE!7p^#N=R9G$ z6e~-NhsoepMyN_+Mc~nP-0odw)FN48@>s;AFkET_FaQPv@&!&Y5=${^x|>&RvSTh3 z!rAA7hII9qa~sz`8gFmE_P?boF|yf39f;fLBr4#K2cKQy#^1e!KT#=)&z4vM^(n>t zPulm)hXod5>+GdBtt!0;$J!i{x$OfHRpnx`_=)`QP1)QqXbUQrVs!J$uPX?&A$QrP z>i{I9%IRG~8VKE4_GI6B16V;(0^;~TpZfmrp*y}RQGMHYx><`C<-Z>IKrF@g&pnN1?Wh6Z6}V+T=^0d$rNvzjCIPboDfRPpY{d~ zwK|OV!dZ4@?=;Xqg2~nIwe__pl(;x#m&Les;h~A7u`b2xXboMr@^H%uZBbc%D@l4O zcn#@s$cw%0?b9A0HM^2KZqZ{YKFuokaV;mIYK~yfkC=|OBG!tH&OyZR{y_Wm)$xd<+y)F5V4{S+MOW!@hO9n1b6pdUt(-_!J-g)Cy1MPRMtZX_L+QSE6nP z4axoY!wEiviKq#=&1Zbd?J`$w;gp+enQ?EPjRajM8xZj&(-eJU`@S;GqTPxr*v-sa zGEGnS8iOjXq&5>Lg8^FH&#zKyHX^+hrEUL>uTrwR;D zf1QMVvH0(YIcT}@c@K7?7@dO#c#w}H+F5CLP9D-1eI|Z>gBgS85%;BB_1k_82Gj;Y z%ibP1nPCgqv9QV#{WyrU%H%E{yi8E-fC^Kr*rEFc%)PJ@us-N5$4!sc~_?fbvs#GDZt&!@dB(hJ*9Wg&VMJ`{qpp{=kW6R_-+r zACL?h$QPY9=C$7|kQ=Bul2(Gys%Shr0jD$=f2z`RoNio${E(d}3*6W3Eb34yVV@|3 z!iuBjQPl|tU-3-G>u|4K`@w+v(2$_@N9hlngaKv@x74<0@zl;C{-bT#j%Opmd~>|&r8Oa=6=fWdzqVd&A^l@znqeAy&cj8wFnbE$0PFU zPBo4to1)Z=*zeT8LMefDxpnq}==Dnrh{Tda!8N-hq_cO=FO8|?LRFcM|I9ra$71-B zMyQ^Wq_df)SaX3bV0I_IJj;MdUBpEzl}-O+>3{8T+GYn0D+~RTXb21dmNB)e}SdLHG9FfrM&F=smK}RX+HK4 zPA{-~Hfy;!k{`5w5=Eo=$tJoS1kBy4xt>qkt4`nH*+&=~jT(Opnu z=NHNI?{*tbf{8rG!Uhpj5MLlZalC^D>W=sV#~Naqf@2f#J^&)q9LmCth$C141@{B< zw+^(_LxHVfO_%+?_t1LU$RAr5FEBcl>MYF+>!Ea;wrOV|dareN~EY_Tlag_RK znft^szW4;*Im}I^d?_vwt}&g=4eyduRfFHIiKzCimT~pUU%}qHWB;0ykI2$J0+=6X zN&|KWMawCID7C}9^<`XDz4bFIsv^iXq>-RK&W>HRobE{}mpv}zgu9$D6H}@zi6_j( z7wZmL=PQwaVv)k(FO5CN6gH`SJtAd2l9~qHxeZevZ#9!AjfaNX$T?Czz60FFw}?DEx7y=d9SSG48uxju7Gk z{L(@t+Z=s?z+^XL$UV1QeCz^ml@uq_Lw?i6?#;FyILuCTKFuyS?IpmnlLmfnb5X1^ zy}Bj#J@b15r6IdT&Mci64Ee~7-C%dfGsc2M`!v2TTCU@d;U!BTuK;A5sEa#X2a-#oG)l0Q=bwo@In7V@7LDkQ=~c1Pbd#|va_l`wWy2ZP z1gs3VG93SUub^$n9%T(Ck67VV?u{^IiBX6j@&1zw&v6-;=L|nUmQ!O2M3Z{Xq0dcy ziB}F>SCgpauWA~$PqpZi0}H=iIQ~_$`(xUroOe-G$>ovWxK5SJ?~5(Pb~U&&f4=yu zzu&g7i5oBNmb>mnH~zQZ)nD`8u)wPPlqD|ss1e4Bo?R4cEd=Sq&rFum-vr%F)FJFI zxyi=5R4oo)K|vuAY^mbqH$GX$4_kPJnnBk$8MHUv2Cp?z5RQdGFx#Qn; zBJpYF;xcD^0b!fqLi-b~WL$d}QiTuaV|+4_=PYU2|@HJ>RT9_YZJv z01X=onBE#o;w4T65Hv})%Qjo(VUoucO9{pLZk8?CtSQ!9vGFH5xxrZE!Du*X^w>Cg z+kR8AfRzB(5p2B))!I|ew}_A&@z!mn!o;+Urc?HE=1Lk6RO=A)#^eM@<_2*EC}<&(~91)&hflOCKo?eXBM-q2Mt3 zNv3z~M5v5F#$p@@U>a?=3#BaV>Q`N(}k;giw z=w$KU51VJeF=g4OY(@v>w#N*{pY`z(R3CF{5fc;-96qa{KuYZDon)U^n<%6pzT zw5DUV^)GK_wXxW~f2cVmP(2>jd(R?E6E|O!@aKpZl;3D!lc*vJomaN>&&nLL1h1II z7BymI<$Mo&Rjbc68Kr|cjoJn>&+A-X3-B&{_r`j2?-&n8lGx=(+@lJ=!KtRB>lbLb zkhwDS_@nms+xJF4oN7wI-+M=l#lFT0CN{F*Y-onCc;I@AiT@NzN-VoeCH#y}0^@-? zcaRNCK=+7?V1iTGmVr{3Vnpn?odrTihC&a{txO{i3-xXxU591xk52qOEj=tM9$}9kS%53Wwa3nvJj<`h)X_c8IoB(U3F|#oWc-|dz^kQ505DG4-X3v& zG;8eoP|Je%KA$aUPf0l6BIn)?R++hE&_i#f(KPQ3i58AjT}G=Sp zpd4BlQS3vL(Pc|R+AlxESOSimztZMOGFOQhm+|+Pz*akO2nhYK69cB6nqx%Tk$c)+ zA+{aC$0>ZwLHw`4VxHK#9#Zd9x#-t)7a)|$kCy}6I2E%6OYz`uHf=wF&LduvVwFh# zM@<0?wt8uGbbIt8tAf{y$N{Dg8~2Fteq}R%0k(01G!>NmKZ!h9>Dd-&IjhH+sU|j_ zuhz7L0*(W(3q2Vt=5KBp`nIurmLFTHzp*>SPeeU+&W{aCnt!84;;opTFk~yNc@`R| z!CU&w2aeEOJ2^gWHt*8rHWqiTiz9dITA<{T3E7wgypCw15FI-K>VGX{Ub&Ub`5$OY z8P^8!VIg;8;G>Npew(a6?5EfG-=6mrxbgAx6Wj^SH&`(CEB8A#x2H(-+l%Xq@EE_6 zbnbnsOL-&?(SR$+8|^w^%St1Ylsh9sy*vKkz89zc4!Buz1RY*%%z<@Qfx^B~VW}YD z&)QS>lTDqEx%S(UX)3veFvK$`RoAA&)%?R{_`wc%S$%9 z&PDfu;4PBN*c$z8BxvMEwHN&?Y4aPwo9v`Op)7E*(kt|}_&i6y4Q5NI*dP09ijDng zKn2nz5`n-sAR-w22tXEuAI*@dfYUG}cYS(&05zFUIPqfOsGF#Z?FeTFwaK52e1NyS zCxquAUlI(@Y*|3zh>>rMJd15J$LwDu_?qm!4^c$jvIK9MV3j=iY#Mwc{oAq~WYfxm z7WvV4JvqW+_ak+h$@DxYTFG-7HIWp$Hp{t)Qz*^D;YY6vWz?Jh`@upq`RE|GL~sB5 zj~_%5zXJS;YzR@CLn31L-JyOTY+d!{gQ<_GJ&PaTOKtE4ab*LVc%#zoT+!yoF#h82 z#}|%Zehie?gKQ%5DcA#Ggg~JKNd0B^kNE$7xFU}j`2^|o0zIBIfk`{tDe?0In4G|B zN@fZr52aGcsW98lSUTr5!`)Gn)K3pitbOk4L!LGNxd3~$a%MD|&C7qlr~O_i1nF&v`KxsriX#k>+b);7!}5xT*L# z4!={s%JH$bdE<4^wNgUG+h5@NVHS!{AA+w!e1lkF&b(vEI z7-_r>v@v_w-~VF3w1;}<%PxjW61(bru1ffa2%*USjHN7-1|GEDl*Xh30PIYe=0 zG1nDTDY6lU7lxjXca&v^Ta>+NQ^cCFFgo|VT5^UjeY;`hH57*bp4_6{l&2rqq7j8h zfs{RR5w)h~7jBPj=^k#l`|Oe8)c0A-r34#7TOcXyi|K?8iC*qelq7y_Ip|twr}#Z6 zc;$k)7c!^nGGm|>;GNr0Dj)WC3cTQ9GT|9h9O5VZI=q;R`Wg7jL6ZZ$nKDSNrCl|wXl}SN4!TWh zv_zo|9}+SXURGh{y^C=-O?NZ|g?)_LC~1QrljhC>f@&zc$leq^MjFmB?|sssk?@2PchiVeJ0AjpFhNZ`YXlhfBe z3c6>^@wTleqfIAcO7obZY>tv#*vCHT10TJfdU1_6qe&kFA^ zs;FcO3}-GRR9%Yj`s!8dL4WL}a;n}0CLIGM=GiW2wxpkZ^{g0q>Uy;Of@Rac$18sW z;IFZq^sgEJ{SXm9KR3LfI+uc$#Z|HvyX;0NieM^dUVmo1u#5jT^;f7uYQg+AcfInp z!x2W;^yh+8^NZ)(`?^b(21?IvXtE`%#ltUu)sODr*|5LG@ErXnwR%zJXYlckg=C1?O&lTa2@nU1Muy=s zV(AwW>sM~jAbFOkMO^wzq7K-D$xHHXBMV1+UUU-=5+6Zc*?o8tRh8L82 zG#Bdr!co1R<9+IJ9Llc{MSvjLYXq z(KS=ojiS6p`>U^@kHK{EYRe)XggsbVi^3T-KY>w(Mxl5^kJkd`$OLFe8CrZ<2%EPH znI?ws5{1XRgqy#o_90liCj1HRxE-HHzaz27H4QQqj)0g3@%bkp@0P%csq!Jz8qBDV zO(HzsX3Cq{I5Fiue4Sn2v97OsFq9ZpnC7Npbo^OkfSj;+>3~t|f^`0r zk5fx%ZSmgS@(A$H9gP4y?ti(9+kfrWiW31S*nRJS#VYm3kvr&UrV?J|`4tET;>Q1N zmwu0{8J}m%0ax#@=^g=#oA5Dn-EFcTQ2PN`wh#--!R4MnxS`5$T;T;yq}BIIH8EChL z$*OUhMO*aPVyykY=~%iPrg1TK0g5T0?V9dt>hX`P4=TwUZ8TzhLO(FjS`*v95Q z#ck%;J7FX5E+tn@+UFB=TlYfq)2H_2pZW8TLnDel3BtRAeND34w}#Pe{II)jdkWdl zNLPbi6}v(qGPW+Z+y>vVn8a#xxna{sIv%YT%EGM`;6nE)>B>m|zFw73jnMt{AD8X> zQj9%^F*z0iH36i*dx@or<<*-U>}#d%d@z3J3J$}^PWK_pDR=;q9)G6iep)EqB@_c z=AW4}DOdHlFJccdZunL{PB>JY?y#}$TAX&Vi@}u2tl9T?a*&^>VP+b6MK}H3@`n`_ zz_Y~KobL9@tKr_Lt$|01(gS4tzljcJj+j?o+(?ZQgqoYizyDjNqT=Mt;VSo>ksVF< zp0n*pW3kiuYhL43F|368H~Ku{&}oSgxU&?$p|%r+j|Ba0rqIN{fdM-f_(b6A9otH? zV^g7w=MW|gL)JYq+f7vr{E!Op=<9a6x=*_D0?Dq^M{dfWa@*J4@BFaj;>+-rJNcb! zY4z4>CGTD`c1T-qc5DVsgj=n;Q## zc*eEo%AB;edBABW?(l3&=_MR3zeMfCmV35f`rV89~85gh7S`)wlT2|1U;Sig}4jVM<+x&pU0G0+f$#z$4aK zAaGI0B;mta@jhUN5TS@$hLh$OhviL{Rx$_7=z~Ogyeq)WMCq*R8g>EuD^vLWZd^z{ zm+=|)*RY4WhdN~O`0l>( zg=5zFLaV0oSr#wH=)JnGo_w741rz&0Hfz46SuJ0jpsz=Lc zxrfnRW3*H(Ou6xC{W;`r^@8QlJhRe0-$QJlVB=Fk^B3-(bF%poSYPwV<(zSM)9LvO z4KjbMG+-(Yc~VYj-lO@d`2|m}v92#a$`=SWW+q8pxICb`I-m$ni5?A0w18ChQLwmH4C|lyQm}Uz zF3(5?lKGF=QnL~Ss5dMznMn!SlmUs(eWGt z<)=#>IqzOV(EtcptaJv~lfA667A~pFhGOsdTX&G~#xP$boS%0sF z+5_)bazDf5aPh2#y+nn}SVfdk+zpgQsQ_XglYIN=9IX8AImd)10b220@2HLFr5sO( z|M~CEeA^oaQ4SA@ z)fa)ZVwp5~Q=txhD*yY(0DN>^B+9wwO)0nfCiU&iB!&q1OGumf$Iqlcle?-0dB^P6t zEJ1A__vDnu=fkJ^ma~wE2?&Egyavt8h#aCeN{z^hvD+AFz{^93rUU}yX6uk5N#GDb zfO)Wcf`XEo`R|8F((Z#VP&^Yzb@ktjqtt348x?W7J19MV=7~(6Z>IMs$xtp6E0*Q-ez!E~C59 zoVQW}ruYzZ`**16`U8^lN)4LX3E;OG7et@V?^a&NW|S^Kr6K_1gd)H!AdttMMIXE- zv3m8&AICc_8eu<`XvHnaLqWQ232TY zBjmZ=pURd#Ouwgl^y_Cf740UQjtO(CQ6^8B-N5J0f8ixQ8;O$ofIr#Rf{iCf{d3E% zFm(jJsr;S$51OM=H?|mamP20S7T&k&50UItWHdrt14=xFW$~J7 zcYYHGgT+KX<#u3UZ9VP)ia zcb*voeyRz}5jkTsuJ)$RT3Pny+SfXIk=hP5A=E_Egl}}|OL(1}@nmgJfeO2~$~n;# zt`uegVj&(?otJdZvp8-wvXg$`g#fRrsh)lFiay@gxE||<;4ByGX+rBL=l)<-Cq-(Q z6+;(QxGsK{H)SQSnLev zR8?5nY*XQw$z&0s>mC%4>s*jNnTfv4uuDsM0Ny+~jkxwXws zK$9I`{J|N#-Oew#$|V>y)Lp_HdV{~P`*-}nG2AEN@ryeM=I9_Y9W532|tk+of1Y50ok0*&e8{n;;K+v6DtQ}h@`kX9x%plX6 zf%%EwjAsj5_jHN09t*3WeY=3WKzeK69mmk9pzGwJlKDB}foNu|TYIi1L zG|{yrq+}&PO)K0_(UUx5sX>UlJ?L6uooyX@czCKIW3&@4Ba%HPh%F1=C&yEyj3lPO zzEJeWdI`naH%{;Bp9YkMo`X%SMTMStWia&|SPfMdaiLBx2H$7NA_N)yI>v;#K}x$(+9Gb5zA z-bKLkp~+#PMR%Ro!gg7Dit?K0H6Np?u9}b4QS>m?rusF_5YF7JDAw2Sh7zVeR;|y2 z_LJWqXXB5~6PoHL;vTG)zPO*iT|uHI$KQ;097&EtS`TaI4d>L#`D!UVXeE z(4q~BhRuBM8XIfd{-w^*cJ=JAaZxPmdgD;9cYdvr9w6LS+pVb=AwEJdg?*~`*k~PM zEJbZ?asPnb2kO27xfo`5^vATF0Kz0w4zIzVP?d0rofNLrJzp>aa1$2N>u~jJuLY?T z2Bz)!wI9e3> zSPAOh&^REu<>U-tbFP_Q?Rk9N#PH|VD_j}`!GU?$5GK-)`#$p_6Hq`-~aU~O1$Oxa^6PeKtz{Z+pC>GStaDJxCuF^^l|&| zhpQnjOH`ItOY#u2YaM@iw|>BuFaafndbNsAfXRT%2ucbXBEcxk4q`Ss?mk9M47Gh$ z;9h77ttw7gdfoOT*u^hkRH$)bnVOh_DR0qcq23fyFFEGclF7oDP_F&)M}p4K=zYs_ z7uCcz`Q?{=(}e!h8oCGnNxEjV{pyBlL9o2Lc1Jl;@nX{aT~0W(2SGluoVZmTXxnh9 z3>&l55cXmDW&W@0K54|C5-0~5I)+oVni>y@0zxD|%Dhm|s=-T9=5Zv_d1cyurdx6uL_>y{oYPj@n|nJAX>yBNn|(wWah zFJm1B)MQC)Va$0NKWyQc6_*br(LEnZS&l3bI-D~_e++xF1hHPVIXL6qe4i`wvE3?m zxr4JDzlMzAMlk+rs4_ph2@2(D*-4g6qal}cyawc=sgh`bu;Fd$PsAuHnb`f6VhUBK zP2;XBf*CRgo=sIps>O(yzkn1pmzk-nuv;Zx{b;DbGk{=&TR927=J(oS)h=(((|@;l zBCjdf3E=;u?`9!T$sE%+b}-Z4$;92%aa4xrhVUC z-~Cye;trCnqxsn=;h6$S$)X|SSzQ?hc4r%*x|#qcOJtgM?AHR#p9q6gz@8m-$t%q^ z3epVC!D=sn@W2^@CfCtMOL0{@sf7!IXlI=6;-2I6bB{F!vhL+ zOCN66a4X0tvk|2~FWJu*?Uo#)9)cjg4rxZ1HTxPZ!5f~+sXlfOM$0h5h~MZ4l5-ne zUU|};yA2J0*_wb74IVLvnd*}Hc|X?Chfrlgef3FT0IlF4y7GY3toVdzLO{;MpX6iJ zCI5U?`Y_;d)kRQRh>X#N2)Wzw>M@QG$Aod3zbK8D5y3OXS`Dw<49EjkV&Cp=D2rw# z;c-@4m^C?v25ULZUeE{N`YkHR6B_Ry!!<;y(o603`TL^1RPyU8_#mq=arcp_vx}qk zAk^^iljL~&3dsk3p>uMkQfRI_mTKtWSqBpzXqMQ^I9I974qmI#N}$ z^-!>rcGr&T{Vti}gx-}hVRA6tc2Hm+8tS%V1bs_RL&-|nfiS2m!UsLtz01H}-MK&< zazq(R-Y{kGcA^$>q=+U_!euPI#>1w*V99WG{4K~_6VHiPh?8gltqs7GN6x^JAc)i; z+d@!|h2Sk%(wBZnz5D?1Av0@UG?ctUMhERVx$Lka7b$kAxEQya3_DFujvNjk9t^kI zc!+BR{%-fgVcULVM%>FyV1-12;}~VviIt)_KfJ+s@!zASh;EYu86Wh z2R6A_RT~7!aqgoFq!}f4A~L=Bt<@s5fHH&|(B&?O6H zii;SM909P|Db*$;i+hPN{Xx*9P`@HR+=vTb3q^`^J;A3?bUZ-wfao7nn7< zjeZz+G0_T|=#lIGj5@@bOqu5vpL1M7-ED0&>VSBEraX*Kk|JXJkBEQ750qJC?GZNd?Np7pwT*G_zwN(QT$ zXUR#(WrroLMu*%XKx&?coEly5q=@MK915m9vHSM`g78{$c(=#~RscnlUKJ#ZZi)5y z)K_uCi#?DiFFC&Hd}>{ns%Wl4HB{+8He8_zOG)&|ruP>3@T+ zkh8Qp+MGr!jAwt6Oy9d!5$0-OE&#yk$T!tOvF8;T~l0OR#gXu zJfJh}-iOC@Aukz7YUwoMf{J+{L@c&B6W;WNv@7YfJT zoAPw9YUC>5OG#p0+nKqB2~Ey!cm<%^5?dDE`d(v1!<4Ba<74qnH^fv*X=dnRG}W^> zb|&e~6WKd%vSrU}bD$;GxIRYSwTq_3+n!|zPk&2*fDh);?rEMn&h>C0OTd$D_j+m_qcHnN$= zRK}kaZe|k|x*G_}IJ=?m=1hKD-f?KV2}9Z~^?N<%AK-V`4`@OHtnGkpsOF^SCiJc; zTlO*t5r4iT91c%HmXbaQVlX?h2);I%WN$Yt_bEG}thvsXGdte&?z7(^(X$8+NYH(q z6Ac}Fv2ueaFEogyVW9ZVp;*Rq$g{}@*st3kJmLTeni{<9xIq0aIrh*74DHA#cB;Vk2AgIq|iuIgJrd#BLW%94<_4o8Vk;C@xIkTMWw$uXt#O56dF~Z zfSf9a2JCUCPww`hm&&M$1Up>a$f6FxDi*6F_Ots4?H|;|vK@W9_XpsFaf03)K3Y_{ z?GM_<2+)O+6QXEVTUL$6EZ(G6d~On@eFl~{posIG7e^mLhlj7YKa3l55EGcHUDM;mR;yGfgSOfSfByK=HtDly3Yvb`I0D_C{PW`wC zy1-vkgxHO0k&D3Zql>T%c{%}tW}?gp^IL>x#QpdHfXbP7&Z~=YM6)qJfRvF1-MOBR zFcwNxB+2?4grCtpBtny~KRNmL>T^8y;TQ=02BfZ=c9+q({XLE0a+H=TaF@mJ++gYp z(Fct%>K(88-4~V0qsy)-^DDZo*VhcY=D{0s(fpYGSsIH7v!2B{d6; z*u1?(QN8#SxhLiiI;@*YFYp;cOTJ^TLqtdK#)MWiw@~j$%K<yv!PX`VqHY9pCJR_+xdh_O&yZnQ-8!nLi$hFxm*>#yuMY;7s zC6Uhu`JJPagDx=jcf_Gnkob0D-fc;tR5ZklF3=kE9ENmAtZ~3#7@-O!9F*oTFY922 zLZzYp;{9CRz$7u6Nm|q*NQ*B4t(2y9zZ;G&IpR1`hr}d~DPJP|t!8CuC9j3y{AeCF z<})%PRnX?AV`?i`Y0iH$g@k}BzHKh^P+WZd$t?E!F90t1ShUyS!SDnPQhXsN(cHjr zY)ib)y|GZ{p{9Q`Z=Wl3^5Pa4(SEI1$~TSc$PreGGw?xQYb=Ot0 z=knJgd)-lRa&&dVm*8t!I)&r4Ri3qfhPU@JdkL!Gx*J$4;_>G={YsuMQmVC}p(9>T zSYY5Mddsa#<-heh2SnYbug^LbW~4O7RG7CV*M&lhndEv*3>Jk^YkHdY&^O!_O|A^M1RrF?r+0)ewUh-4$1{*DIJQy%Y}f z0R9?Su;VB`0)0dm#Ie(2Gtu5)aAn6vd=DY9H6ewKK&;;5t~Gn@d0_Nfar>ImGmCN^cf!rzSxeT&t;z{yZwUKwNGQwISUuP@ zQ9am0$2-ebokgC-b`nP@^YCG`F7#4SUrlZQ(F>XhU@8z#FJ|YsI6<_SN00)oM?&|A zzT;fB|9Aol>w@r3b2eCA2y|B2fXm=eVPB}XHK)dbBWzC*sa#lK!s&Bg6^#teRa|{f z+w8&`(J?>Q#LE;%n%cpE_#elo-`#-#AWgy6{FOt{l2y}~zMVR|3VgQkf{>*)+qOwh z=L*9-)gQd5-Fj*2j8Jqt#+jp&X>Jbu{3j>8p%jC_dRdk1G3zV3Ci?+v+9~@tNTa3p zo&>OmG&EhbCNP?2yS!p0uQ9JM3yG=&s-c82svJQo7;h!|%9)s_Zr>?gB4hw+LIeqU zPDmv!%GbUaH~{5sZ8ojXPyEg}EM#U?Y!-egNOlD+Q_4ZE-hXJ3$uEdr% zL6`4+NT0~bV*8B(L9(Mml+#gODCTZhog+r2(z}7`HNH-_ z(}u}Ip5sbK^|p=8ris^g*cS#PKFRrL`yR1Rdk;D)i+WVKQG18V*v63Y*#1R9h#ERF5(HJ#wZGvz9BvLT$#a$Ip zV0Z^?e&`RSXQv5A*JQ1{XjKW<)TB=NUs2N%aiy{orn@xn*4XKjtl49J*_{v8U$Dbg z6BQKd_wGZgVtmz6x&hC$v`V7?Z4DxGcxJR0WC*$b9v|lCSk%!gQQ#&BoBT}f4qp6} zZ=N#DFk?{={#SgEqYvFGjKz^9JgYX-sAM-1@Cubye9I+!Z3LE0vD^ukyj^@q*$^#u zhn7QEwjyDqkJPgRBS1r<1H_n#LL&iGUo+KA4R-60K>!i@vo^ylj6ZQZU7z}KFSN4S z_c`R)%F@;O%iA?3v(OQjj~Ibu_w~0$Um@$k@dlwz^pm4dI<>V2oED_=zqe&mjo~Ds zy!0D?0I3e2C=CZt$YociauR#=Gg~|~2*;>8-nA^8L1uoJ91*s1eSP^*K#HqBVawJi~#dwQN(Vo&7iD@7x;QJgpfnH4Fa;;rXaxlFTwNfz&Os@Oh8K$I&?NgiJhOfv zf``rC7>f@kHU+7j$}bLlDWhzO8@2gAyuJB9 zl=~n5f6nQYY)P^&bIP#|*`ma7FE5@Af>wG_d!RMFH?dB&pKg_shuGjT^J|2(z<71_}a3U)J$<}Z0v@_ZL z7Cn{WiYyE_NxM%}Xiu@pP(!9aIAPZ(agXWVsu{TAAWkg)_oo{UfJBw-0dzu9t!eiL zOEE!{Tjps{bh7SNE!WfQ#OJ`$-~zp+NeNEOf!Bps-@D%;F}>}x_ml=~gwv0DXun?j zf{S9)W>~GX=`((C8QYWZ%q~4Tj~(-cLV7o(urnL%12k@l_X0T+BC+GQ8H6OV>T_N> z?h=myoA283%qUJq*eHV`j0;Adtga-S&K*?NAtIq3HuO;7m^-ZVMswV`8l@%|{O#G= z`_!-i{gzF?Q-U{a`755Jt=W^fws(V#l9k2QIz2YekC69CGUTrXrM#(DvsKRET$AhO z8Ke9ZCGFz^bJ)vHg8*s_d88%0vHz{VaVqPW2cIl`EY}Ghb^!PPCxUl>143*A%h&Dw zmg8jW{7m-N0Z_j)uxo<7#W0tIOO?>ge6Nr!S_nZnj0U!#p+S$hhpKP!dOrm0QE+Fa z!HI$R8SDm8>Dl1i;5CpU`BK5giprKY+tiQJ&<~=Y@{T}Axo`nx4Tan@z&Yl84fX-m zPB=HNlDmk5!RzJSizhtC7-Itl)59VGE5WT{m@KE&KtILf$&Oy~r2ED0S^M-j=D#!8 z7{t^Mbvw@ao2G~SolN{xtBbG%dII0L1(q=Pr(W%mw?;*P>W+*OH0wDK1mg1x#SCYVAiTLdA} z$?Ci%#+lL?-n0C-seIUbMSvrT*MoM=3$G*O&z>aC!m zrza0d?~KPTU*b5d4av{IK$+h!w)b3c9F_v0Y2yfs=`%g^3bY6d;6nMe^EA}P`Q1+l ze#t>65<~!*&wnqu({VTKLJ)VJR8T6@sm$3(LrAum3Y6jI1;O1@M4mg_DwCW3CW@hA zW_FsWz;J=2=V@vE&Tn9n8l9`(e$id%6E5t|o0?$b+{MxXV(BmM0D2wdnb<2RKqO~g zq)BBk-Z2AJWYyXB+8h^(jZw^1J*(q#xEDj%_JAfEA3cU?_C(_lAf{c9E#Z-5A>**X zW@M>%=GDAFlXIR!GM5G#Tjx%v7-sFyyZQY|`-TvTptRzix#++y605-h zmGb||D2Q>qI*>B~_!!CeguMwIJy-)^X`uI8(K%pO#6}4717O#B;OQ|~nNy#PU$xac zjI*S@g47=oF8BHITIY%NaiD|fhy3iMdtUIYt%FdCr<*T(=~wu!gC>*X^hUd0@3n#a zBC0GnT?q7YJJB8Ut~R7{bHGD-vgqy^eIHX1)4{TwsO0{pql=a&dO4czgOt99XrakI zww4QH!9Q`(P-n@MeEHc-b8mo5SRz?;e?hRRQnRUZcd&y=4{BaY=Xst_)aQb=@4H?= z8hNpc67lk0H5pJyl-J;c0pmV95 zo!0oQ4dV{vc(a5P5T{aTk|s%mQAkV!_H^cqO<#Hlx#oC2eG1C#rU;fJ^{^W-r*ePXYOZ4!ZwmH2t-m|aPaCa&A=s{T# z+Vl4WVt~+t;6#y%+_U4dL9@{=YYqXp4SMmqN)NgerSAuR^_gs&@PR`NIkoi^v;P_< z9JD#b2mWwY>-BfReCKt&|2eHMxD|eoclG7|yif8$=8Dz1T#RRzD8i;ad%v^xo9e|M zw@SjXUVM#veSOk)NVvb#xhEk?y4Fu5y3QV4N>R{r+vBe|eeSX~P<7fsa;MIvppYyqa zxMSrhnV!SKN%fs>EKH_EjazpWw<+PzO}+2u94Q&p%s~Uw+St=*MF!v0`-I@lo6}h$ z8STJO1!G(YQ=VIq92GmSRvH53#%cg7+%IV}!`zWP#dSLhweKMGK;vmT1u|)H|FQ3-9~$ow*de z&!ugzrqhuZ+r6X5(34z7$aPuVe$)rTz_;pgN|W_*CBArFocNfz=`aVlx~zt6U}Ngs z>*|JAg^M}m_ZLp;C_CUQ)3F<3y!h48_=Y&uq_n4wurt(y ziUL7RMf%ib%v8~jEQGLx_VKDF!t~VOeL24@ahZpJQDTldC^#R|Ms9iA)zp z(D$&R=a@X#?(u=9LNk-j1DNl%Wa*PO9#?fE3PXs=h86yg7Mnro?m##@+$IZg2%MgY zz0e%cCFgXHVmy--Dw_tr8mH`hk&<_paQ_)>C0v!Lir@L=dLL;K5;KUc)Dip{{4n}w zS`g^C!Vj8@wF6I~;#LX#A(p4Nl?)YR;eUsNwF!4_wymwoWK!UeKj2%uTkKzpTH8{; zHDnY`Y&BHB=DaDANi8pxoncYELvP?!-nAP@*92{(VdPfyw@|7%{wHg%xtnbcG%NY| zozd^%M&}twH^NmP;cz`sE3&F7Xr|TH>2;&~M+AAiE2Lxf93*VT!G^E%x=Or(-f2#8 z`7wq&y#rfpF%gSOPx+dc&TzVip78)k?f^$%I(CpHR;HGrrO>OFb~=x_v*(Whwa5+d zf{*Z(+V{$UY8kP03yxoCNF+cP3DXS%5mz3Sy~G+oE5U6ngv>YEjD!PBtGfWXFO)Ks zg?a%fzBKtO)~|0NtL>==@UFQthSMjzGV;@)wfT6Xx1I5kJTr;?SZgOZfipj2zTxoGw{IfPdYx)g$Tdt(xv@s z)9|7iDhSt+e98%om65?dHy*G<9*k$6&*!vT=nlu;^jHh0iqL$^-Gy`L6_^62{9h^@ z?{flK_Xja8b$`oqkC)%0q|&SXgH(R%!3-S>#;;VZE}_ofrRG{4&Xi3o!I_^|Qt?c$ zMg_7khYZQ?I=>%7)H;mgl?8L9hf&@f+Vl_#dZoEpyq z#*Gjpi)W|#r(C+kcz$_-r&Ag#9Hhb{0Cd^-8IQH~Sl39SgGb@d_}wqdL^CF@Kl%tO z(M%bfa2@pV@`VqG!?{|M<&N)$xV>|7(bxS8oQqwQqD>Mo^*5Yc*b41~x_T!V?1+FD z5Zs5xeaSGKwKvNH#iaC*&SQDbSz6UYo!CV151*{Hamt8Z4p2E}|6Bz5$W}XP0$`iu z0|STnKlA2Ez{D?V0qf|cG@$(JfLnFCfV;kw6&D42(IoLF_!mYx_p>AQ1i~A;NL&!_ z{NEGto_HV!NOkKg6xsU%iUsIQ;oUP>jUIs(RKQXkp5Er%Nbb}+MdHb_Be$8)o4R1B zYQbnnLuShxg5^lu?kf!j-sBZL^7M68c)?Ccy76!l9+CLh3&_5igV8m_njhrw=S)%; zcqr9UOr>aubhRtPnVRNvy4y#Y)nGiZgu5n1GWc5E+tOI-+>pW*JFssTv6^i-NNZWT z+utdWq>2q>!2}H|iOw;c`|TeSjnvJoFwT+^s=Yh|JDjW{bTad*`Y#m;`Tl4j5H4x_ z)*d1MaBPse__h0EbGP&0Nr^uvx-9Th=0Cw|yGO950)QzLoC1u^Ae;}h!9WP(u9q$} zFsTxE1;0XV{F53?!i>!ATTFr|*guE83S=RqaX}nybmGhsvD2&wB)*bo>|apf`9CLB z(-aAZ{KCi@d;3rWxp3u~*NrjVi>`(~7IMKb5O5x#XIwU~AsIm)J~_#T?;RVIdh>ah9JbX$?CT%G$K{iCCa*3}#s%ai%$ug$g4^FJkDODZzjXXNh#-+*R=EE;i zI&@1}re{kz@Eid_GCW{qK=xk$Cj7}`E!dXP@;T^x)7PQugvsjNDEu`36s)?d1`jN> z5S~#Qm=+)|_guD5Zz`ShKVBOVuZ4ZY&Z2N=NnIxJS7-;FjTSW?7Uf@p1g(|u@mawT zS&uhSO831!z$&WD9Al}dz%ewr&YyL2s`wYiQDU#{^D#Z`KFY%WjXqHfIhA7!@Pcfx zv-xtv5(a+9`^y`w#Yq&ViCLl8QONVG$7MJn#N_HV&(e+;*AUki}~v?Ir? ziNR6bDWKr~cn;qv=c@o?i!d*6VXv(>JLPNN!iV2Je>Rs11%+I{FV7)pJegM&d{sDs z>!1S9vj7}tYR0^QbFfoYHUo#LTQ*Z8&TbcVm5CQ`*V)Hu2P`i@ox@Vj``i_klxpbD zbty_6$?~7zewXU8N++z2n%4-`?P-|tJ%;<^CgUsPHN*d;HCT%R%S4HqmE31GzEvTX z;qQ;a>vkIAlrKzBy|k56C~}uF&emYpT#;WHj+FTo(3cX5-5Bj5NU^Tx1-pk zaXpkC2cU8QU!_xM;Snex_rW%MLKW1~{nGe;Ut#ImOul9}bqT%M~w;C#fft@o1{E{m)H{i&PLB|7az&Rd;-+@ss(C_5x! zEo2$F`X@%I4k=BAH}f>o-n_UB9xVeofytlhmxkAQE-N+PR)A5i+@jfBhS1{$zB*_b z!IF39$7%xrHh?qz{omjRSq&V6kWP9W~gulch#(q}69C+1T-@|M!{ z_z14vLG0%0!cduR8~e5dd;5+C9RHMm4*GSSi;z7tv_r~vI7wI;j5TGix(vozh+wl> zO3x@FHwI#gJP!mByK76&RxGZsuzBgqq%zWQXn?*=Mbui%##$BF-;CDX`&RST!MOL* zlO>1!_c8NgkV=TvQx#R|NA4Vx(Fa2@vp&)yrglmas2`hyZW1Qs|KNmBRcS zh$awi*o^=X*sU^NbDuzIFA0Z^=Sc~KPwxU-K+hjQISpK}qVU{(#|2XS|Lr|O0}Z@s z0c=wGJa~J9ZCwhyFE2Thr@TVIgrr;tOZh^58RqgI;DX+50ivK!R%PfG($oH=Mb9W` z0oN%PW}DxziO&tAd!kc*^dj__LGiNzADdCiVwTLHhq?X^;)MW?g>f3tI;Yazw;wH> zne|6zGD2SIKo}VVRCi8jf1O@!pLEakHUCGWEJv2knQ|MVmxqmq$TtmQgVWQMw}a*G zqGCQVvlh$o4eRF@8s0be5!x))$^g&D@8_4WFqFOJzLzG@1rY%V&DF^6Qh+Dlb2R#F z3F+o25T*&?Y}0A!3Ww_0Z!9i8V$&G6Z5d|v#40$-xoaeTb$}o>kEJrYkS)*r@cP}g z5~7$dA(pGT7`|3tu|MPC{sjAR3>KGo&m_XMCr}v?C>MxnX~wOd?%{x;uB&0Z+JEjq zzP3@P7HIlDqUiToN%KvOzOI-AZu)IB4qlBvu z1mfEy)@boD6aFj6a%&w(Z_a{)U<&`0!jokTr_76^>~{aekKh%78&2F4CULW}d5K)s z9F?igy zYD?WSKUQK*4uSy(^>HQL!JIi~G`@I;JtsE6`;q5mKH4QJ@&XgD&+Fr8q*BwLP+iH2 zI&UyBc?V(CX>TFR<3k41oxm-1jOm&0nNLqI{&4Z#S#IZb&zw=#8~-M_#=|%nTQn7K zD~vQIAIdsZe^RSwqWU2l#pOitkA`f$0}jRAgM^;n30LQdUB~xI1;5VW@Ov!+8NNRJ z>Pdt`8|x8TXmv)=$~(hB^wgsn-g}o6ZP=CWYhL$XZfE_bOzVI>>O`jwql7ZjwkbGTMH#;!v zjYSjKRB}nIOT$5X4UhbzXAKI2$E!IQUctuRyREO_{#Yph>e;j5EP+m_-+{y}{mxN~ zz>O*N!uI;Z-T!&vY{r2a9)V~n8D=&p!Mi;-vl-}VJV5&K@-iD3cZ2`^Ni6<4w2{gW zE9VE5`tT&OI`^?3;!K0>dMj%ZS}@oP!SZzp3(a2BRzge_u>~`Ew?jv%7?tC=5FJAX zx5{oTSy48-`!+$;UjC?loJyFxL`u@hi=xcYomw69<8513pn^xlv@3++W6L`7CdjHn z1N;+-vw67IMGTe10tLux70aK{?+;fNob#Kk-=|b%FMYefWe==_7Ru&Mfp>TxaQRGO zH42{jd|sG;3{=hq?mcZqDDd4KGR&e_fb^*gQ#lgyaBMF@r~>dyL22;v+$s2VjRhn7 zC}_&#r6EXjQqZBq8|4g+gAhEr8Q0#iGEikHi8jm9le9O%OK}fgF>Pryz;?X&A|#v0 z3^utr{ig=<=(Fktpls^|pOyt%^ml#!XG@g2h+>njG3e9Mg{PC)+jr^X$tTmW7V@Q+ z!G%KZ>YQ@SEOXwUL{W;V{NvqVm}{TAOa37+yQ0*MIf5?gl?}b&F4P_|Za52!(iRI9 zgy-m9gbFrWAQH$KCV~JzAqp`A+8u;a7WP_k@)~@p`R=X*&^x-FA@?sxD3ccCa0I;Z zH23YB_H`WZ7jdc!^F)OWBJgXvK;~^>grKk|5fM**%xa~T<-r(ti$Tm`S6;%6)Tx~* zvX=9pIZdg&m#qI!bPMeF+}qNS8RW9rnSH$6#<;o2#B4lt(Nmx(jQnQcsUj--&BxZp zM4&@GHbS;y@%uYG39v)801AtRI% zR_kL>SZf8i-mvaQA5Gd*Faa_E^9B zcBYo7f0`}CVrH_??g_4**n+&^!j<^&OLPt|56az?4{E`<-mVBTdy(&*O+n^9yXvPX zMKYu)9SCH0T38~h3*Fd5s(moAV4)nfFF#%nCYcN=)49mE#Wn1}w7#XhlS?G}l~rU} zQa4wBe0iZgJ2m?IVoKRJ--31D-P`<2dnvSQ)$z2fdC2Y!nwx!>78E6fi-zO54%3#s z2$_$sV8Q||jdlQK&5exFOR+el4yQK2V?8R`W52!q{<3s>mjfcGh9{&r8U=xz^wM8p zU)0&Eu$_Wz4iV`oE6l3_eeUPcL<5}f{g5A7Xz!K6j6Y*K(^sc%zL37DHB7=jfM>;{ z*484gj;&0Eu`v*H$Ye#Iv15*S*As%XWlyS;4;e?}&|*2KyBFnKv;y?MMFf~skbjZK z>q#E$Ej@ZAr$_VBAa4psQ!7Ee35;31S8ac|P6zmY@$=~C?#Tpy2UtCrDv@Ck2s*Rw z?seh_5WwLlo9n?H4r%6UupY!<;MMjD;v2HIZ@y!lJz@TP=-f&8Auqxa{nM(7)UIv` zPpaGNS{ z{ugXItEe>TyWX!LYS4AO1yKI@ie=c<3*+lo0DtnUTzKx+3^z;5pGAJ0)zybMrOJ!W zL;l~3{r*6D`ik|*5(lF_f)aiHutqp2CsP^m(J)ytD}-2XE0qG^*Tv@&tY2p5ZeBcn zSSK#zQ6LtbxhXizL@8@sneyR%GRaUgGs!Syc5>>i%GZ(Xrm?E8%R!sf-`o9Tg)fKX zb9b}fO9@17?FI|zU~FCLZb(;=*n8L+&)eQg+AF|IGjdsE3iAEU>ALgHX#5_GO-cp4(z^TJ+WuYC{%AR291Knn5X6`uOy~?iAb47-n<(yne z4xWh7`Bi&tu!`qEs;Oa~Mq;3Ue==nRuD~QF87w3vQ#0`gD(SPf4=1Q5eZN4arJ|R5 zk>Z~`Mw^fo-nm`JdV4*JA4%k56TRhi>N8dY7n$a2J@a5N#96YKH+i{c;j6JZV2pH-g)Q|ccU-Fd zt1q(^4yPprs*+L`Q&~YcZIMmN9Tw)m8GUv!r^0$&U(%&fN$6BlLZqt}C%SMsFtnDj zT0`(4Yj3xjzNp;Sv{yt}sG+r10?)|%%r4oLQh=unn}0T(LI@|kSKRU#*~r|%T5y)` z#5+uzGnmUkT)P|0IV9W{E6b`wbFQ^6lmvLwlE^>7LTnILO*WUDG@{9@(heJc(6i6? z4UV~?6eVG4!eY_uE$;C6QFk(e8(W~(Xq>gB7Uez{IEG$5SEx8pce7ofMb^;nSu`Dz zAv-uDnYFidBK6!)C+Sb|@d#nZ(X8{O(7bqH<5Z0+=-=Wr9A1>WI#iKxmwBl&spm?e zjuPhEEGXN4gfDMyMA}q8|Mx;?^^JkM`=OBM4C!` z)bwyKp~a$`K)UXC7;dWz-4PR__sbiW`K#a;Tvc|)mbXnZ2^=nsn?lJiNuAl9_oe^ zfAT>7(AAj!WMZ96$>sPn66S;qhGW*Yk`^<1$NmvelNd{0!Q*OqJR@kXmtrqpUBpYi zP{7S8UJY!*nWoSgKf7favpFzrRuATJyjuRh zKe>!kpxzRTD!#Aq zd{Uk~dy!b8YdpM1R{WWicR|NO!e1YlIZa{`eO5Kf5^H9Uxyj)y)>turAN}e76(j%W zfe7@b92iMf89>4wEje;Wg~k#rKbFwrN$`{PEY|1${po`LV~Kx9|KrwkqmspUH3$q3 z!3Y(4)fxqd{fr=aZ$0qU=lcVhP$vQb-NEUoC`TO?9fq3-&@&6Rdp7Zx*=4RkMuY!b z=@j{z(a&c?3XtgO>6~s&LJ0UM*##CqXxnPrb)R%YtRlKz?KN!O>jrAo*W1>sb6*GS zn&v)mVu%@ArJe%dMonr}{7Sg8N0488v6oEl+qK?xSh4Wg?rPer{H}LvwNe~f6)5{1 zhaZ4&xe#B9Pp2J1T>uFUEdMlmdLl<4jVQg0^D|e?7X64ISuMvkz<<4CG6a$p?Fxjg z{Gi>lcu>Z{Gn`~EvK;z;FO^(GuQcq?;UCs}*KBB8itO!&t

      zJ*mCi%?;Se5u06O z^kP^+LfxbDT;hN^Z4I+=wCp>&9%Yt9YgIXBz5OMvV(~lJMSRgTy&dx5>ejH*@UHS2 zOswYH7How}hO7JpsaNv69eHDXJxMg~M2=TSIy(<|Iut+PQoeNlA~=3;)8dy|7<87S z;tT6#|3`RUo5%ZMgmQO&9nC+BIGlI!wB#okuUz(^Ue#5f?=2=Rzce1><$<`FEorSs zR`F~_iK#x+QL07-Y#loAHX)wiuMoB0dj=91`Otq>?6n$z-7%q8~}r?B+d$cw5!W^f%jElN%kW++d8+qAoqKhUa%NxdyALg;DxK^z zDOS;t&GR>0D^HE_(_{vXX5KXEbQ2*e$oULa{Bo%*m6BF>-d2ol^U7=tL;Netr1qs` zGRw-OSRAK}H0pYZh$K;yDd*xJSKSVZHM^A5bhx7Gmg`a8Vai&Rm%iiI(wU`>+`2cvix3>`h6~M)AcTQ);50`{^PSKdxPu=VhMni3OhOca{wK;2I7S|O zt%J{7_Vzt`m+dJZ7kK+%`(4aFp2S`N9T{OE7)f}yGrU)R*F$1mZ{3!*Ze4_WahcE> z<;gW~_i?A$fsh@9*ff;hF$HjTQ4AW75{x&c?)TViU5VHNLCu`~L5x+u2c} zyRjQa@0(8DenV|;_|P}-j$F7pT!%eEJNXH&-&nm(IIT{I4s>|OmcMLY!1&O!zbMN)M?G0#pk?c#Pr1!ER zSAEZ{GyBg;^IQzqbdh;Cr!HPoPttJ97nR70i*RAQD-LyJnYpUTO-A1zc(|AlujF_B zQHcC?k$m%`yj(c&+YDH_!7q%*( zPUBQz*9!R4F6Vj)G}bMHI1>NYQ<4*WH)sJYk!IkrOKI5Stq=8Zjt5Fr+TxnM-uFc6 z7xDP-vB&P&jht6#P?y#0Z!{_PJ1vwS1YZm`H&)GJu^X}Ba>Z97+>?=DHd%Jc^y1Z} zRys&}83(Dkb!tskQJfAx{MeTW+bCJPXB?yR&m1~Ycfqlab@+A66i+)Z!S)nJ4+9+ooAVcr~0!YQ&h z4uuzeZDkf*onZ;GD`$Me&(|;JuXjxwJ^o;OqGxdQ<+Fj9461s$vqWytL%i#`mTH?i zrI$ja9;cemR?&}FoEgp(;adk?szp#Ect99Zz%}KLXHXN{ZB^f#y!iEZHeUJl*V;{r z&5OyXypJ!gqaOx;j|k96uX8u-^N${HGFi#vxoV`=fi~FM6;259yHZWR^GTtehI?MR zdEE9Vur1W*Fv3ren!{aaX@+mJQ`T|O`4yWy3NJISB8$ptOZ~F3^aqtuWxM420rkIu z*x&FvR*np;QjYxHx|~Iq7?GIjqCmry1V8!3FZC)$)L})Pjw}TiYQW>hIHc9nP=_N+ z$&Z)Y%v{F(r0!y^S3Ng-plmT`7KXN~cXWtso$FXC-FJlNLa|QOM(N1J+B6Ru+^=d5 z3(#ukV*Ex--0PR}cFk51zv7%BZ}vtOXsnj_^DSN+m^bDgg5}sR??0RWG;S_CKtO+SUZgU;#Ct5JlK@P$QSn2c=p6KDBN1r&2qHQ@)lFm5m!2) zV4o~PG;;}MS8)QG{wA6k5pGzQuIjehT(EMib8C2>R{N>E^3WC3X~x62XZ6zmJgZmk zhu}4wM*fu_R*2u}PJM4#6ZGICSfx{nqV~pJt)yyuN>tG9Mu>cGYz5mij*NnV?~_y9 zaRrz#Ky91}oN1m?;P`nA`?W_!j)&{`^TwNfbA1&TILg{iw|?!sKyJmhGl$oHyo>Om)}Tb);QMy|gT zjD(+5tIe?Rm7(~g&xBB&I zVw~2MahyB5aLpf@Pu=*iX6uI~F`#9D5>#)EzB1lY^=c^$9Z>?*c97qVCJN zpFhDFf{aO-dwDwBvKQX6LR=Qt#ws6iLha))^0{8UZWIlBO4vDjjUanDb`1^fioK;; z)$H}-l(x~f0EVVyJd%d3GaV@ctGz>!B>!t81Eb-%wxL+MOHyL>ElXZS`)=Mc58#x2wKrdD;3Rv#kC3i?)Y;^6N{f zGg@VNDyD(gFG$}{p)&m;xI?wm!e4HcY(d1_Q>XkXK;paCiJMsPvk8K^0{-e0lgeV zeB0=e66YY9%0;;Rk4|X)Q?q~UlV!~N9**b)UU;|G}q1pX(B`i34R~Vj8xFjN8u2ntOgmKeRdeD@K(mw(m{O6)pJ8^6FI>>GDFB|-iC&A6M^iCrpKYhZl@64wcZr;hSHwRy8_3S#-1QjajqLa6pxAJ_&ln?qZo3$FnBm0kzRXb9Lt~pLg#L8bX@XHiy8 z5NF?$&_3_hu`iJe6NG0*41yBqrD@shWZ4u)bh?DmO$vzAyIA7EnvMNv$t2dho{oX- zY*BC7f&~ND=q!d#xWOb$7i>kreO$yr{-3~&X@NTeSMv6C%iPQ= zU2st1TfwdiXhkfe=O(_fzNnQ%MA>qDg`6jGXM?J1ABdlOccHVjt#fWZH0|7lNd3`# zQEAk5@lM@SPkO4k`omKJl)cjQEDOC)Oy|X#IU&V^9LTO8_OaO-KU-q8q*b4j7&JG4e+1UT5zOmoMZPN}!FEW&>rKO?9t>c0pYdx2R7|YR*WT+p!%3WxmK45m z&G|aYR-#H?MMc5cnyL4{){5Ia4Dx(85Q6G@Wt|qUefbL18jgyTXY=agHE(IX=0M-W z-?CzD{N^$*j8cb%`wtX$v|`3J*-aDSfzeY}PXaqT{9-`TQX(<$CS2{WIa<5oOi9KT z+iM*De9qwMDo1-FdMmF|O9kTIgL$zSIx3}cw%NrpQ{(eOcf{D%uxCJJ)6vtqwH+lpHe72*<(*+^#TmhGMr z&}l!Rq++lz=12J2PzaHKVIf;8?D|eyudg#lP(emC zjeXw`gLD3Z7VFD+3Jx-7KRv3S{``Df<+yBWpcHFBk9ujq&DGc{-w|0Tf}S3|R9RqC zr;sg?Z{^_)>TpTbsd-`&#%JETmLOGzj$lrer}SDHRzC9Q$)zQ{0*9s#<>6?Z6FJaU z%Er0jdwbv$Zc3$B@duj?Nrk535M-Y3U$2K^R{1~gstI1x#Ji5dZ3_+b`RPYnHvkgs z-=9(mGX;Jq_`(7r5rFu#AS&S8K@UPFy<}Q3Afxg#hzNKQk~*E@HzbyKu4mS~28Z&J z^T=9l%j$D-|IERhW~J4D&m#k0HQc30-G2Fs`!izetoOgp$TuDwC0T zTHEl}##Z5o`G>t`@LYs$5&gQA*Z<6eM9hn$c8V1@`b{89U1B_l8pNfJvY{qytHqV_ zH%e~mhIZ~%6c-xiduiZqY5n_E^1wF1YcWm<-~4)DJr_?UF1jY<;_FDyvYRT(=fQgG z?kMgoM4+3Ri}AH`*ba<=h6D51ee4|m87L9ZEY5B)N^BUO@T~+eWbA*QHKzzo%-=Q6 z)V7_#DPo>1=R0EqoyKbQTCAHon%nYEG?`>rom8|nWWB3P8w?Fl%_z@ix|CdvRPxcX zPr|q~xvH6c<4Kk|QRF6xe~o8q4HXq7QRG8JT-eFXg);lYJ=`$YvJ85!fyY%}k?;A( zUn#jB%|o3>PNnp|@`?{M8LyLedy+ePf8~2>8K-D??HzDJWpf>p31NuCxC8L%dcoT{ z(Gh^lNfdy`VllpaHSRLhK%$U5+HOlRXh))q!aDt*EL**2`W=5RV|KkM>gw~k-`+(| z9y`=jMd>Z{nutdG?UZ;GI;@-7WCeW>&w1SR&6z<9%5*7~Q7?h8r`X;z=l7gN0S}`2 zZM18-(w~})!+D|pi}G)YE;UveWsZ}H6_mkpKt^?~o>mhX&GVRfT3jC6Q~E0kn7Pt` zfnQ)0x?D5NrDgT8Kl&Nd#v1}(wk6uazHDl?IM(8ix4+3WzOD$pE?l+RF*fyzwUEO! zS9|yU_Xm3G`=Vq#T)$tG(f--WdFT1b6b#?NPpY^Q_ulXyIFN)f_D?Vwd%9VF_@B?` za#f|}FI79fuy2{-iI@}zD=Iq~cx0$sCbDO)iRSC+buZzpOGom~-*}UX{h~Ek?ndia z@h`jkn0r+xNYD12(OFq0Fh#IwM?UYMQ*dWE%6gaHe&5^YGq!FVDeE&5A93NTu^qx= zw1M5;G~V*crWfdAmJYAl$fKL136Wp?^W~KlmE2@Svw&XWF>5RqEFo)EfsjsOIaa1H z0;0b^X1gUHCx-Te=N*3yk=z=qOU1u~T@ zskVA0GQOygOLeN28?SUKE;j*et1C})vIl@c;Eu&*P=$*X;t0`85B`@_duBnz%kVv- zBrI5fbE~-bNFe?h|1+E~kfhyqr)Tr_^~{9aTgRQ@szbfisw;jfQIg9Y_eY{WY#5D2 zMh||U@S5eBIx^afabgIiG~aGx{J!;CY`Rx z_OO1Ja3@xP)=+VoSB;5YcIg3&g@>j4ErNlq1}H#kkoDFH_|`50E5rh8+Ihx&8hCf& z%Y^2>dpLhE6wqyJy4uRI8h%he4h0Rpx*kuEU6G2AxoMaAv4INT<9NT?DcK#)IwLD) zuct!}O3hML)?yo8C0Cd~qoz7j6-@E_vNe-1L*~^f%_h~v9W~z8_G#QH4dc}SkWJ#tY-Oh`G)HNUBmQEwK zF2Juq5*2X}uO=8IG`BH_6A9wSM-c2AbPyHf%fgXdiDa6@!rK;&EO2#vL+cqOawz1tOc&}N)vMJrxTVRy z6*&>UcQbZpHlouWNHoJUUpvONTykP5!qy~lGsB)Le;=8B(gUe3pS?`N1tYH2B7z~M zmL;uPyRe$#&f)hHH~c2AVX(Vf9(#YA9|ttlDBej<_8NEh6uio{zVq9tKWxd{*EfIA zTn=b(gnM;3;hMJ87R@e2P!Hm#+{HtaeuJ*H-JJVv)R`f>g@JFmc0{@jdVUysCy}M_ z3a5JpSi~l&$%8ylN@IYXHNG&?7oh+Bw`Y9Ui}uG0)Q{IG>==#d*L1746)td%Tx`L}4I24|V{yN45G%cy!mpQ67<|0^=?MMx+kCS} zL=mUT^tfUb^&^yIhI4U5Y_AJ6g}q>76sCz>UDYphkQ9tKh%G=+-R{(-t@x$1$~AxU z(6KFSQ4Z7czIB15saq!4vz$H9$6mT)L{q{ha;`sIh!R?!KZ5fH=`}jgkcffo5}C0+ z6?LdD=}Y{rVNq->Q$?q(DH}Z*hYLby6y)(oE+TetFcd2(`e#l68ij;mn6 zw0huDp5EXfot9}-rev?4xj(r)g{e91)?h1^uTtXG`Tf`*$V<6l_5Z8hoo27N?tO%E zk?iQ^>WyLXre907<%59Pk9m7;Qb!;_fRBl*P$p>{G7tO55)t{(8{y;Q6 zfqUUGS@`chos;K(3tdd}n11lrM>lILWOw!PCv|47VXhRvqbqNz_HnDuRJox%8|U=Q zzg&~Xl9q?Wdod3%x!z88XQYLPirG%Zi}p{|+{xkj;roMkj|5 zL;BguMAoHrDsgbLCKodf+A|LBm4rJ#sTr+C9Z;RNH^QK1|IUopy6p_@c6Z6cz6+pb z-3an4QMtdcK_W{+^LINnDCb+OE3gstn`g<1WmDEos&@G|gNSt<>zT5W(Bs3hv;P;P z-%@H`Q2W(Voq=b?h?boS&%5+RI4Z&-%=K;0+hmm-s%3pj9(5YK}JbhNrySrFS90y$W4mbc;M-cTMA=k z=i*AW6+IxE^YD!&t&4-I_8d9J*P3~bA&Pr827nBmt zHpqIlG&t33oahZSz;hct zKwBY8{c>WZqP2vrvZda@XRg+0hJPyMZqHb4rI@iCgAHmG(2%vnQNh#+pxHq6T+4FnsfBi#3zTIOZ3mW&SbR|~@5_AK0zxm@4U6uut&tls}7aR{{* zt?JKY<*}CA*5^;nM3&@^MCQ3NJEjJ&TRXjEqKz900}ZRk;~Vs%?hdU68pxfo-&|rY zeD%s(y72}rkr7oCtzw32zo@d$Ft5?%qPpUV0mx(Ns=DI7v^pe=q6v{2c8g3vJ!l-& zzp>?*f^kHknp2*s!{J4XNLY4vKfZsyc|M~vgy+yr5aJ8z^$sJj!(37Z%9i)l6Ov%O zHaDHOSS_j;&wqE^<%Bd1ENBH{;#*_B{r}%YyW6&t}!5bIhKC zVK|GQ^R#^(>Xa-bki8P9d5JOhnCCHYeykyjX_JTYQ?ISQW!C=Bxwa;v6l3&ILmiSt={RcY_{E6ygk1wTRXjIYi#v?eavq*$P4=q=ksj`A>sh9`BPmk zTN8LnUX^&+6!lyfdQ?&UuHhgZw`?uxtBq`S%5XbguV>5(ajnz}HmPM84&qyfP2Cye zZ%!&aEV*fN_51|~DY3KQD8_aiv=Zg&qpV<3RQMtwLVKc`L{xzL3$sHP581%g zE_SYUT3hIScriRT1Yb{oE#x*F0&FLK~?i3Mum{1L15|@!3kmW6js+=5zIy74o%T>J_9|0h`lf z#Ea*zx+yBA(Tzn4i{S8>*9N&fz7CHrIrPv58rt$7K{mAd|nz=M0TRJgQ9Wgm$? zbDhRPh`@&POtVjU3+VkGD?88cv!~*RkNC~_UU-5%O`mLQlW|UMsVmZ@{r>__tH zpY#2X&#Jo1r}r#;o@>2nRPzInN2VLLuES%TjpX^m<_7-_i9GKDC#%B&Mj$$`_f0Pwa-QFIceJ;rj;q~6G8OIcg`wu(50OV`S?sXm{7?o0| z#`2EqC8;jtm#VSWVnT~7?gjI5u&eIA8g{#y`D3m;m6wOoaDU+RJdG7CMB(t+_kYe@ zet>JFu0)-Q3o;fonkxuKGb%NJmRn<+mTyzdczCX~2^Uh@Uw$d3mS^;%B2Vs5Y@U+) z))}hY*DFyeWD!R<5E=J;C#Ey-{v|EqpLPdrkF&?2{t8nKwe$z1Y&b$7BDMP~c9;`c z*@G4myf1xbk=A7}4?o!Md2S)xX}W98SD6&3&0$~K6|KC#1hqEYjhmO7#XccOPR&lu zdC!I353{TGb_k0Vo2343c)U}BuQf*TJ^_SR5mzW@P;&xoc3Pe5?p6}XW)+6HpKp1L z)5m(8$%Ylj54n^PlUDnmP~-<~ey`7e@%!D9J3in6*LCJRj@NjW z)xZv;|40xQ9r%vrlw5CmKmgMMkC?=lA73X{m$-PJr3Vl}OmP85S<`KX>Yhu)HSV$q z1BhYrTVq~!;l$^P9DzZ2c>a>&P1|Ax0w_J-;J0v#(34_;d`<0W%G z^u9JL>Wyjz6xVA9_cNB2Br!&LUW{Hi8zr?cjow4i62+h7+W6TfQ9Q! z2~Hv48GEhmuQDz5{5PJk>#{~WhAP=$+(*MCj^A%l=$!qwvo|PlOX;#i&=)0J9q2?X zWU1NR*+=5x&}8G8#IP|DPi;0Ad=(AihFR_1254}&a#c~2$ZK&h8rZZ*RjHP9sYV=V zZ^?G2a(9g+ZbFer@98E+@4I!4PY{YVJg0N$r+2daH4i?Y0Y4ksj=+uZ*ODi`7DJzEMh z$OsiK{;P?6SVqihv)S%QDsH1_>Yg zl{l;Ep@fgi8pT0BH(yS^R}mZ;8g(w4nRymELv+V`X)}nh$F~W$5DiuT5T^+WuHgiY z4ITf-H#>0t56LrtR}YN+#HmRnH+0tir*RMZs^Y+sls_ z7~vLxY{Tf*7mm|H+0e^SDvu)_lX3kFd*6-bm8J7ERb9^l?1Zt%~>>S$flw zjEF0hN0i{TUP6(jW@yCi^7Ab6ViC`PyD)T!T80d-b?EQW*s4Wkuqj-xT`-q2ggPdW z0Y1m8Y`l-Mgq9@0S^5%h2d%!10pejUt+NgZDBj%y8Q~B0PS%rJ(JWfhjb& zG!%8I>dTJ<745l}hs9LJb8c5?*6^#jx;=ts9*se|COx5@l5DDpAX{o`N#~I~lx+$X zmE9Z7#BnrB6;()HRlAe{VBtZ|Ejw2Loy5aDL&5b!?3oNT1;_pieIAf-@3?Z0zXap( zPH+U%06N*xnefp4v>F-k*7PPF%(UgJC;=Ypwkh%SknS`6MMbag5op zBfEU(4a3xdC>Tsi44E8@1VdV!~{qpppUOd55jS)s&ArkHKzeD_EgSs<`k{K zm{mJWh5(|pX(0MWKd=IB)P;d-v~w7{`OnQm6O*LGX0N;}Pmk;R{%^Q9vEAB1 z0r|9E6;bhWcEbirn;O8-B@WG!?3RuYjtSN3j(un?*DX+>=DNE@Xh&radC)f(t3KmF z3tBiUUTMt8vm04Y4(cj$BIyRf=;v&t%8!e>aXsTg#I0J?X#@&=ivRHmU(B4;u56FYaa z&bGc9W`uq|a&E)Xu$VsN5ykM`luL3D&OyJ|#p8xePxtz(I2LM_RX!(mPr2JSC%`%e@0z;myB@BLb5NpdZ32JfouNLGF>WKwXC}qE=NV8K1`3KUE>6W@Ayw|!eWkT~ z+lSWSYiGbV+Y~22f)fD>8EO1$4d|DHYod1ra_9>S%&82%$6si&KypHqE>Ph74|Wb6 zYQsH~!~O$ocZu}&uZSdu_v`$3EH`&@=aR4J(5pG3`-|fe$arG*C^L;v=23-*Ek#+r z{JCTNwVX&tFXzvJ;I=|kTA_+-edfSWfL2@pi&)`OXH%vspMke6wbTe~*D;{Z5>5wj z$K-Q4MEYRxnLN+JJ2m`YK4Wxdeo5nQ!ZU4{{LzH|6vhC*qkb77oEj8&RUAE zA6;QN0G}b$*=CIKvt=}!zADG5o+KwRqtBqzhst<{yFVt=nIy{D$OV7Z8PiKP zTTauhiGBVLV9U#Xh=Z-ssvukQ>={H!Y~nVn-MO(uEr&k+SKC~yT&5zFu^sT3HcRrT zY0y$foGUQ>8&=y_qk>1RItkmf%8J5j_+V@OfuIuw$tr36_^u_#K>{opQ%KYyN1BhO ze#4a0;2n^?>h(@;0|4g*f>w3#b|$WN^c)@*3$CTpv1h(z0(+HPye-~)l$<+__F|U{ zRSxKNVuhRDunaVPk|>O^X9?e%@iOhR|NQiO$FhY<-(D@mXIBo>>nNMZ|Ou2qdTEVqG=UHuMD{$W-pjp&8XF9ex^2yDQ!Vf;jq26pfq? z7ysr({+v*Bj1T2_-~_5@&Fy!~7$ zEGC2Gniz>NM7Txt*wl7CpK*-mC2Y?kOP2|b)h2W2PsIOsOpy{YwY0)}@~#UjDwtmT zDOC*2*(_uwmU3mY_*P(@2R6-GJFHTr|3#-~LA2dWZ|t+kGFV9S-Fx?%eQtN8DZcD@ z^{Ok$dpW5N6Q0VJ%^I0Ln!h46ad0yj9xsjCBHA|hle3F1d0R4K79+?@qh_S6Iv4wC zg88Q@crY>x45oS6Bx-%NM-pMNB$4>)D_=$vnEqYbZwXqqEp9TU_QVwBmX_{3KxQ7sW}o4GQJQJ;IG7dSZaGV!!_Wv zjkfLC3}k+gRJ~loWBZFvw>|TlM&14hzT;N<2Xxf-^e_LMwY_@cPT`q|(9>=i+jAKa zE<|}7yv2~C^m!9-w`=5Rl>h8~u)IcPl*w${Y;1%x_%DdAn#bprS~0M31->N7WUSFqr_fo<5xNff=hO+xsa~~sHYKY@@A4J>R=a>Wmrm&?hyL^l~hjhJW32(UyRUE4|q09j!?ggKjU~zgJE8wtCHI)e2Tv1JNwKv+99ZDe#A=d z_lmCXuI2d4aW-Fpvmj`}eZ!f|i)YtD&~{*>jBP#3Ni;0=QswY1tUYHxI}rl;X!c_> zC*V2gEbsoD)8H2&(>c|+Wa)B(I7fGHEYS)4I716;8q{*7GoQQHXy83^gKD0`g^m77C%tgx;X^_Q~{WTT{b?jSSN^0K6&SD;~! zuVuB8wO((8V^?Hg*lY~Jzd3?Ia&slgzjY%bpGCx15zskfvbwq;9##Xb1w~sd-0Ny9 znS;8xa%PC*AFsNQ+^d4@hoRCDL+bJq4x&_4htOWdy5d@{Lis~%FsKx;2a~ggKV3CN z<$qt50xoe@XbV`GgBu5tACj%?SW&}|m?R6#eN5$NJTWpdk(FcWHQfGuZ71#OgQWOa zoqG3HRnb2N-Vu?7qB`RSNiV!I@D?t#;H5^ChcHTiyiMu?LstWS+~=oXWE=1oqtG8kQ=`#J=zXa<_&mM~dzx9y-+S z)mim-$Fj*1==9;@ownC&W2}jIPp(q&i}oh}Ro_6Skh!%k})E?PA-zL>UelH?fg1a&0zs?1h;G%1AIHm~QbO{V?Z`RlKp>x*(*>kIL6 zaZPA?yJthYp>u25h1YJXFNouiG|;l*zQS~S%+~&euF)X#^4ao1uXe_E~a^pV+{%v3*HS- ztInrq`W`Q7lMce=x(2zN)E@P;e;yxD)$p;$!Z?p|1TKYxTRhkrwTIUuYCA&*tn7Gc zGu_8Y;k8Qp{Sb`R8-PaGXu= zgoUein(Z;ci6vj~%TfI|)g`dYp(f|h2IzEvY35pA*;Wxd?QwIU1BYWp*5-5n!P+y4<@f z*0dUZt<1EqRYQXA%By;Rz#<_IWX(yFXkq|9r=;Cz@cK0&=$FLcjQjxbbi*ZDRG%KM zPX5LsetAyq3v2acRFcw}PK#f8H#q7=^aA}s)sD5j-Stn#Y~`2W#!_#4RR+-HEd1IA z;Dg!EnR&xJl*HX{wPMRY!1C0vq0c}Kw3~Y|xkTlc8-ae_Iup4b-qO$j(BrD|e}zW| z$g!<-+U?@{Eb5e2OAdX*m^R(WcFh0s8W{Jx`@)qi`;eGJwlwQV44rUnv3sJsH1~8u zYG=-?+_Jx)kWECiUWk-W%yuEWXDW0zG*)|eh0i@LValtdvx?Fvr}(kK>^`$$ig2nt zKyd^|EOAXH_=|*qL>g-UFC9SM`lX+`H{bP2u;2LkAl{@8t)89s8S>YP(xmzSa?8$k z)`won?P$;5RVZ4%(9M-g3W$8^BdR-`L~mpG5N*8r5J{lrvan>O@vHXC+b_9sBj(Mn zb)_5c5`AOL-5j9W0b7oZ%1~+TJCx3F$6THZp&TUz8uYeDl{#?3miG*g+%3EG^M~M} zf@zPZm7MQ;BcQp*Zhh!G_-vq-zOEPHz~28B7svT;4_wx5GdZMz*G_{IPWD{Wp`o=L zlL-fAX<;TLZGX@5+Wq_Y6I+-4K6YLuz5n3*K0-L&HI50)^{zT!ct0?pU+RUe_r*tdG>(g6zb8Aqxt$X@rM5yqPYc|c!Cv)2g=t5W_?g$$?ALO&>?JxuxOJgjUA(x3Q;9xht5NRF~E;k zt*R3KxKMv-Z4VH*OmtHAuJ&XFxmWx8UL?(B-e4O(stUExwv*0r-05?(wzDm!Ueiw? z_MSBFaTzqX+xau24pCAkX4;n@08I#+Epe3!2B$z1=4o5&Naot&6)^A)4QR~hY#}qv?|ii!yIh~+ z+BDe^&RW$st|B0FGt>`!#TZ&1f9*`og2tf~UN~n9%op(!!BT|1uN?R_aH)G_v*yl4 z4U4NW?H-z}<*KMNq7tlJXfn$+ee7NEFqGO^&bL;WKd6P+J-{~k`swA6BD_7G@vS@*AX!I~n5@h~y7rhM&EUk@dbR?BRG-{wF=Lp$^>|q=8*K@nJF~nSyS5>gr zXkCF9qR-oH_oa8Y9EjHI_V@&y$vllD*huXlzGj5Y*4tLA%X?R8&1576Aw-nmGzj?c zs{(4R=sfz`Niao#T5@7Sax78I>Yzb?T`q(MSz?G5$ zdyILNGBpXuG?HyZiOxJo>|j&{cl)|)N<7hB2KWA$dGpbVjCfdglk2#Qb@K+Y)gnk^ zBgb>JvuexbT+?AV$mbF}#iMMQitt0D+u3o_3^jBWzy3}Z%{&%je zCkM8elyXx;_9wT|0y}72VvM=cnKPskA0lp$8Fp*5R3xV85-i~(OFggtG;+uuiKNfu zhc7&?L$-JeGja>;KwHZK(e~1E$*x<8l%M^p7)~mk(q2j!{1neacO5+f+cO=U{;<~I ziU4ou*yAm!$1yr!xjY$Y*Gt%?b8S00^AHiubW^y*NK*Z_?4#ZC*SbHR`GtE&Q9tO; z%XBo%m$XZL`C+;No$IK)SLT5rC2DVU;Vs?lkz>ru>~sS32|r=ONsLHE4zvDYt!hxZ zXDd-&Cn3pMWdJ@}yv z7#Jy{VUJ;MAN`39-p{c<4w&J`>iEBKoQnF7@wK=`8U4~>oh#vG@gKoyjBmjLg)MLR z!*8!zOl~R6N5N?_-hK^b%eLjm=|OGXH(=`dLsOT%zO{Sigy!O5?UR1VMWzMbrf$im zGIur(x{;;m;cknjo!cb2xpbG@3fCsrx-?SRG!f>Ni20vkB1dXV>kcV!dqi3R-L&Z0 zZPTbBF%lFc@|6H>_v}Tw_^*=TFVX4D5!#eY#OkSqUN;b9hJNY?1hl+Imor2jX-8YR7&(_dKXX=5j8Xj|$Fr-EMZXP872tob)!{DAM!&^GDOb7rPxq>$#4> zFXX1CMIr4w5zSVm>K-Sx5uS)#rNvNfn4Wk?Gz2X)&@VBM31{hxpmnJJa$F&L!SAy} za0$~j2s++wIni#CDQ|O$( z>mYFvpAF8CDvAG)z0sHpRWV)aZmV(ixB|o@+Du%`GlHq3Au{aC(`Zn?3Y<;V0@m1# z4-c&|Qk;>I+Uy@PcqT;=tf60^l8=3)$n%}*cjn!b9~?Bk;TlcR+JQHoxhZ~T4!NG) ze(pT^`k931t!kCZuo?4LT=QU1_s&l*X;qg~R}sJgQLs)D2jpg0=?>DP&P76@ zr`cAc+IucyMbaG~Qnh7fo$I#Yr25A=K`t=XD+*(UxyaR?=OL+7ljp;F$gK>utTdXs zsl_d(V-cs52_MwYx^H})lR`xuw@l(*1I_DatmSTT zQ`lL5SSm8dqD8hVu_JH=bo9Wg4Cs<5Sx``Kc26#NL2lG5vQ*pShX2mXQ|`DQ)MRHs zn;#4`0Pg=mpB--&c-Y zaJhSZE^VHC@cy!nVjeYU3kkfx$X)z*QxYdBeFo8!>>7!vwzLdK7!mA5Gc)j-Hj=Qu z;{xHsLm{-sfWHag!K_`ZRnMe7$(SEB}pf%_YV)}VpgCNfC;gNWSelX-UO+L8mD7u0yAu>EI zBTL%Rrsi>P17aQH(D|^40{@UEm(sUU@HoHZB8fXW&8f`o~`N6xQK`D^6{*Os@K5kzS{AW@$_1s%T_by`PNQ z*>-t%ZI9-5FX_HQmAb4(j1Aw|F zozEP!k@JR1sma;4b(9J1!jUCywZ3I~o>NUPvwqCA9}sdz#w7P%J?L%k$(iiG#Mnev z&Q^QB{|Z{0^kq^Ad>u^FFo5OGplMd z+b;>Cn?pW3WhJNPY2-W`Ygj^G|CZ+m^HaQ0HYxYptgg4-6q!xwj@%o{EQ{AA`^~<4Dp5|EoGQqUhu>Qpej$8bAbHo82e9!kH{ttqG z*(oO>2dQ?6Ar~sR1;{DXkvtf8jieS`jMQ~BJ|drO(r#L;U7Oo%`geka&)qr3_5> z>M$o%X(K}dvxR3}>Au|Z+%v_&A)vugde>l^cNR>0GYU4z&xeA;l|TIRHtO_^+Ziz> zF(MM4N+z*?($-6m)Bxs_O}Y0g2AN7mM-y7?PTw)Z@%Bdqxn}o(qG5LAS5~as&du^Z z&@Eivmq$Nx*)^|-%%(rMc06;GW4+vYw1Fam$=Wl18Cxa&KzA$W5Wtkqv|{mGn_|GOj~kEqdj!L6Qu^nfiIeKtZxjx%3z zzj*~{`u^*?dwjc7^;UG)hvA(13F4*k%HZOw^;I=KM}-@jB@aA=9|}gJdf)7L3WszK ztPAk>aX(r`k~Z(_YN#%yD4BHTPfus41muBnNJJ}4zS;{`Q3~zJo%<^M(lQFR_?8)( zM{<(Z{KWK-b~%|&%puATC+-9o%rv77dkPN{IAc{$r+L2t;D+M7tU2vf=*yV~AKYRReWza36_xo3~k94nzx_UN6 z2*3--0ho2{rLrFi$p`HS7mBdf%ISKb&f=b2Ezl!NZYM{M zB$I<8ru~vj4PC$d@T{1UaL^(^z1(15OTCkVwdaQ2s&)IN6$?eGK*MpS*DMWsyNbK` zc2v)^@-rzfwxy7My=P&3vnj-lwcPT=)iKXy#MNJ*7tZ8-Li9G-!=$`lcBJR4Tsg{s z2khtiD*&b(}ANWe#VtRE2h6 zp=l-#rPJR^duDo#qZ&QOU;9_7Kg=wBS=zw$tgNW|N@VFwnLp>WHby}^%Yx0)su54j zbmNPM?ALePNtTy(;iO5hv*e$W&A&6$93V>SCUu#ah=cm9!Vomi$L54$`~s&(9E__EXfZNqx`k+QlQXwv* zM!^$JpDEPTq5bptHonApyrX#;En*U8Q>Lc)2+?=5EHPwzvKy8Zl`L2j2OF=&A>oL} z#Hs5n?S&s5-v_Ku&hK$1794(6e@tsy_wNQXDWfsZ$h23A( zy-3zc`FoxkQ~N(;a35=KwnET=mfmfh z4bPh-V3&vF zyg!`8$b&!D3i$=!jtg>oGirVUQb5<2zv6D+?f1ZxFQ@Eb!%nJ3)lPDzpy9XqRG%|{?8}T7-`Fnj4eC8dUMzMKk(WvgUD)_KedX;3}l=}RG$D{=xGTb1v^S@ zi1R*2^vd1XVe%uA-)Psq^Xr2Eh3=Kma_;)K?)Ed|^(Ev@me z!1-q2kd8VjIE7ILuCXAw%OG|TsBh)#1HtQL&H%-sYUoJsOZjg!^P}LOF4VR{lTXe{E_=xJ&J!DTbEQnNK^8AQ+`#eFndJ&_*ricAk6WLt!O4 zROMH+jqxuU8*(YBqNCyOiXZzP#Pr$^OVX+OPk|?4ft=FF5ql&dm*!fTuQOfp-!ZE$ zeW9?`3mhlD^c&E9a;U%$1;Se~{s4+C3hK1+5!ep1yna~+G8(3urgD<=00iev34frZ ze_Lu`bW?KND+^x+adr`F@vY-8tu$j*SoIul*B{&jCAKmP8`p!BhxK)jNM8k|0KdvtrW#>Yd_vAABCe>0pI zYbP66cKj?c2<>){Gj$ zVuc-E6YDi&6|YZ8hkFM%n8_?-GcF}Yey|o5w^;=*=wG7G@y#Z_?w{xxE=#1nw|cU< zsvlb}ht4YrjK^p|glPW?)Y8Aa&oTm0o`Ll)LXWtY^|c5!>#?5s*AYfTp>p|BhDdrq z)4RH@;HBS6{ z4bS2;NJYFa#3zTops}X!raQ{L9O9Bjou;$Gxe(D1w~yc;frjl~8n82{FW4j~^eztB zc$-9y|@2yHNP}y29pbSqK^JZUy`Beyd%Kil> zD=(o>pDj(HPlPgMsaGH;y~pA~#X&sM>9J4Wm4W%`%cS5-|ISzsYjhiu2Z3q2y!(B2 zC~l7P@8{#W#+I!w)8x&-h2U|+vdDCn-UVj|B|s23l7S0@2Kf$!K%+2OULOe}QT& z)G*T63b;R+yInG5vk&U4?*y*MmvwST409j1`W|`xGg6gGBq(arl_ms z2~g{C9Ce~DqtN-urp0~f^|+nh0P}hDtBs1yGoDqQLix02-Tqe)*%)@zIs$CjB=cqDjY-z>JM^~NEFYHMxi*i`O5tXa&S#x#zyDnsY`@x6AojM%eZnUmlM6>@$q+ z)ric%=lxjqDrm_e<`$|MmZ-nDuM3-i+NKeZrI^EqyX&i`MC2lpu3I0kx4Tjrdfg@y zDlxTnfSD4`exWJ(^c8zmq1OOtre=-yO9I%#B)-8>S+nIe=9+|HRiFh>xSfL2k%u=h zSAiZ701^wfEwSLaz50i#fD@H+tav>&a~&d#ZvE`%r%LYM$b}duLemf;y1P)8t54xFaSwH?eHZUcb`hE>! z4F$>tBFEYKOUT1@{k?QHMI0d9;8H$ya!1&SBg0eK)>^<3lTzeP`I#TZiQ655ce&@7 zNPsfiy-pSxM>)1N-Fu$XwBY-C{u@OYP^6|_WDJeu(47aJ(%LD=dlpBk=g=$qZ?*0y zqgmlG^Rnr^2IBz2jWjqWSvZOxGXHE`=VUU~j{YGxa!tN8#GG#{DWrQz|9F-b%U|t$ z>0KLAZp*;pUAwcEAJ#vvuUgmWlDV-MldlSZ zHsgza2CR0ZcKJTf6g-1&Vl27p-#`7kUL>^ymM5ifC_LVRDOpr74~A8SSIEG1u;7VY zm^@OX3I1*Aa7h5gET@x-PNCD;7}S|>dH)?N@IO1hKwBQ6U-@7(J6J2R&i&`I>}CJq zcrY4SW#Anw_G)Q!k8 zbOVsm+nX+p1TX}r1J;!NDAO?6eaC^zME-Y7wO4bUvQ#v<*7ZGyvi@v2nx=mmND+u+ zKHD}^J%+h@X!kyKT7g1`XTZA)tJiB6gFxrC;(q_x2PAfMVZRD_j}qAuX@EfjYw^!h zCu%h353pir8n0yjU~EkWt?%|4_zWAlJ;{!AVSQ}Ibq+a*D#X)M*98OC z+T5Z-c!2(5=P*UWl(c`2|0@>@reCk1Ye%dvF!ad#-IuV#3ZN}V|8zvZ`h2(OC%31r zy?qSRr=*qLr!DrC0#^8H#TMfwc1R<{~zBdNTRALb&*2mY}ysLan130qa5@TR%~&-i?qM=bDIX8 zz|gE0Dv3?D&eiq-{~e3fe*4<2VSQ>`HNPCxcKaxwXzY?%yHBJ49h3X*s2%=Wp3_p= z>_8>U&8fOLmqTBt=J%M$-XdN}7xyHEx)Pn? zHM?)E^&2<)IH2o>gDBD?)+H`DT5wHpgm9p>tDdb=0$|vl4HSSwAwx#BUZF zPC{dQfm|gg^+Bml3*?WRTZ?Wq+kC>_^ME*A4gFtgoWZt=19W4*nY2x}?vIw!j;(s> zbQgky;oxS?Y!;_V5h{^ zxv|7lCAd~z0jv5Nj^^;tK@;@#kS8}!v@PCc8;u(R_tXV*EQEQLHR|gc{~U#NpDrHC zD+jlo`Ye5w)b}t-F5eG~U2TI_MpfRMci0Hf{*Pt!D@LNa=PS4#JkJ^aH8y04E6{EL z313A&FZ%-omiyEC$hD3g${tm4ZjP_5I+%4s4|7NT=x2ks5i?w?-@e5c?djGUaze^a z%uRi~qqQZ6DYB%YH&8}}33yO|rtF@vF1$sZnF=k8A8;KB{z52alqm|!A%VT?-d&NL zNmYXu%vaf5uEb{E&(CK^xjNc(&I7p=7}}mORwjEqdt7Hk6JPF5^bt)Tp2wviJu6?` zCHxRQyvYv+hPV`-3{cBOYV7VwA9==QdV+{hDz2Kr~ zHQpmGWe^TQhx~U8#ZCMG9*>mJ7FAYgUh2tR!O!trO?q+&f!Ts(W|ml+_i8!Y${--?u`7-{yLSv|h zxSeiIBEmu$vswzZIMDuWOacEzC~x2LSJ0EOM#XWINBGhWg5fM4bKyMjA(4Fv&g*nq z@q&kx0;25SIWv4Ml;~m+p#7fmvm&nplx3o12u;AeJ`f(gC&^B#`~)hg=j+xy-elt- zg0pHhqYTy4T+so`%;^HBgJ+gLew<~nqIEAz>4a9RP+{y*g%Z(Xo<2hRo4Z^q$zV(C zDOuKK(n6-iABua_B+7v;l8}yMVN$6X^71szr%aUwf2|r&xd1j}ecIGFip+ zzqhW@TLdzx%UHQ@Q%ls{p;c}0gDnRQ@}BgU6Ubuy1>9@kcLj$Cl^xaN*5|=5Z}X)& z->K!;t_NA^rhaF>y92an@Ui_kw>f9&K*V^rWAkf8n(u)v2WBo$2i6oUt+1?pNJ0R| zGvZ%fxY)i#nrG1gocb{+v^+4J`2~CMn4Gz49--rgwfIMogA|;G+{QZtMJQEv4Sy3GtV_V&~;~Z?(G7DT-W%$GEXhmMk(;P`S^uobs_Y84%damE>?zh83;yHTb61vx-oJaC3bLx3=!wPg>Un$sUL*5{@vVK=aW5Fqf%+6lpAN9uwZ zTppK600|qO=w)$d@c;eW`#*}JM)wguVNKG9Z_p0dDTIHApSh$jSP;s3D|G;BL6{g$fyEMx@b<5o)Dp86s`ki zWjsXwk(ls{FdtQt{4=Nx@)M#}(Tq3@)I@j{sAzz88{6~PFc+TJi{qD(f5%w%-@RkG=^Jt8HYw+`K5PT!o>p?zLzXdvoB~&CZiL5<^ z(LcQK5nK(vNPTl?it^#hanC$k6Se$_nPYi%9lrFhKo)~)=d@(yb{{DYRoZ2IqbNtz zoZz~rGwDp`o;Au&e~8&BcHLsqU+m7;-1wo%0$;c2vnVCBkF9xh^QaLqYrO5f_S0Cr zLWQ*q+BAD`-O!vrd$M4{i0>Gr8k((!K=Xs|n%WPW^kk(!-b8VoSK5eT zmo&v}&oyEdp7j21tO)I-h4xPgJ4k1_)Tdcj9d%j8vZg>B@CESAB!PUy&;iu4kOMdC zVd~FBX_w)E zI?GhMyhPcqOn8)cskGw=g<2YZr)TRI+5#!VH3n!^8jlF^tSn(ZdcJAQo1wA{OVu4E zNM%i_Q!s+dV>vUVA+Pw>D7?zZFLjQ?S3c@dQ;DYi`vat;-g0XhAhM%VWQEh!pR& zNz%;F#-bMEM<5%X$x-Fwkdne5&Omv~s9cb-@Z?%e`oIfLx>L@2jZ z490?bzMkWlTRt|izMrW*U56Xnb|dV4eVwWldo$8yoSjv8%OOwZT3*(PrUX*lZ-$fF zA=5*zyMo53t+$z()l^U6&D*uEAULQ-^(gn!r-t66Uh7}@8sLoc^r$$X#T!5gL`>J= z%c|?-z13RL;JJI07cI3mTo6L;0y4%)lp<@TzL~CxIE#LHj2kG_pG)}d=?E-(?`YkY zfw@%{SQZFq3VZ8_=HevbUN~b2yy+U)MBaJtqOU$~B4$Z-4jcp8$8>__V4nH2M%0ae z%TzCpeJ#|j38)J7d`~iHJ`o;JH*6a7wd8%wzpA`cSy@Q)+rU`!RRuiVXq0R5e&=;U z-9uspYj>8q{#D@#Y<40}pj?Pj@YG#7zl{;+5O`g{_x1fnmw`1^jNf4t`ifK6|0zfJ zqMX>l-)ZC=tjhl(CnO_OW%=sd`@FbmY{(}#E1C|;f{kSG@2lpHr0ZEmH3R2HP~5wz zy4(X?G0TAr%Dij#uep24->VDDLeEG|7`KMC>Qe!G=I@uwWD0a&^vRrLwDI_EP$WCF;EPlK>ZPMD*#WQx z^j2+-zftGWD@z}4>n`u=QMIYQ3fTVP#Dp(@XWBk(O`TmHuIH>E0TKx$^VA<+30u7c z$gl6KY~P7YcFGk4i^>PyIuksHsFDD@cM1|R5Nx3t0E7PUC{psn$> zAhD;HV5WbD^CamgmQ4)C_~ey(4$`vY?~Vxn84Stfc=rBJo7wrkSmCQyU|lKLv?u*I zh`ZDn?2;dMb4{bmj!MX*wQj2@bFIGJzpe2oMv>L_g$GoPoMFRM zmjJOd)?iBeA6f`Rv9KkrOi2GZUfX@#AR<5Z$++eAY^JWbcVem6twZD2Z+KEhJM)SD z0fj?%{1jw}sGmU7VeFdk_?_xDKjC!NjZ`Fu7i&#=M~Js14xi1*#T>-BQTxMNw?vo64(wJM`g0~RcV0s zSL#%a9EXk--rqWUmN3-DZG70e2iP_4$XqVcBjsRpJa!Bk+vTQ2H4EL$vqacW+}YWi zUgDNn5@jr%=>j)hN0}Ev?v(@XS!Y6gbq>aVPj2`1a}e?`Z>dENzMK3iVqP15Qf!O{ zUeGF&t~72t53tZqIK%fh+vhku+HmGgJxxpcLSfY1x3L;(|Btux?rJi7zrK#6NEhif zqlon0F_7=b2nqtyI}s3RDj=W{Lt=r1o*AVJ$qx}i2oPz4h(S_dq=nqmCfl}{6D%9RJ%9^ z9Yby;@vv{p*b5ywyAOL2iv%&Sul><$&q3@@K+1L^=U`#bOKJRVBcrs@khkF9x0=I7 z?f?l)((BiiKB+C+dzvoTz3&!&&OQ8lB_?<&tf)TGNwrK7N_V}Z7ag5N;|6H&%^PVy zouUa(2bP_@r`cy)!mOR07_nh<8r=`%oF)7HV$0}8SvRk0IBE8w4bW|^>dIznK1aZ2`{Fcp z`$-*xK=6otie0Sh`SJpL5LGJ@|4X3!ayYeHiClf;Gb z6U`z=XqGbyUe@7SlmzS$+7>$XC=s>~9@Fq1V)m2Tzu?nzt^1VX0yAOZ{Y#s}ja>d4 zho@I$3Eg*%89vPOhO>jrtW7QX7mH?g1s_U}=8v>Kwb_@K>h`AT00LfQnQtb~_?Rx3 z2$G^6#le=oo-vq<(Mo8eRCCc*+=`3VDLzbhQ!2~4?d%`jkxN@;!ebL-YupdfqsZeW zMr{&g>44gRqT>a|SnZxf>_Il?FDjfJ3w*nFG6}h?UzaVCX%Tj%Z7x z<7%Bj+z6zz_^lc|suB@E80T+Xa&$6muG}2J`4+q5T1yfFsT%Oan^Nt^`T(LfZk14qb4ql|wo#jGM(M zh=w1>6J?)G(G6u`aS_J+V=3q^4WBXX&|E>7W9S1%Cco$gF*z;y4R8dA7mcNO7nz!7 zy9HJFbCNbRWVGax40wtJU=an0A*Nju19!9~@FPFdsIBzOUyJRm8hjC86}ukxOR6QuWn zBpj&I9pq#_DKFdL^vMeU*Vq2qs!!(kN0~)VrD9^-!9&hRilk#y-lXVA-Ib5iZ5r3Sig|)JBQ~*lwaj3;x*-+5U2mwsPoW8ZM2)r*5A#R0 zegmza^pNgoO}4oYbFn*r^*@eJ*t48e(Er)6n5u!5i-hi4z2tXaXQDFRIhQic2C0%h?$cmgr#{&b{#ayH?`^S$!-gk~I+~>uy|JTu0=vuDTv01Qva1$b%E^v1$XKh5ey1- zgLqU_DjRkvO>^HOjXkOy06pU(4y}AR0EIV0AHhXb8jLaeB;rM8yOknM=sIJ34P!V( z$KpP5OMNSs6<6JAnF1vQz=&;zlm~Gs{FxI+hLmKQ;RlR;N6okDh{Jg?a3)OZN=%87 zO+Zbcaeu(Dl5JmJ<4M#AVV|c;NE$VnEXCc-_+gd&uG5aZpP1sG;Ag2Uj4?_2?VCR#zDNuX#js-Y%Y+-LNv?p!AQUtW^RQ{I& z;a-01*=eW4iOPQpu~1Eu(CqaVX%Fhzq6YzYWotBv>k5`MC1}>|^%gjD&accz#n01l z@R-DOg+mZ#`>Uz0Lv8*myDLFpSGGGFD;H~RXQA-VCr-+b3+6vQ$l_L0bb@D#AFCKW zELAt75YKO3Vmt@(@&OsTttASsBQa_Hvhlo`#u?`wpW>9cD_*x4DK7RtwDrdoPt zqrG9Ff7^Z3tH@P?)cLa8mAeFZ60nm#058KvFU12ahnL+SUW5Q6>4q zZDB2GD^Xvo5PMQI`kwGBB9OisjsBxwG3qad^UcyX!zRUWRhGS1+qNvSi3xA;VM2Kr2gxGbMs_F*l|YE6gUt4tf3}Sgv~=>^$FfNsBC25R z#pXP!>m)yLLp`+xGxXE8zgbyyh;+*#ma(DCMdbGC^Yg)zD?SD^n?q1FT#*{rgUn6u zlS5_f1P_}B8TI8ssV2kIF-*nwDxPv>)XGdzQhu4l#mBV~O|7W)OQ~uq@KvHsQD6?3 zdc;Mx1|w$Ln`DAZ&$ne0hLd|yvKtOn#zbywLUn{5L29W2BQF+gbQ~C)vg;z6B~U7n z36bGvEf_q(4NPQ}tFlA)%6W@-5s43?x^a~wt#aTTn?hyainYSe-%$^EO}9jyV3n#N@nHT((1uAxD63a2K0X9YNBpq^LtQd%*1Du6 zdm=)zx+%h@8jZ2EWJRX-E||QeOl`}JwLaZ8%;BReTs&?M#CBpjO&k6u9`1N-wTX<* zA4U-huZ|#8cmm2&kg!&pu~fn@Z=4H|G^i`(eihQ-BW6p zGRS$of&I{>hy$g+YdJC?!k^q^RAu_g)FMH)wc?3sVYj7tMdOXC)fjYi*^*GM^g^+L zi(SH&CFUs0d%(N7fLg>rgO*+^CY1Q6;F<+NctOQUeFSBzT(VqjevTPs*HvUunTCR$ z805sgt|?@3QL(wDk?>{zR#e91aBNwmPR_7`0gw0T`U2mbR)p;o+nC+CkeIQ6r^^Wq zAX^R$()U`wzT*P<@xL`O@x*qT9Fuo|(t?U+Uel5m0F=Bs z1#KtrD%`;5<4BEX1lnFtCp$Gyk41`&Cf5ZmQvP}R%E8)f+M>l?;Ov0&FST1j6w8luUBD*$78$79>8{dTrAuvtg zcJaY{NX1Mgqdgx(cR@iS&ubTFwE%iDuy1~DF5>DM!A{B_dqTGd>dY@94eYI-cZK2f zSzm6M(Bwe+6M;N?@n+aH*zHse|B&(!EhZyEpOxZ|&J6TA!Gy|Otq9x4p!iphQV&iA zp?IrNIwhz0=&Nd1+KMg3{(QP~zfQyT(ATdg>w>_5QG5~dDODV@Gk7PSQ+twj2%E^^ zn+IRB>0`?_r5w{Go*Qs0m6vu%ZO(m!R@_kspeBjm1^2i8XN2K=U9PTBF_CLpB>GQ4 zQ=nU~{kum29kX+Ct?y7Rbb}H-K21Z{X1o`-Jh2xjVbtN(8Swdv0vq1zL`u#jS% z!|xM)C*LvxNh+Q3bURtOjtFp!9inT6dF1tvlf6uFvi-s_lOlEL;AP9Py7KWs!IYV5 zBH4&>!{h8F@R?gZPG-@d#{bFu`k7O#yj zf(5Q=zbvG;UAE)!X`wA?-F6Wu@FZE$G11UM2biwp(v8B&gIHN%(lkZ}{R<$iCIt$v z^)<7(vWHMdhq*0aye(NzwIS8Se=wMxUwdH_p(HrmDH-6UFGgr4U$`3Q(Rhw>=Wpu8*3m>xF?qN8_8_u(~ zFO`Mp2R2M=T)XmhC?zP4v&uE(#dn`$y7m4zj|M1g zuo}#J3FTZx;x9oZ2V!sEVl6@j?!jlWk?jk>WVYiMzaT4870n>qNdwqDaat14DN4cz zeV~GJRH5tqSfAZSr{ieYgMobvqH+(Ah%e3wC69N~!dx$B3R2JT>+^YqlK$(jD1iJR z5R*Asa$Um)flsmGPuJvT@pH_?Ilry)Clbr}0qb-G}Pyw?|UnU6cKd*=uZc zCDB>)4h=^}7~+YhdM{CTvdrw@E|Kt=j=r~>i#-6eJ5b*OK1=QhNQcHAn|H*5fiz)59yE;3e%RNu z`w(r;e;`sST-cC~{0~vK1_~Q6N1)smv?X7w5D*e_BW(Bt#xPQb%^AxH@xlvF@e)ar zYdy5WwBbS@q};07`u7U>eiPfpuz7wk=ER*iW=^YWjB1ljC`)y4{Cn=FD8tCdc5dkg ze37N4KPs4|Zo8`R_(U10#%{R>EG7Zlp71~rWWV(z|}VMVomeeiSeGT07beY>3q zP82(xe|SeE(P1P8AU{X3Ko5je!KJYvp0nY*J=!Z+$m0pRcj;Dd(*BsZ)G5z7<0SEt zmv8zuVeB;Dq=G|&LfV7of}x(btPg?KYQY_LWloREz_{&-uRt;@{(PyW++9jPZ1qHS z_lz4|tGCVJX}Z0$^*w6w43+h{;OboRyT+lGvvtETivNp$ir0o!MJ?_)RIPl4`)-#s zi?kM?dJ=7{>d$156n%ZOKABSL+p5yB@%WLI=_d|{wnv@8=}ip-Hopr(?0;@LtSWY~ z2`LG5fKDhLkX$xhCxKjkeY^BE$Z3wLVx~XrCxF-&M0ogCm`;Zho6)xX!2T0S_@Bzm zVbep9BqQPk-<9c=Pde0lrYTMftX5eM2A<6JsH?)J8^>~5J*(Dy|L*RoM`Y>6T4Nrz zs{VpIs`@BZLIW}iJfweddX@9F_n8H?5GXYl0)D=eb@$aHd<(#a5_l*pPgZF0XpKS|h*)r>;qg`B653 zkVZuPH`fdlN$l+Sp`$@)yaL2Ed-nIOhwqpqzz)*&yIv4v<31cB@TL}&z*r^RnQQ&! zt}s1`6MFMk=r0=*1ybAOIxgTlf9K9lm+<|7+Gg9`y^?=h z&c$|T(OVHMUIkYRGWEHQ?iKJ?eviKnaI}shgYMU8c%1mEKe%~9BtHJ%)93hX5*v2| zV=N2?NANrG2qlw$_e8>q_~@|L7#;Lph|MkB$3S!`e6Z-#5*Luyd0g3fSFUUpT^wo; z8aI;ZO5`&+u=Tr14@IwthWsimt!ZH_FZ{6R3xo08=q0DN|A)|GCF+JwS+d60O5#xO zrtrA+k}Bcn+pUs-jTLd-{Vu9ZiPBiE{7dL!eoci>srN3vl!L;G<+43X)#ZuF%a)qCqm41$GRDJ8Y`JEM zuY=%IEq<1c9#Z~3I1S`j#w=Eb72nC5Bs%)AQy^xqjsGDM}Y0`7ZjF@ zE8IyyxpNopI_Z2u$af@Vf7sh9pyN5ly4-*F;L)~}KE`{?u)O8Bj56Y(&Rz&>%uP%| zCHnRRnas#`^D5sMArCFv;{tPQ3SMp+4LglkfWo$d&9k1Nd0aTRUX70RM0X2qF8kZs zI$PD?23&vPTjI3r)XMFLd0;pjYCQZYro7RN2@Dc8$g(Itgh+%}W{1fjaZH07iZ|Tq zG+YAJ(iR(LLELZyX33f^wOunoHk1fH_Wu8KdH;Va5C88MX*}utch8YRn5fs9w5va^ zw|7m5{9L)`E4a=5yXWtyO%bp~d@EJk^Y7GumhvS+7Eo#sxflas<}TSuAy{bMIRO{n zv4qB$B&jWAuCkUx(U(v`5({=ns1BVF^jmEha{h5rE{GRtbnpoS#wMde=bJp;XAdIA zzcg`QOIHaJ4)Q^W!RSUw##Io(MQCOZ$LmUbQN<6Nmyh&m7EtVl5dKS`JJcP(AQSwX zsuS*~=}-J0NT2G#O$?2hF3AmoIVYH1vrk~1hA})Mx-#ZXf_@0O>jC9HcXgKZIohR) z-%I?EZs;nzId&JjNXE+c2G@(mGg|6)Y(=vqnI@3X#*2Ovd}r+taPs$hnesc)og|Hu1_fEoE2i!LDX|ZzFoI6e1@= zQShtq4A-a&kGevVNjaWaKHadX!IUrV{V3;&cEpu!YauHm6PD(RY$dlUi_M=feVH?j z^|gyl-1{T#Qq6cEs7Ne+5@W$6JXhye>bm0@Y78+gFBfWoc zy`*@q=IrG|IAsI}P2N`>ZEjcDeU_$DR~*H^kuAHveo-;XAPN-8Go7U!(w83xFNSmizuVBwE+*w73Wxy<_eAlH~2%%_WE3o;+R^-pim*2 zLDz!fAEMS+$ad2WEGJ0`8s;_u7^Q|#QV__{G(8PX3ba|KoKJA?)F#NCDF?m!eumWF zbFpZ4GJ&W)h5o&s8S6x7422&Ly38KvPTI3+lyo@is?jqRQldTVnGpx=svIkfDM|4( zRA#_Wltv21jDONEm%HoL<>3;M%0||3lkn^pQH?X;4GOS*wEF69@ThfGa{=wn$m3!P z*FvbNn9Fo27L>o6@aJVQB7LcPJrhM*oo9C9$FrgpJ^V_Kro~N92@o68`xn*|TSRjt zF(<_Yq8)$ib_WTDy3dVe(sGDL?=OB~nf@BLAimz~4F-2dd0zJ!BD>BW2+wH_WXi`q zM!9f#fHCZzPw1fKZ(P>S3#E-g&zS3LchLVEf@JMjF+sV@6=bPJvpJDR;SI3U_NQP> z4Vf40KluBU9CSAyHuu{Mv3u$XWlZtEt?IbdrK^cu^UcMj00g-f@hC3lHZ_moZp5D4 zR*bBO)K=>>v+F7H`B_zWGPzme9@(Ec?@P|9bGgzKmkAXu z;qNUK*Y+7E?5=No{IR>-(Ree&Z*~5|M3q6v_b#|!bEawH{Ps=@+KWee3(oeY1E-x1 zzQepCb;5Fb-5Vkz*fohx$^Zhm>&p0`Gx4o{d@@AfbhjZK_0g05oIij+{*-)*x+Y!k zyuWyIP$B<0HyES6Z{Sv|PBj9_ zGfxuV2fiqcFnWEZH>N)L|FWKcsNtYY|Cw3eC=Pq8L|h)wD-Jv9PO_HH^pv+4ZkK@8 zZT7+L3~;Z$Y`jql6VI#3rIk&k{&Q~7r`9Lk?0#y3gf;KL@(=%iHel0%3dxgWON{)S zHeI$k0~_a#D@_6(%%s7+!{V9Of^BDjiCMn1PCqk-vr8~OZEf}FY1_BHLWEd4lPh?L z4uTS!VEFM-Qv!hd(xi~2{im+Xio@wfJ0=t}{`xt`x_7B(s1L02+(R4Q;qSzFx}lx_ z3LF;Lx4`U&T2-&eJksN~ezVlj3{#ZYQY!>mDDUR24FAT_1|PCdQ;g4L7u)B&BKZQ8 zE39zLVnkLkdD+&SlM_H?bxWDtD2+1jb##~Bz_bU#853+zy04e)7TUFo=%j-3`T0C4 zjHzMxS zWyKb^yOmhNo59tA)26|*d)cb`!~&FAA1zYW9q{{G013OyXdwV-9;m`yXzL6~d+x>1 zvgTiBX-dqpwe|^Oal%B-gO9`$;1=N?HVJoq82&QRGW5Oc<;E4|z-yLgE~lvXr)Z=; z>$iaWWc{V8JYN%1bUa%sK&=^crg>P0O6SztP1oeq9_KcWQxB|6*DtA_@;qD|njh$4 zl__(IWiO@>^KBEOHfB+DWTOzeDYdHx1)|3(|YwP)3FWO9z%2^7?{$pjPzA<&8 zGP$zgzUvs6iZZZo%6Mj=O||cm7aq~}oecw7SFv0t7<7I6Pd<&&r>ZU=8-0anIMb{B zNa)_yXXbjKVmnUge)G})TAT56lm5k_2iZ4*Mh5Y1BMf3RVerBaOk(MILv8~v1=XY^ zZ}uXFIHB?`;3)BE6DOB>-tmdImukerVzUpkhUA=vAAGYaht^)-(hI4KC40Qw;?<0b z9k%=aQl2H+DcsloM!GCDI`%FjfHh8Z0tvqKE%ez>zRgC)Qg7c(r>!h&bY@=nglPN} zs{>OVv|N~UG@o9`(X?cbWk!Qjq|~XJc&&ZUY?S~q`9k;IbD`1*MxZe{e14^e+2H_h zj!fO(w0=3}j}2mK+04%YgZjj~)L~x(zyyM)tA3s4>PXBTYgLR12%r!Lo*O(3rPvyc z`e*Tp3q+X+8~OZhiyK!5z;lL+Ddx0ERJpVUg?%)*kuIauKPHc-k_^7JA_D4|Q1GI8 zv2JB5$VnP089ZnqYBfdbj172Y*XQCN1>#|AE$#WmXz^iHuenW5t>+`EUc(tiYglYQq%kaZKN>~D@hj+&Na^es zF+o+EMl}`DDRv{)8dv0HvtCTIUFCC{^ZJ1r)?{tqM|OCFcG2q8aY$czm9dRHgqEeC zW<#ONk=*AJn}c+X@oyX02!57YVMot)$-~uGmE|@>#8~@*N+RclN2BdGq3u zDWvVyv9GQq_w1R=W%Oe>Zz)l*8rxemRpjog3a6{q_EUD!@1W+Bq&ME#E5;st^1R8u zcaWnDf@T1-??5gT`tr56Q2-ln8Vub&mH~hthlKi|U(ggcPbwe|t@%!Io(gbOj-#Y& z&uqZZPT)+sih5w>igA*)htKvAjrnZe@FN4x)w874v?W)=zb%FkK|u~-;K;Mrd0$qc z$}~=m)Xw0nM4DM?pOjJHsHwP}tCa~kSD^iwYY;e+(mD{e8ZdZK-k$<$UHt)E=E~^ghay(+5<`}S?j@U0Ug|72xw=Oy9pqxEs*Wrdus~Ni_{O4Zh z_~;l!j@5g~5c;@0Yd+?AX>9`ua@~5_bo}{i^7F(KYopeSy$`%PgLy84dV@_1$6szX zM5dIh-Ixi*jXs8q1`3jY6v4!c@|$m?<_}eeq$O}4d&v^Wp4N@soYpi&B!DeW>7zkx zr^R=0&Jpw5-|;*xca1gpkj472yoLcYcIqm8Os>Rl>}oJ41x0JR5L~1y9&sbUqzBmU zP;stuMw%-A)T_+T7F;c)W|%l7}}A$++>{Z8~AEo9@+=a+@GIR8?F#vGkomwqZ+fYzg(iZnI4G6y z77l&-U?rg8ub6TtwuWIikjEG(?YRSdvb3P7^_b4*J>TjiysRkq7X?A+F-;_9yjwSH8Xr-wR2BcV%V*|kzy46^FTte-C1+(05Or7Yv$?y~ zMpowX6oWK`tAwax|Fe$z0sf6AlRc{p>`&U2!8*$DE!c$j%G;rQI)$Il`ngMH z5LD1-p=Rje462=iT!7`X>oiObWiK6N{gU|fQ{gE1COjtdhXLD9i&xNsBiXshc+0vFYxCxJzyiN7y4Ed3b0 zMC?uR*Gn|8zbIyddgE6c(yX_*lsz~RNOMr+1XRcPWa+z9hdhgF7?VbtWChOXEtg-4 zxnyHNu((SrYpRLndzScn9im1y#;SyPJ_LM#IyHiHNQduVpT2?z8J5J!H&yo%lyS~F zNlnpJRzW<;>I;Z&$TG|!pw}(V;@7_wI!8cVF*K*gJ^r&y&BILO>!ePsR)4x_cG_FV zq|;BIPuJjm+HP#ICn&dmexId`{o2;k?WX#G%?QG-uYykcBe!acw%?Kbs6Z+t6dfiW znIs+$(zp;u={3f9=r0P=TfbfH2@3NF8%Itx6f)PM6bb_)t zV}o>qsCGA%f`CvQS=>vm9Av73ko!LPh2%|!v#K(VXrR)A2xg2)tGz4gO$ov-aF)(^1k~=#qhEi| z>30c!z%qJbYKF4TFEu`YpWSPeESEayeyG8qD6gMkQEEK(Pf#3tsQu2_HETps->)4> zdx7xP(k!^k!93tI2WROLlW0kS*3RGu#V35-LQ~PPRW(cr|LYh7WAeb?V;?Kf$zf{i zvIUcIXhp5?EmX92t_^>B=R%no^~2G^OUIpXfq8X-(iPlR(j0W@nVdMN?KKw-JkegY zN-j|_oE~sc$=E7YJCt7SU>*B6PrTfR#aUZSTuw6_Z!YB|PY!TXCHy0O_u={{scP2d z>4N0q25+WsvyTEfqVBX$VemjzJy~xcf)cC_BZ}ZavLpz#q0F5>unhdPlNLI13Vxyv z9R>OC*g-qng_Ble_?LVb2iT_t!;GJ{1x|;BiUR*vtpepU5UmkK9#FH*$7oU$oqhq+ zSj1i^(H9~uIvTP?rmsz{rGu>;+lDMgs2u*PyBK_ee24?3uB8c-xae4k3qNpJR!~@d zP>4!{Pw*B0dnx-*6}{3ai78)a;x`NM#)HvzcZy&J?6nFX(a4M4jJlAZI@f)r%X9V0 z`)u)qmk4QKi)77r)}Lp4Pa2F2A6)QlUYxR@?uP=N-HL3r0zti#=dr%g;c)z_%Go2gYbE>&beT#o$2G2>soqJlP2tE|H_z4I^oFkjcH z0Ggym$BJ)W*3pL#b3wp{>M$J($c>E#bqV)Usos(NZ^^|9t7nF;`k9rZos{y5N$t$n z|NRVwA-9N)LjW5W;C&(s=_U}9a}%i!G-VpYD@UXQ)hrHg>^m(8C*@tdXiv z!Wu*L8|oWO?(G^;qhl)VWt#Do)8DFtO$u?fM}x;KXG^M<&HVZ_Z zIoc+CX2NpVGHb0V8jMFcD# zn(L%Um(6!QH+`9Y0&PO_Xobd{NGVije%@D+se)s37wbm{)xFu%bkB$YYVmNI=L)Ru zUzWN@BUWM~I`uOqe1xGq5b0_}(v46ReAj35=dEd6zza zYxbO3WB!bwrc*=Tt#t8+<29aKKiK6d-;6Y2Ok_23Q*$@rePX_c;TGm#HWYSpI( zUDsgUbT#Y1C%X%SpYI1$eR6fEMtK(4UGc@sc{YXH{d1VSp7|)1;#CskbB7iAW5)h< z%J#RUq(qs^V|j?q!Sy=6lW5Hin%?omj3EzNyTcB~_Z>>=Sja=DIjIW~eeHau_Li>f zZv^%C!B9J^(u3WXWsQ{AMqT$19DAu%nAt*&SL&Kr-Sc+lN^*ffVacws+-=GX>bBQ` zn`q0AZY8MXbY)n#YTVyeXl(GL9eZ9CGpwBu1P@0$sVh25<~C;!G^O@)nrX<)RkNR^h&;TX<XHeZ@Vp1N_k`D-<*<2Kfft9^D>&vDe zKLP?}9!%CmG^3f4ZiOM`RW0I{dg0ZIE2tF5&H2FYc1w(BFGDUdNz=ySvh_ z;Y)Q>G3v6Yc1s>^uOtrYjp*79?ysErha5N;(_KF;mF^W2P~sJvO$i7q(SP->onRYF z7P>*#8v%Ofse&I)GLtH1Z=mg+7LSp4rkN3<5qmXTQYr`cN)t_94}pzsrI@GkO;6tkIM@J)DCx0 zIiI2`nE|vjo+U=kehHq|YPWs4vux9SXc;I}pv`k-ZCr+1^LZT8+vs3{?jZfQo1w#; zhY+IQLGgPo{7j>yw8Mur@4lPH+8)okiw3${Ir;y0bXl);}rjm(E%}8b$22QBb6|QXdB#k z0K#O~!+`<+#8?(W6%k9z?>lIW(Ojcjf)ZHnTTZc-V<+E~y&>y8OIJq!?>7A~kRLla z+F-?0IaPxqpYgEy!VVys^S|c^k8mC3*+k{nEtfA<{<~+QROXFCcMqz{M0+*(Lo`$M zxs(;vuhffmBVyn2SLVT<+HwX8{GjcxSG5054YP^87uA0Dz9J4}kZLNt%wH_Ok?I;j z0UR>Gu&?^plwW|Z{5E7RV#>LSKlrD+iD@~s5^Y8bsl&5;s9vhYQ8oF)t=;J3@we&% z_aZg#FegSH`?4|#VHZFC4eJ=(xEa3#N0B*wOo9wZxUB8C1Lt}T2S9P{_+T-=70@Rk zmS-%|ME~X_)ddyuMt%LESpjl!>~`cthh`ubaSM(}d>Df2*%_c~&!QtA&4c32`OXft z>Cb-+1MN&eeZx)g8MgSc5jOB#LcUqUL=BaVV@~=}DBKj(yUVA!TJrnv)a0=I$#(|) zlJC^XCQUq^Kqc6f0V*{&^^%D@t}x_voxvMngrvpDZ!}xAwB)JBPXi24RWV@Go6-U0 zy(J23lRjK4UHplQEA!_A^j@8;yC0^`{oYpZr+f zA6c}GOP50?i2j9sH7`qMYRe|c1hP@g=`mG_p=t@)d+E_n3{sfP;|XciXO~-!*GVYG zZrzv}N`^APub`DaWizdr0By2;?WkS6F1~8Fz2r2bNk1(_7HAF@sPA0Q=X`A@tV8St zK@E)@|3(79MqSAI|AhV!7PwR$0`Q!Tt2~C20ezOPx$<-CWA1udwJht;a8xu)*#SpT zBv!PXN_n_y;f%Q#YH}sZ{OJ{hvVl2!NhQM%c!J720*B+yjhKCIJ{Y}b4L5cOS~n~S z@n*T1u{dAsZn`D-*gj~!&EkN1cQe$`eKP#m@g+R#Rc(E%Uo0;FAF6(jc~IWfN3`{c zW>|Wv#=`oRfV^!bIG%ra&=$MI-Wz5( z0Y%ka9Be_KO!~ija7fwDX#03+!122*OacK=RvDjzRaB2+Ou(t78z);t0VG~!+S)&9v(*+gc+y2$He zf(I{19j@Syl@WUJ9SOkg-N)4#ye0G(?DzmD-5zPw_*9=h<0+q2r#j#Un&HN7^(7D>y#)rKTo0<1-4zD&*FY<-)dC(I8_?ESP2@LPn@5aOG|-6pD_bU=g6RJTZb#BACiE`@}$RUm#bS zjH7G)ce(l?(>2+gMxGv_lV$|~)<@QmQCB5hKGbb6W6>sqm-8et#3lFm)uWX9YZiPnpvHp$9e>}b0rUut-Q z6{DeB<}+%!K2(ZyvmmuHIcq0N!%se<@a*uKQWy8(AJ5gB8jq|*B7T>f@H?ZOe$QSp zTvNru!R}p4!P9^MABo3yzumE{%yl_eTzibC*QM&>_R7L@)M|awBe=dJvnV9}NWdYg zX9~shk@kPDotu2tM6s^8A;rZz!Ta8|_ zs`Jd{|GO9WZ3DgcA z&Ay4``6QThCPlk-CdHhw^&z*_2GEWn+w1JVGLWRcb}*AaZc5NXK(mX4!%2xV3aV^2&Ht2sR>3El)w!ZV!Mpt zClGhi-W!CjUB1rF@T5iCRD`C!ENfouuFzAr1lmi`XQ=N{ zzkKnXv94C)eqN;x1R1E>Zs+~PMOH4Fl~=?-MG05y^4XD8Ua6#bKnLI@#Mj;WKf#}D zPW(+Z2sPb&$}L+ppwuc>!yi3wr$0G(zU^IDgR5p1=}Dp6A)HLL+nXM5f=y^hQDkmu zc&KEAPcq9VyKyv1?`ejs(0XB=1hVW410)sTttEpIB?0n7NDEz4z?nUVq=?|8qd`b2 zJ898WY3?PNeVvn}hT@41M}qwYRWuWhbj#!YF>CFv=_zjQ=y>c&!1E`;0j9fmN)OZR zcioC21N_VsQ?TpbT01!fw6dY1!*y3qM>}xKoRc{po7Yi@U}-4}Vzbl17fxz|<9Dec?995vj04Xey$fH-82F1a z=Ow*NqQrj>R0@33#!k6x_4sc>C^xygO6lkmc~v|OOqo6!`19XX`s+pM`4!zGg9U5= zlw7Xpd79r_?JKLqY0Ku-ddX$eT;=hNPXTn*N3mfl@7i;Rj(0WIY17>Ko-XIx5Ps)> zXffy%7r6&z$p!eZEUXkfQV<=2ltCNu$t*;!mNY*w7o!7Zw-_4-{?0#;&Gkq;I}ML% zww~TCY+Jzqd4*QU-gtC$ug-{}iCvli^=7I34}pF0<4(c&Fz}|*2Zr}&7m#xYTqV6K zpD{Q!s-Dl&z2>|NVhrx*`CROrXP*C99u>k|)Ss!tQHp3gO&aEk?;Fk$k6)`*ni3{*2v-=ZwvHg+l(k%f~?)90m~tgcnGqN7KDxHx^A5S;K;qCr5F%YHh3S zWK^$=4eIQyrn78>wZFZ8I=|vnhJcb4lxGGyy*h&euE>20SLcnrSdc@X69o3l$_is4 z?-n5Wo7_*NfnbhIp+KIYMqr=_KKfuhP3fFU&pi6-)neG& z@{1`}F>Q4rC1{%yswbNr-kfden{GGq*B_`?H(`ARWz>S{#rH-!nA2{UVL6A?e+ud@ zJp8+fsP;rwHrGowXGCvUuIzQw^O8%~v}8;D`Du+;$K+isCj8?D9v%I5<@2&KQ+6J| z9SgmsKz*km^PNA0lF+jzwA19b@X)~?FQ#lhW{+T-yjW<+D)m{7(3}z?BRR-J39}LE zlUutEA8zg{Z3g3p-ukuSLaC~{cXa={PI0RO!&S7y9E-D_;J0H(|ocxi^ zA?M!OS1NJXL{g2%y6*yPrSg|0gEW(-g+{JfmSfB(Tq>FcAyQUmW7iw(=DIaje# zE_k(^&DhrX{=gcEmMrQx+y9>$pMt~zzZf6+V#T1I%TLKFQ+m_Xa_-fPv_`+t$3cWf zo<;Xb-;v~Usx9b0*sq&glapY98EDq?>j+)ChVE#=Cer4dh8L^5HVkj@&tnXmfY5`u+QXjt}ZxPo6*&(_G&d?eDy}$1;CWIXX)`WBur|fpy|mV#Z1{ z?mvZ_-(BFCq0-bJ`C*@QNbySGpi#J39-~)NmF>rB@>GSpXpR@`cK*8NyIlXYK+hl8 zzK+)`Ju|jRK)7WEme+!T7b~^nc z41yGEKv|cT75_UEm{|3pXS}gHB6&cJ!YVEJs@)y@0oV zi^vn1^Y1MPjlwMhpFS5{EaW0&p4T-lEU2qgqfY>jcq701lH*w~CH@z&6dCWVnqYrg za0>b0(!1EQC9^wcxRz+G!15gm0H^7scX z#^sUjtr{iv`(&m&Nqf=y0@5v^H3gipwMxKqru<2{64z9zH5a3L(Vq{c>)a*A`{pDI?YDYR z`6*78*%oLff@@^r3#=V}`bJ#_FYWF;9E?3Y)HZT0lKEr6xs=yh^}DNVNz~Q|1$*&4 z=DAO^kx%XI;nYi$lD8kQqbtf1jfGT+Ps9$X&gE^Vq`4BjQt4`jZ7@`ysQeqYsKd9xskoXnFT& z{*2DG_a&b(2|{3+y;Cpz6&k~GVNXyno)-flL73YN-)$BhhSs=P9QydY?S|rxF)A_0 zLp==Q@v;BmoKghxT%S0lBrGR90CrG#mT$@=ew&`C=YgGYsGNu_6(v zca|TyDs+KjGbxWdj`oiJ zzfq6@5J%wQCz_2v7sd~lM?L;=F;HqjF`|Iqf^(`ny_o1dn&8Wdsh~&y6@B%SyCJ2J z$=j3&eiE4f!ndX*aBxsD*RSFHYLvlLmN+xA)oz3*e=qWrAJGN}48oJkdA07!UUn}n zh)0G5-8TYD^qKn$hAeygR3+a0eg30oNwDX0gL8QM&kJHsI!rJwMBZ{ToQEt2`(!U+ zj-rrm0!+o?mplheTDIs&T&3r;OI<(DI+^m>EtDpbbmDcjOEX=w7|kiuz_8b&uP1s> zMLt@asVur5^NE)nRP{_Au4JRI5}holle(r>sw-X?q>)z2%$qpkrtXXff&he zKw$tOQbOnv7`g}uNW?%?dLNZu2PrXx-bJJ&A&eAJs$hX6(m@jiyhlRjx##^O-Y;?- zep8aYuf49d&Q%Ap=MU}!VjwpLfz2EYhUE;N91y_!doP6d>pj6gX2a-JCwTg=W2;Vo z^!(rr){olGBg315OA~9FKP)Z!c)bgejx*Sje7EFn4}CuROJjNGzdt2pQCBn*zboZd zbqrr89|HXWS3sx?-U}JwDPaunWRKfQ78%=yF628d>@+m$nka69cu&tOAT>JZ+yLbs z?HS`yOAg(0(KooSBgNRYe{=Yie>|G&{+OZqocI?^ zohNhDWUkEfZ9RIzi}q*3?i=tRfDBjAiIbDZs5-`fQzgdN1T5WO_v>)BsXjVD3JaFL z;3HdLRP{i9^j^PxBfgCK@mCHmYyaJm)3`O~MN6)+$mB(Pu1<5+9~&ejMQ0Mely4Xc z^xRv$MM-7^a7T~q;G-+w#NB+OC>ILeYcQ1pQXAMQ1s=U=8Zz)$Vt16g&Pk+|mLU4L zon+dB(uvl^Zk27A=a_zpCuzU&g1X?&hHZJ>hz=R51KYtI?L?q zv@sqxn{45=N}-Mon8#A&xFDHo|{g8@zDfQD1#0JRtU$uX}zWQv#VI*Q5TdlvKE12M2bP z)pS#}1TBm)a;_u3TVLmB(>Wnl*$uAAzc##dzUBNVy9T7xg(X+#j%~V3w1V$m5j~oJ zIvP^x_i>)z78DQ_aVNG3 zaJBcm+S663kkR}|)A8dblM8LbIo4TpdBv&y+%mg4UC#BHGNw4BVx70RSxqlXuuWFE zKNHG($GSphXnh^!XQLZt15)vS&ylnhL&4036Imt|^L5iSP|7>z=n>_9xtD(a`*Kcu zRt|o+zGm<5U+?|)H}U~OVhgeVgCCm_QvcZAXgY)xGc#v2pJUvCBeQ>)?22#%={OmJ z{UHhEY41FC?YGw_^wNqkM|!rHPs*Mt_PbCW0+?132>=%_`X zsA&l9?!HB92x%YHx7+sD@nvg!i@Iuw$bl6h@*FBV$~0#C+Au3{%Sx7j2@Q4O?1L{# ze_`VQ;YTrB8l;y-K57QTE<@7{D>vI`_44(G+N2DJl&hmcR&}K8xY=;`LNg1J1-jVJcl z{?QL5D^#}0?T_k(%gnOPZz1vJSTftj$g1lxdLTC;Cn!=!HHsbo}52Naw-h56F?hK z3TKn6i=Dw`Nh3MEKzflIBx{7`a%?ON^6&g{G=TCALCUeJ(%0Qpgrlh8xoNSpzAp(ExR$_9KIhX*?a8mEaXcVa=_IL{sO zCFaE7Rq5%*0EpG|!D()#y4<(T%%#l+A!0yV80yQCw2i5m znLPAOd*epiBD(94+Pq73#lp=*@o#$~!z6CN2Xe2}(y_ z7T3XM#zCdv5Ek(l{P)o+`9uZ0<#3`tXZG=ibQ_RH9nj=LGCGeSbcAA&j~1t^J#^{H z(T5~7%l>DH$muZoTV7#UNP2Z{A=W1))GS}inKq?Mv5n!rrn?@DsP9aed|CbIpSgY=2I5g?Al|pFh*4b^S#F5 zrpdLkOZ@q*`5*I3KNxEw<63{8>Fez8D!rKHN%2gd54&3ymhR4~6k^2`$~}q8b^G8g zS8)F+cuB(_*SSiPT=Q2Q>JSejL7^0;%`~;0PG*97>PsIT_r<@!OC&UA+mS5X*+4bc z#E>+=i!M4dAMRZ4nawoq(iqcWIEK{ET>VD|%!gXP z(>|WPqjTbMco5mUBmq%UDc!Ag+`+A?Vafo%C418gLl}e<2A&>o@HZ63hhXuFI-y&- z+1x~`Q;Mx~WVY6|{Cx(s8HW`U4bb%6V7JOD(vD{}FhwsI$nM#WTZuccl@>a1%k?gIRZdgWziFL0IeF{@0^C?y&;LpAjFR)!uU+}P(@-8_12W$Rn#+V+AnhTgOs zmiE5CWD;7y$=|v)E@@TfTHyhY%$jyWTN=`qI~R67ux5c4^%PVv>VdL)-ilFQGEA|G zwhZM7HmMJ1>}7e5@4CV=ck8#mYjHk%8;m>5>h7Q9;f`_-T)Rz*WVEDQJNnkGnvf2{ zxdCZpQ7i9sFba@1`ldW|g~C>Gk_t$!$xJE`?tMB>cF2EfajT)h;Z)>WxxbD#ylq0- z8IF+--F(y7J}RU={D$uN7UQN?s5;XWyAyg>*|x_krvRyS=)#{+MsTq7hzy^TM>YJP zfl=nv@VlcpJK!1nzwg;~umA}rK+vA$>HX1HmC?DJ{t-S+xN@f&4?bdOebM#R%}e;w z!>hg1+9fylPd2Tb*`gSyQm;+ugVBH4rpUKTQ;WX(B1;xI8-79KRy|)Doa+vsjemcf zY+RmiDPr4vQBLvsaff=t^JTR)_o!62>^~}koQzx|XA3}3q__N70h!O8ep(YJ)cc(% zYOcl80Y0o$D6nwDc^N)G0na&Xy2TE-#uTK1$5q_uN1+9)s=HD3%M}VEK2oz?;Udn` z9yxV$DU0p1>e36{3(_4oD&DqL|j>dutM<$cpUpJB&K4T<3Y&&HqDB~d3yu~4kZ1Zs5~tlPx=~_#mx$goT`0wma$VlKXTq7FP0wGg&Q~_OYqht?)+G!(>N2)5P4P6W zv+as6iG|-H=aMYNDRvSb^{0hcXKa%rfecqNJSxT5qNB_<{~vv_lT`ciZfQpjvgRH0 z{PI%Qx$45BAQ+#W_G7Opqq&Va|fuKy+5rLbRD0|>b z%SZ3cA2P%CmaNfxjRQK{*aLIrHg4>G?qd#X9hb#G&oMp0pG^(cmXg*!2=7#8PM7KL1$j0M)(IQS=J|2;D zs*9>I#?)$?l#(J`T+5l|non)bv>X=uU24Kw6txyyfnt}i*-vK<2=Dj(Hb6ew$RZ7FYjV_r3SY+*RWO+ z0C!uPKOJkRC<=Au7UL%uk~tkQT*pHBCzO;Y%yftBxf{1d4($YN7`6VYSeYUsHC4Le z8CO>Cph3R^l4!1fhy<$ycrgPdW`5>N9C zfVn!L?04`lSj*BI20*kU$9jY)=B0%Ty?|)S*$Qb}+h>(pS|d{ut_2=%F}9eB`zN)(;Wy-3sI1?Hi7@?c(qq5|C zzIW$@+JncWVy1ra&Xis?7Gh;<+IJJ5O_3A;7ZlYvAY#$x7uT9qtcVY>>lN0bPe`Rxz>sXlH_UdAeCWH9^YzUL&$a)zfL zO`%afZueD|)LMo{v@|gjy>4DeJ+4z-=86fu&g~6-+ux1{MV2Wul2uOpXE_}N+-Z_B zn=0Q|ZGCKa%e6w2S{|VB(%MU0yxX^AeoO-qHR`KHO$9fHzrW%Cy`C>c3H%(tS{yG? zN=a|Y&Vk2he8Z4c1#X249=r$XX;(M~#HAn*DTfNGJF43Ir*m8>j;*@Ds7j3lNh$*! z6w4a0KWSMC0D!vwGk@W;t4?i1+B^yMn3aD3f`bV^tKEHvGntv-%o${ItMg(u4sW;` z3MMyhUGeP@ek+=IQENoIum4#HyTyy5kDl#zaKCjO~YfvB-Z?3PD%jaf{k))DA0 z4QM&Gk$94e%0-2M<>O+U1^Sdo*nk-j!Gb|~{y-e_1B4~`pkJ@X9kj-MJkPOeq5zrm zw2?$m$xZ9hx#+z>`0cOvxJ`sr4l$r1RHkqqdkqa%R7MZ`wSm@s^<>6Mi0!~d!Hlfx z%;DEL7%NPhTYP_4gNiHik=P>s+(*;WK1g2hc4EJ|jS(T*I}-QS;n;El09LlV;29I#7R6NPb*o44;jX zh^}@m2)1epHK>69NrrlgdDO!sY{tZGFf^7XrrM*7ut#ww+dj!=YK*e}>;D+GLj?|| z!8q5Z9)Rwjt5Xv1foH_v;ppN{nr%diz8ff89`f{$a?qt6K!uZXR75*pZV+K zL!s^O`%X0>F@$j)D!ZNc?tGo6SQ^a|&Y(%AjrhT@F|JiN2hKY`_&W+Hv2y86x-haT zrTOL&87H89LEbocO|C+11qAo`XFVP>c<&LL*i-IIegOKM;Azh{m%AZ51)w~H=J-53 zbWD8pqbEBS??K zfQOcIGv050DP*6bV9JW~s`JT)${=R{YBO_HxkNLYO?Fi|H~hLLb7Wmgu@uwZe?dkf zjn2~F`=_-ta(~m6>}s?{y)_-vFmq5jUGV!|ZBRlWPYGEsvcGBD6O_FlRLrrnMp>NR zMqP;5If@@xOm#*6e1Wa8zaU=nVBqL+qGl*U`5|ZYpz5eHQ6+RhjpO>9t4=G8yT>;I zKS&9m2SFp>kJ8`)Rqk3&IP=TtEkm&Ni^Fd_8-iHK*eOhqxjLKoHX`EJXRf(jP5eph zc^V6~xV`FT>z*27HTanl&?~&(z}#R*&4SA}p=1j9NHO9<=MaVz+d9*!%G24TLiARK zl|7r=J|20&zCX}cR8^b6F$HlW`m%pt4|~m+60yw+!JSHvt?;y) zHbMy{3?33)XZLl?sZ{FS=kM^ic>E1}Y!RbS`Grj&fB8_&Xw#)^f={uO%p4&GJ!PO3 z_HSH($fURI$2z}#O$ED+R!LTk)djZso0!R`7_x9|y8`j1Bd9Pn+uw1{GTzJ#0#p{eLFV zmdp;`87^!T^BNh#jF18=kM2TJb+JrhYCRWsaI>16cgm)At52L1{=~j^t8Gh@CO-{= zUYTUyHq87*J(l9QSVpzo5;OD~)8nnJ+$tj0?_E>+(Co-p*J=xBfCHXjFaN%PDeOGo z(m{LEw zeNYG-?XhSe~d8 z)%=8S`}{4czvBF(BDNeCmD3=eCeB8h)HE zQgTO&yj%GtYkP|>Gc@TD(V73|Q_%r&4(`u?F~%qD%VUCHQ*wSxR=^sZTQWfNamIR# zFIK{;yg_r0B(xu&Hi~|LxWafI(g5B~*m`d~jwJ{(O7W!&*MJnJmR6oP&jm=XR4y7q ziSEC>8Jk`=ZT>5sg_6NLp#=exYo0_2pa6+xuD^+SH#fgG6YB;#<0FJyJ40DMh~^;6 zUs^c@LD@}@m|VAhRxZ@Z37`4QLFQO4eJy6=+tl&2VLysr0URIt?EyvZ8pbYCcz?Wki2#TPP)4xht`RI zgY@I7L=~PKw`vHirc-BGRk3g~Kn*h@gJ8z>XA>#J! z6STm(jXuHLCW0Yb4E|hNZ-&Vfug-n5 zbv&4T&)Ii5AG0xA{&conFM}jtVv0>xIbVKWuHLhd+-N&#P<}HamEq`|B4~XqV?5F= z((dQfpWJ!tt5mOpir}P7OeyG&=k-C5Lm+-L2)81~{ z1C=*wNrkRWqQ;`s(^tort9jkupc0F9lGuEXsV&Zh7OVg#U1g%DK zi0O#OyZJW+U{o{$jX0Py@O*B;c>|nBs&ot!{wLkGs4ZVb)2jAKEqe{t(ZZ9GJh*yP zKN$49YAIrfC^rDx07=W8dXNuz5=#K2z$Km`n9k@Xo(^{H>H9!B$Qz;LXfY5U@2@D> zrT1SVZx!~$uk{F&FI`mwyne}Dxe|S=rZB+0S+|^HdSgNB?+$pFY=ImT9<->7u6Q%1 zKRFm+d2#64D~{~d8ND2j4r(COyh*;G29AOEPLr|56JNcIeDq)i>t=j=gxh5`U)=xO!mkhz=V}&whME=5uzIBP<~XW5pQ3$8+WJ?Y7REXaSdn(6-SjV ziHZa-F4(OE2G0(0IWV!$NGR8Y@lE#$2V{hP&-CMJzUBq7o;m+MSBeq`ZvFd{=jgvXNa->E=xNdGpFYMfGn`z9J zy2qm;RYeDwgr#H#jis?bTiKqYvbLuw!ugTKr4mhWfMEZ-4K*eH6pf|ok%M)p(|Fyu zezGAtAN;s9g8|XD!DFa^h?Dr^te})c5&raYcNGmXI0;Dc-u{P^qM-(sGzyJn?4?bdzu9Y_5Q z-mA$Mc>MWlW3`}NG{#$|XnlH8IeaI0RkjY(7;fwGm2ib{nanT+tsBfwlvmCb2=C&h z$Z?K)r3ut0Mg5WMMDTjA+S)hK$A=eE-F-U0U4@;cBs=GVY3h(k) z6`TzIB9ESGxE|ptk{g;;XDyRFGLvK5TC*#z>T_*eUyflSmOl1%;zEe0CM9>G1`SEh z)ir%@1vy!%kEs+RhBl(+zxE=yO<7cMf_2JXg-7mv08vIq6`hdmc$uBuW?np?|AhZq zS#x@@2c$cixPp<5oQrJ1^cWocAd0d<6w}@Rn-J8nnRB9y>`*k1FdpfkkwQ;5)?ZYp zk+~pmz_61MJr|H!i9^5hXQpMfXhXG}in>M`yr#s^g)fAn=Rf7?grcvwiYLfc9U$Cn z0dVvHH34EV2?<-mjH z%g>+%*P)I}T*-Y=jR$?TTljV6?uV(&*c>d?37}!yIm$(~z@QUX?RnJ7MZ2(FEtXi< ztCac=cq}M+h=}ycX|MG*eqGm|(WS2y+hSB7(AJ74`i#Tn8toO8vDC%#jz;aLeSeZ4 zVhNr_tGzeIoRhTzdvDMLci20@vvgNqnL_{8XNkJAZL<9}0%gNCU*UGJ@+b#;JMETT zsM*Zq<}6d2rsR42rKYv^NWj}Jvjo3L+EI?n?;wXv;HUp@fVEpo3%pb#;t$R|agTKQ zFToZru`l@eIL{IUp=C`S#)0`6x8URd&iw~GW9BU`48f$$6%%K1Jqh14_=+Dr31+}I zE@c=d&sQKgc5_ilEisoY#xEZgfJ9T&{l2thW3-rMGm#os0~Erfcv{?>wU6K9L;5e8 zCqc8h+Yk6$qtzK9pW3h5=0CqM^`)%37v9;&KkFL=vr+426X2QMYg=x1ep{4c32OE} zQ4Q}m=Bjt|xf0a9HB89DXaMx-GnYDaYNVNuX6;{`xBcRAbhpishFsl7E#|j!!)m9j z(u4fAYmHBzIu;O%Zw&r1^$tCfC<9tkl7S$W3$guU4s5q%W$M%<^Ig@?y#E1RjW3zR z^he;qLZW&fN6#NEUr-#)j<)SJxzB3+qcX}4npJmy==%1dsI-ch zoC}@Jne!h zvS$Rxv1w6u3mNQzCGn;4&zbxR&hkMn0P-KHL_wrNOK74-Yb)R!SHnXO0ySI+ zO-#Conc$?PHDm}>d2=0lR{rih7I&$0;B3+Fz0*eHVZY2a^Q+)L96o`wrf~_^99!iV z4eD3D&k?VBJIsc!jZ;{?H3H6Qt?x}}z;|cKVrHlx{z0naeeg(mg@Ml{NrldSRRTcu0*!dZE35cn=#zcC))C**cfYFx_>ZoN`CeX+%5Yi z-1NqPOZ7?gHZcp;M$GKj3F5#;VC}a_B+#vQoDe)eptXb#0K*4vu-bHib;nXf<#GW1>$y4b+pwLW(g% zbJ?1K$X=wm;+K|!@k4pJMByhO6Rhmhor!=mHDCak(!sWY_)Q4R$AY4~d)VxP|B zhs@R4LPV=goQm?nmNakRJLd~uXzuVg!q0Dba&^4GqrXt0I3PqMPi~a6O^=sJ2BB|; zAVa>hpeW~NvvIL8Ds$irhfj*-d>h90)#ubW99&rVXfV4wG`ow`G-|q|2)oEqhpj4l zvT#2KK2wu48jd6iplOOlI`klv6S-^@v=WVeD)2EhrmcdeSi_0n>rn;s3deUhrdtqr zVubvKCgq*fl&dXJy8A2jMLW5&z<(+ejw;eBY{&}?-;I^0E0I7$=hNXXJBTe$6!*)9KdoB!-`onHcTFuhGa(E+&kxclQQ*I#h&;h#5R>r6P>P; zbHVqrH@W5thysuN52{yum8G-E4G&x3%WhG5tuF5ys*cgi&y)n2p9OFuKqw%8C*qeC zq&0P|Q){+G@%CAg?Dbw}u|niP1=85-lH0Y)D_QvU3_3Hw*7*DsMA5Dy!17aG%D+Fg zS?Bdb4z29C5Vx|S(uJf>a3n;@@^ynNHOm<0m#Rij+i-E#12c?_s1*$(ZxyO*UtxKy zW(+vjN`Ax-(j%AgchRkxqqIJsCtsq&xcz!V`1h3q68@`2tm?;~6n!7A7|P^K>YGj^ zm}^X~=XC4oeHvn(mx4Qz_p@0>T=zm1nG)uP>oDuQLzmZOl-5gdD=kVHQKV&PHNzO3 zU81xh=w9Hs_kVl!Yo3HJ*PU;T(=Bw=m9Htf_A)4aTs6Dp5m>pRl^*prnA5Ew@*8I# z8J5iH0dG&-+b=BCa7%`=+8i?297>{&SEccP~ZvPA6>RSL(3BcijoQcn=s7w zVBUZTIE?{QI^*ryJOV{Q! z7xLOu1tDf&_;@Fl3$r~c7=R~EE`h-;^J81bU1x88CMdOR_Wk=)-X0OK505ZEw_SNL znP64+8>c0$YfxwlA@E{1B`r<2QwKYG`*x3hXHmCFUqHuZ{Gc){DLOMzIdV!AQ~i); z#{AEdWt#mQR=^FX2!qYC1Z9{>uD~W#-1zLTXpuDSR0Voq-GpMIvr= zX?E_yFkRC(_6{MZf$8NTF#gpta0Yl{G~?mz%s?!s-01QgDO?&^t(~7~?L{k$m?dil zL?%ajEvSPXJwMATcGqjkppQE=_D;Qn93*g;M|1pFTt3QyENVRkJdv44m*XX{azxnD zFIY;-%XEun%h{L&6PkqO6R_Q3_r=GoSkOe))~HsS5w7zpqi)HjKJ>iT`%8oOt2mzn zN}`CO>$A5$D^3{jk_5}0$f>Wi{8Vs~8L!Syi8<7U(BO2-X@Pj5u|^Uye%jQ; zLN;?C2&~i&8aTJg6D$lcgZ;7&h%2%uU~=mvaSDMYxi}Dr`HvO0con#s305_Wg4(&8 z_Q(3@^rmv{0C_jOC47jvnmnn=4ok3ni3))%DzI_cU0*UD^2D-MZlFa z+hCpD7tl6U$hkZq$wg(v0(t~Z5@1b@XA~unLZ$iVDo0;F%d-m;DP|2we~%nd%~?*P zD@s;^?qKKSarMX6XIWRbX^J0QM_BsB1e#tAbInkkS;*v=62#R{Y`Ri?H;_jBF5$>* z)%z~3uXD8j;D^y$giYC|6W=C+jybO&Pe^9!n&+w!9P_AP$ff*(x3i!}uEGV}l5M?;Rv{^!=vO5frmPF9bmwrXIxTn-SQb-0 zpcfp!I~%v#;)a)8;TNoU>YV~7DH88&htE>zLXkWq{g2n3&$TEy%J_ZbuwAr$g2g{N zM{qB>Oj7Bpd)?O&oFE%_8lRR)zk=S5?e)L#lH02-?JmEJ!KfEsW3UD~u!4xT@lCxj zr(A>Bz}Xrj&PAh9HqvIo1@GaWC%ry!EYM6D(MLxH;vR6CkpiOpTovfiL#F}hdILqX zO6Qm4>+3#+XJvorGiJx<_2d*$b3V!(!JL>cOX@5L-E&uF<-M{17jhq|_t!@JS{9Q+ z!Q~Y7F^ZzrLZuT8xEGh|nyZ?^5c5Mv$e51^QjDXU4D(qcw4dPR8Evzqq&_$ z>YcJkzM)oAzVB+r3*cc&#Z0b4g=pamL~lykSVEJ~*yH>V>w}Y@ z+?RQmm--zzUb4Nh939b2x$IkG|Ng{16;y6*PRT1g(HuEL1D*0xoLiX9RW5lqsBA9w zMT*92aMcmb4I8?}a|8m|Eol%2*WD`#!fw~<&Hm(>iLz{l5L82C9gL>Tmb5iTL1B;Es7c@wK$15|=(S zGik8I4RtY8?8D3(9{15TsL8CctqqX7@;lH1E~SUi*~{(bWrx4x=Lm6RUL@y35p@b; zG7PFgKlD2V%ls$VDTAbv&Fe=kHA>h?> zus~W@MsP$C#DL$)_%UHxbcwO{Z1hy*XYoRaP;&Jyv6X|rAujQT>ihKv{*Hee9;y3t zy{FZpkNdr`NND?3e%P8>I||M*8E)LZhyM;une6|KQVhiAyhNI<@bZr5(pFl#Ze4|m z&yWk*9g3mDtG!-o;<8tD++D!vzvh%tr6DZ$6&PTL37Q@yanuf3%_NT93crp!4-&Oe z3dXQh^Irym=l)D3Q2nyubfwY9mqkO0%+1<3Yb6b#r622jpSa@-y=~uJ?HrspzWDbI zR)(%#a{xq(UtI}a2x_rqz6Jyr?xL%VKEtA|*r(yls~4L-O5{*k5k#UBXggbgousui#IDUtoK2E z7)JA2kzf$=l7R4BwTJ1%ct)?5DammQu`sCJMCyoAL6jm{*d>biEC2m+ zD|T0(yUq9$AGh-P1*aQzUw(9GFc~G(T*LiBpOOY!qy_KqIh;0 znT=bDqg9>i1Tn>;>d6D=2$5jKjq}Crb=Oq7#Ac#77n0o-Eo0#4tp%2(`bH9t*0Kh1!5b5=NF{4 z-aTTeSRP%kEJV4#paoBQOc1P{vp+}cjfIJ>!EwQh-tyPFkqEA;MI)+#p>{hc>bp^PQ zy0c`On|0xstcU5+_6iOhxVtOzcv1>%y-^~RcmAlT^ULBFR?+Zs3h`LDaTO$S1_$N+ z#x1hqEDR0G@n;fEz$kUIxojw|T`(0XdAFJHzdqngZ7}}~M-eBlvttf>x8YGpsR#Zm zEq?qCG=|t#AhDuB|ET$zt$@s5J-HI**7a(|gp+%(xMWFRc*2q zh;Og-cc?=;oC%07Z|&?qeqec&O}r6tAF;f1)Pz5@Ix5+BJe1`R5v5Un=%m}qPypP~ z{>GjE?#dP1nQFqzuuSOhc5w%UZtyrfLjoQxA0*hLMk=8kMirO3J|rXmf>B)?Rwe1% zmuElyB6IPx3G`vq2q?h{e@iqT0RnO8-tN0svb`qU_F@U(c~x|lfPqsEEY8RaCgP3|MTLGZn~ z(kx$;;K*IiFjpXW%_pAX-3DS0e_sv-E7y@BaffCERc;Y&GJ=iDL+Y?}AdJ$=0?r|8 zWIa{9*IY$sDlhgJ}eR zZuVn(o+qVM-WBd@)h~n~MrLb_vt3A~tcxn8M?okyZ%WCbPF^uuPYTvaoBi=hPq&6; zud7lmD!MuAX6helCM{w*v}&wj4NXdoe!QZ7FZ))g@p*3bv=^U>Q~HbwT$WPjX~B{l z`O}G7M=g7hrRi_~OFNi5B58MiFk$$}aUwvp)TWQ#>%p+_iz}F_?3gbZc1+aC;BQ-} zh%`+!r-~j=C>^DJktUdPh4D!~K+e|(&dCnq6oJ8FDESc7NtH!j^Tk(b| zQHdt|Ui+H>f7CU_OUDORjn$-IZ#aq&@Pz-Zo=*3F%H*25A2Mx&aR1*u&#qDaC4B3lH#j=AlM$2^t*H9X)Abc zPg3IX#K|g7b8JhJ311u7ybGfKWd64>7$P#53A$mx2jzeqetY!e&q>rDjDmV=!Q6{L zkeqfUUWm2z%8B`-+*h%(Oa2tykL!+-qGd+Iy^Pvo!+h6icLEi%fp?c!H-6N6iqej5 z(yq6Am0h6T^^&$Pj~oVj`nsLyN4A=F#(ziNF%L*#nA+*MKPWf2K}+Y8)9UO4-IGmW zLPY^cqi;5T6wc@=urwCrz9UCFA(H&2s;Y5P}blWJz7Ak`_&^RSN z>1oa4yO4p~CwvxkC&K*L2-77m_q_2|DKmfBIp&0(C@0ZGtn}rf&8xbr5vSJr?Takm zSIfuT(s*gr)3g47q3JZbIvdIBIv4RH2K1m0~Kv**`=%^eO3`zPZJvhDBB1ymk>Rc?dCoR@K>a+iwm=AHI z<^l@@{aW1CS9kX};3;c^IQK82QQ~&VG16Mb zFFOD&s=wN{7EFkyC3oDoU^(JtTPJXmrTSyrU&|9L} z9;FgP(TmFtz_CMho<3ORYrRrR_!UT8lGzX|yK?kr z3{Hx0!CYdxOO-2=O1QW(D1iR~likvYx#W-KJotsHbC(cnq3HQA$UR&*PXwDD_5O03 z8{x`H3^l+_aVuBO5}G>FFz7xR6-C}9yNpv_k4MgunUVV&>{VyE^y-wago_lrr07@B zi70NNd73b@_jUv2iYm^G!I>qc(^kS(8pgMt-4;1dcdoM?@D=_iRYk~B&ckWEL!gM+ z3cNt)F1N#Wk8}0-LUk*7iwaa+N8S#a`9-eoKZQXU*j|~OVoWJ5@+WRr3Gqe1nt;)a zWsBGSp7nf2N7#T?4|g<$ckBt?0<<|HMu%|1!3d?i9Hiy31%h<|)6R}4x5vGFzU0-N z0(N9?JjS3AB^CJ{>etS@EuVvM33wD_7I;THNhrCV>*fIn^+OJH6l2j1UsujppZ*%t zQaHWJbelT+((uL!6@`q#5bS;6af$(NK}-++&JDD#OSaT$EDQ#IY*tj z4O&+c*q1z5>!4lbE(t7=YkcKvEs{wZ`R8nfwgY+uQ0&p6(B)E{9ePf!#u)TF+&%X+ zU~uU%)vtYG3u%)+$`!x-tF) zjEkh#Sn4qX_B<#%n*F+A_v^Hgw+K{IugkY4bT3{SZZKwMlRT7dYWUQ_P7_)l*sM4V z->XmM_?%^(Z<2Rdwke-2i|qu6=ZNWS<~O}uFUgFAIYrWaxaV)*lQHg4m>LT|h zzE-M^eSL{JF#CAd?l8ja?+&nNM-+p}cO>Ufjvlm^FG!}v@SoY4PDGo|WG20A3$1e- zO%D0=)*~hoSb86p#Cq@Jo${pB?1T)Y;13=yY5c2Vx67(W`?zm$ROSd%b9Tt0($PBQ z7Jj;>*iYZF^zu>5$8@ZV9+fh6dBQi&tt@6 zhrfu04k$(lhr-(PviTCXrIoIFvo$0JIf4AZlYw{@Elp8V~)#_=J z?VHy|{Qv!_o%5_vW?RlGp_KJ4Tlqr8Rb9`0z0Q7h4x6Q1aERso0o0KJ^@Fe(5LY$G zRHs6O0q4<=Qk?p(phFD4Xhd0Ze&CD`z6KN$WC{M48so)#I5o7}rTmO&&SUGDFE?BE zD*QdTJ3R;8jvqbkh*S5opT2p;^f1~Smn*-nU#$87Q#%;@3(^&5859&)AoE4hqop$uk+%X)o86Gy;rU-^6|s zhI){ljUAf=c4lt9IP@V1L@bpZV2_@FtHifFN7Vh#<_Pefe#~hYXB5r{T`Qv^@^X=? z4FK^f7ZI`@>j#o4#H$m+8;l>|+%Ii;bhZ0q`YZlu*P)5r6rAijpT6+B6jsyQ#qAzK#;@>Yn(KhK!xb)! zg=Gxp_!t2lPXSljZ?j0_J0Ke77~X`rkhF)E+>$=!8KSJT!MZvPE-=<*&7tG#I5}%* zCHI8&p9wxvk$Cxkf7&{5Ecmo2-=r8|`|NW-4rA3cdpQF?2s^4O;fniLI5Y=YOO{-Z z>c3JI{mD%;Q0|MEui?%pL{Uf2zi5r{8?Mr{-$4a2+4^(W;u<%nD8p|UTTeO1GHNk584J#i2>-i_HrS>QDIz}n4Aj@dp^ zr_RG9^$7a)UclNYtu&C_5EfsMni0TqkJSn{nEv-Cx7jaeIx^4o4m`_8wrs8U5_*Ix z0^eS(f+BBYQYNB`Z#-9Wv@&F@Z1};QXl%t_SLMTGY$fPcr3L5!`OK;=%Gj3O=*uY6 zoj~UzwxPDxkbhgTE%;CP8Al&-p%1(MNC`>k12kTldh9zThtAhI)rL%G&zbVPLDa6m zQ88bG|9YASAK*ZSVT)Ppx}FC*1HWF@Ha8^r01JoOJRcy8)gm48L$~Y+I1e8`bR!(& z$c&&fU}9giJ1MwRc;cus1RSoC374J%OEix+#&+n8N=4#{?iAKwF*%Kqa91*eib)mj zB9u0JCr`F^feUJ6UnjRyKUUKZqp1-jr)*HKa6FS9fFY%l(6IdLVJ^A8!e4WbFXx`s zA3pLR%soXb*-7M$Q>IDj!+}PczFesd+fs_EsCdW&vQGom|0q>043fieuG5BIkuTtf z0VV(b^vldqEg_1zylBZl^y~`M@va^HHTVbYKI&L_%)6>g`JVK$mE~Q%!`}&t+|&YA zg{RL^4NpZq6^VPgZ7#o{(l%GcT&4$AjVNCN^tdp(>$1XLo-oh?dc1kaFP}#xL`@Xd z6fqByNTAQQH!xYl!t{oK`>IrXizGfSi(--LnO0r&=^uuQ4tq^Ny8s>fN|^`r8&$6KKFy zoFH0*)hG7?A85w^4H2Ddo_5NWw(hR?rt0*7bm9_X3N&u5V0VQ;Eit*Oz2f^Ycs&Uv z>JX&n_VXn8GgVL!t(Jv-jSAL-@+ZvoxII}r1c5p}gRjZS3`L3EO#FGPFDRv7A(|WM z&bylBF}<(j$$*J`>UlQf^tE)a^&1Om4z_??@5sCpAP;T*GgYl$xyQZ{uS^=2S?i!4VMW{Z|@q=lb)^VMDs^=d@FBn z20yNUwaI2K#)jf|q!9zY&O%8PPl?oAdH1XSX<(B8SWVq@sK%f9cm^P?v`FFEO!eWs zBLd3TQMPnn9Dit}5`zu5# zkXwHxjUKMWnk!=D$rGtj;0KlpCPa-AOom*$J(3g8&G51osGKLcXY*Z+flJv;kUlzoU)LXvDuB;(_e88GVl0$N@=*N7#Vvwk zC$0eDIB#ybp2k|79*@8P-E8jVPfUd6C!JN|O!9x!Ky;89Dj0LXl z2E_?j4ryhFC>#s^+W!-X3-*^&e*|UoH9i2(M=K4ug&onXK|!0~ZbS=-p5NfdK?dAE zC^lV_TZ7$ib$J?4+~b+**K3fQpnf=F0S&tzI(4C@=#$GC(7TaMRBx(S@#;XgSVZkb z-kH>XoU0L792%?do@mdSf^s{fX18b}U~;54>q3F>9fz|;^PD|p^IU^Fg(_yLXZsDc zU5}?lpY+wV%4WjuCh>(v4?#U;WqpM5MH=saK;)$D3R3XP2O?m9LyQ?J1eJ?}CCU(- zUlXtA<+{R@kg6;H@sYU^LwYHXc}PxGPRlA+@4*cnf*i+iG`{8DUV_s&Zo!zC`EWDd z`az8O#(FI1gE`@AEtEWpPz)OBcTXSdFtz9s#ATbxhzu1szLG0yFFZ?<`UKdTdTpyt ze3XPFQP<1$sX!kdZcO%XGv*sY?&m59Vzo#f`qk(p4Nk6%zFS~}LoQ4yeY7F=)>A*G zu$=3eN#_6Y_U`{s=l}nItt~kx2L&N1y9JhV(J_}E<{jV2wmj0V+|b%Q&!WS4ud1AJPgjBC-$RI=34i|T@akxe#?`9y zf%E04XVT<_LR!9-Mx9SfEP9Hr5CFVqdugGRxQcng+@H29 zqeuNk&n~1801A-~aP2&`7qShFYJo#)LxH~7ia zXpo3b+qBmTJ@G7Pf@ZEXX7G|7Q5+HpMqrfpf&|YrKx4X7B^6P8UDAdPP@r~{#%5|+ zP~5(OnN^YqBk`rGDtL-8Yu*8~q_8*lu#E1Drk zvUn-d0}Oyye}cH9nM`b;aL4o1ODZONZs6iRtLSHV01{Nhoggw`tt_w$~P zUMX!{ zRbu)}(k_2!ODvhL2>Bqd<&gW=lPZi`;rLYXIO!JjH$Z`c9jn}W=NVZiszAI8zRuh} zDT;ncHWU2>wN(mO`;kcJVv_Z?j(80HqcISATk+b&yWvwaDW~g%A5*@sw|9Y;$OJwT zMV6oZTo$cu zc;j2SegMeWdiq+}O=nE;*U54v^^zs)M(YGj&|dW6!K;^JFFR@!7^yq^xvr%*%lhcZ zq*iBf+F7__eW};tla2X7rwk_CABIq)78#mIOkP+6 zQZ!xW*BOcRrt-oz-}7&S_&Sbvxu$lpAY4}Q?eYup3$Xt`34IqDTE2|kUHtQjE7ECK z6odphB29Bc#n57Fs#!~QPXvZhcZ%aV0<3`E)rMBQu=mNS49Iyb=gmIE0+Mk>0uv#h z1wrKcHz9paRS?_`qKQ$+*djeee3VFE#IK)ZiU-QATAv{`d~`~PEzsVrbxiPtedW90 za25xT3L->_rJxn6b(st|KDsFyrT%Ut!IB3%#+EHk3h(v9V_GXk#=6c6KIKY>1*5Y3 zTrJK-$Y_CKsl}}E6_?xs9SLWgcTIsX+Ox9gMBCvY#2@EokTVq@65 z1i9ZI@Q4<`f|&Q}%s!x^J`;XGbbg6F&MC1Lz|zmKkF$f{F9jXvVsSqM-1_JDp~OVm z=IbmODtA0}wPO*?VtWddc5l@9_U)XeqSuNt5fEfVR?)}5iolfoo^2SRULRTPX7OaT z-T1m?{h_HETsSSY(XX6RE39-*)9@Vd;Z3H7k8K!=D$CNvH`4Y&V;*y#pSnIMhu}F9b6uf_%rs^5{_&U+!UvOvg zD9w#67@;x0R4&QmdY!RhyS$U!1NQkw#{AqB9XaQ+pgouC6;wYEl*nr2`G6|0`9VfP z<~>I>@~}pGuRF$^QUKUwB(9 zv`o13y{C-N+%pFMaSNAWz>J#t&deoibgSBUzsmEia<1CXwFIFoqt)Rp)n2`)F@t%y zM#IRWZmlXB)3{46LM?kd7p=JOf=R)PN?#@CYmmIg#Abrm(h~n)~b+pEQ@*PrrA1Z=Hoz>CNBzu zCQhTYpu$Y?Pqux`tR4&Gm2p6OZnuj-PQk02BKMlai^ogmEhCxb(~rY^Ib!R@ByhZb zpYIbUijOb4*-#@-KZ9a+r}j~v79l=-k$j+G{4h*(p0Y@OeAqhCVDx77^0$IBo(gU` z#x@e!9WI$cu)%h;3{7M#pvbTBD-4;MKm*0QfT6E}z|6U{J*k72@Oqr{4awIU=B~>u ze?;_H>$q*#HO3EMGFwIveq;kh_2Qc>h%1%~{J))qTfQsB9jOKyIsv(Q``7oZ-J~-D z0urqtv5J!+%d9dak3gr!*q-r4EELqhr@cAFTAL#I~s6}%Dv(RhEeXk9l_KHGKQUc}{!Z4rY?APm)S zfoZ&{DII9WjsR)rOrmc5oD+GQ zza~VYoaiyjA_pIwUv0B=(Rb@j(KNBT-%nJPMI4f#70AeBvqKHSyTkK3=vX%#uht zW?nQXb5~?Jh%rJJ#j~1gJPIVWGln6q@ts7c((?=cB_H}*htC@IaJ!Uo?{niF2K{f+R zRG)l=bZVy)8w_6!j7t@pAx5ymR_#s+E@lG>>xG4JdqsP9 z9^m*vYlOXVB7b=N>sA6}dY4HaSEVS66oud#O|pb%=-qoH)4t>wx#lWp-GD|d{jrcz z-&AQO_X~z&=Ma7DP)@Cg4>>AU}fvZD)#EK|OJo4^7QBS;IiT^hC2FQ;)K-u`5`NqWJL(eVs!rE7Q0@oVL zKQf13H>k(D9==}nhwy47b(qqk6Zl|0!pN%HL3i5LjV+Q!zmuYP9Im^i{#1HE$Pg*5iKTA9Yg=~k zG#!+@jwnP*0OD<%SJvsmg}E5MFR!@A9+V<9p4t4{)vhs4F&I0r&?15mf6rH=aQzuH z#{ZfomLQ_JAwMGOP#I|W>?7IyjikZ&KxnskOODHb`?3PdOxu*Lkdz8f4w00~d)qNQ81%EtuFcnG zDhaX;$ve&%t;FG{%i6#Ex2xgfMk5@y<-Ah~_J+6|@va^EXH|s0?FFzqK8P=utiJOX z*#f|J<6!cb_f9RaGt5W!Gn!Qg@?nMb-=QoIh{ajZxYUIc8KMt>5Zx|3?|sq;pc%H+ zRf`NtxNe0U$0Of@P{C=OC6QTL|9Qy&GcnG7#L8f)Ghd2pJUpGifT4Z02gv12 z{e;pTN-Wo`3MdFIypSl?9BNE%l{&ANJ{0|3ZJ5(zh7n*ng{?ysJgi;*k|K|9ktEC= zvPeeLM2C7?bltpq0LVxNTgmn7>Kv@f?7d(+kJJPH0%wQd4-9ix4A#5- z1q(kCtAvCsofkktf`PuY^As|BjM^qXYp!GpdGlY#!z_Md7QFS-OYaYB^p8+5ugDy> z7&L4p)JM*>McwN?wJ$1vbbVj5cxD|%*xBnN# zkO94@xmPEVghbedzfMs(c3ZEHY>j+@6&4THE!LnjLu9i!UAfg2tB#t8DyZ4)k%~Wq zWQaO&A)B5<_@Uc>k**fVu2^k|p5M#lXI*M#JgB~xfBDMMN711TFNQHO*8Ex@o3Fr`!Y9(Tm?|!ZGqc^$sYejKn83d@IL4@T@2km=j&e2a*i967-R%DXv=! zln>78B#}NelisZkwe#CkM4>g80={Np4HnUoNF49`N?Nyd)Z&=zn&Y7tB8RG|lIa@$ z!oH~WEtJZOFLI}+mp`6?ma?qNGeS*zietAQT$K5o{KibCDAKMC2hg4;_vC==w{Bh8 zD~6A4)t%%r`n>B-fZM0{V7-}=Tb@t@DQU`g{-O+$+p6?*makqus<%5YoTwG<>To$k z!HmrZhW3t|L|1EP1n5=0BWawMX@;1amZh3ir}GWHs@YEfa9uI`&|>+KoeZ%eu}09s zQnxnK7SH&U8$aO9J7vjd@ma4Hw)hZ*lQ-GoZ+xVsDGTV&aF-lZ7axVFcf{K7u0iau zKlCWgRFsHK;!d-&JSGpU4YGeeAFl4c{FI+jm*t{qx2%{HBZ$7RB;}-Ozxo(tQgpbp z-4J`VOA~DO3cRGVvd(+K!c3@#%CmnaxhG}xQvcg^zN8ATpk-NRUu0G@S($Ndu?ib* za8lKC|58>NIG*jtzc01N9{-<7N{fYIWn-_gO6I+IDQTYkiSq2TBPXtuhS_IYUgO(! z#pjKaelPoVqQ)>GueK61{zSmkb&I|Fk5AWftWix%{rKwm6@!*GH}{?y-%cbIcQNi2 zOMvDw5hFeB|4lPkVJzwvz>U!Nitv-z-Ss5wPF0VE$h8B)^Wyf4|3OQF;uXvg?@b<}sQ6R8?t+Zc!~Or*-5I-m?F6 zsg7BY+v15o8Zun^BYH+nLPxjg0dPxafPYOgANK}VRQAgI%;0(<%BEu}oer4G@L zRRMX8)|=U`x@X_yB!?H*YidBrX(%GNn0P2JWj)+u#Bc7FcPZMO%H8Xw2N5#BvS-aV zp9P{AZJ?b1vxtS+0U_#d=>FCW2!e_yg+O{dW;X6Xk2(nrzMMh21@i3*`zU)wx`@s9 z8|#(u=r*rM8wnS%auaN6*job1K9a+;mS@NrKK;P^Hxd(ZB=4Q#MH36JtMj5Wz1|Ov ze`#`*{O4-zA8PAvstSRaK5sVhR_3BXgkKPIO_9CyqIc-vr&^jxZem73AhkEV)M2OE zAhdA*P(5)lX)_mF`P}#*F1yjr#5#?8TE+aBxthE&zg~BEO=!_Q8;#Tsq#MN7n)?fK z2^w~fZ8M1}wmcuNceORv->SsYFQHFD5>5pdwXj>HjqC*@V#d~|9a@hZdDO<&03vMB zVL)RPu&4w@vEv&enL?u|k@t&7394cR|J9oXb@1a?!7OwOu1{f(z**S)1uaXA5o)(* zh?1&U>DTD;GtyxO9)dTjL(!p|@A#HDZLA@TQ+cr5>2}C|?&#Sv$hg@RWu-(=q&){Wv}Oxz3k3~Bh7V6Vau%OBDLpvGidu*;ec+lQj zH{emj2lK=3@$98@+((V)`et(DHg;BVb2Vo7*v6d`E#mHGYrU)jUF`AR&8LPK>KugY zrOzpBr6Iv^?izRgzg>56VgE)hnr3XD5zn$(W>Q&~j#qcb3gYJHtjFeuLXa{+BA+fz zJp742K8JU!SR^tv9&7t0`dW4WU&H5D!y$ju!;d!K zUo1wMDcuLdO0S2xJQ9VEM|2q*zE4C)Aw4z|<+N>pIGx&gzzQ`XY^j1J2ONH8NQNNT zcPnecnvp?iW@d&XjquPf(;(r%W`ZyA>JqNG^0aYtnlsryq?D3!Q9YH zaL3ynQcj@pOPMlQc^z~Sc;)eme;{^m(A!Qrg3`?U1v=X?`f!{~%4ni}&x}oh84sll zY{YEOVM9*otEwzsB!)DWWAQn9v_6RrEXYY(JxaY?1>9{gWVVIGh)%)e6&sb_m5QFooBd9WAm(&;~#WVdK=l*F#&|M9_xTteW-`=#v7z$+f0pD z=VA=P;JwwGi50lI(5If!YL{_8Tr55IqgoHC z9`}?HBj1OzvBsv7nln7P^L2ejp&vz>Cu2Z{A&sXdr-qDYR(^F z8H0yQPYS`t7Hx9l9Mpc#@hFA;KUNf)iqmevNdrXJE%w&cRkWO=8u8YzKzGYo`=}aS zP%a7YeO574`DUId;W8oetwR#IWV|B30VCED1f>||Cl6`!89yR7@|M-p4806zs<`SX zJ>vnN0Z;A}ue;fxKkQJx;Og*wxj@@o|2ypSmfvTGZ(n|(P;_DYQpB;!Y>u!|&5yr? z=Ur~ksiJbPf*xtPgwEL2D1pIL85Y+*27f%}Ul5rM-jNA&k3-8Z{2M?C@LKuI=*6W_ zS|iuLY=bCewmo?_5d;&-)V^m)II4+`BB!=P)bXoS-FsCzAg-YT6Q!502(TLRgY1ORDRyoYvP=`l> z=@O{V21!36-?o#;eXKV53iy^cU}2AKXoAD~%nn^-wrw=nv-hQ=#?O!kMG~QV!K^Gw zWKPWgURr-6+Y=*Z_#e~AKM_-Sk*+Ygvie`5vsoE`{j6(S&p9~n;py^IB?;32g`4k_ zk3AhOZo63g!S_UggZIOIFBzbVELAp>3ghOxZE4BMQT)n%VUZsqRo)Ap0DJbpEAPH| z;LuID_DMSWSbQsG+VtqKk+7ku68lSI9uU%PQgH^{DXO&J6- zA>j{Q_;p4?Tt>G_4ROUC*@kuSurEzy{pXs`f-K2F5bHB8?8PPn#LDn}mBRjRgD}Fr zNYWvvgVkIuz?mD%ZmKt`^5{-D_TEW~TAeW%uO{M3IfI)eX-$GwgE!BWuD7HfMzU0# z?1qK8RnpCsnf>wP|SqL%~^UmwCPIL)2}0L`pJSgHw*m;z>tkuzN7?#0r_94ujnA*{p_{dqB1-2f%`E4}pSaKf)cr z*F@VB`fjmyU1Bs7I0Py2hWMy~fz$JfU!tHyQ~wu=V1Be>z(b%*A;ft zavcN)cJ8A_M6_0fx5xhBOZ*1Z!7$7>z)~ru9^$jw41`cnFtzGFKQe#Gjx4X-NVF#g z{Vn5TQSf{J1fU%*s2GwuOi^Pbw~>eT=az;eop|y;Eo!YOoJcjCWcuWje#BV14>xwy zu4!kF!oZ_qtDV8j>x*lhFS0+&g(ugVtd ziO}P*-QnBD$bxVsvsJS!3{)SIEowmT|9D(5B(S|>+@nc4i6o&jL}wO90y*)kGbq_f z&~=fED%tyNeOW!#!p=d<+WtUw311XDO!BIt*Lhe}ug8RkD7+Y4ZahFWVjLf`ij)6j zJgS^9>k86L#uV>V=H{BoWe+z%@YQJZAy(?A7WlBZVCB(~>t@dmUK3;{Sjh z-eK&0ljuCTd3j{9;Ba=s=R}g2s*_<+BrE6oO7$KU`E?>0^ymi+8`xn7)fe?cpAM;H zRe0{^B>SADeSc%Cc@rtI{*>J)D6?;k@g8c5{@g^`6HXn1j>U@!+o2$ZsTy=pfCbzJ zX0e%f79_+rKt&ATNgHfFUJDQZ%|q|+(H2R8#Agsp!`L!wXlrXn=zRLU1r+ldaJk>p z*6bT6Msi99QpZ0HIR5am=g_2F#K|F?l=SgJ;&jVH{V6evm{+vs z=t;}xS3UDx&7=~_H8nFhUQ8dqZa|Q5vni96k2JQiUH#PO!MR{iEv)dsnIp|&DevvG zM8e`QqZyoE&wRIHkz)SGEC%F?n=2GcHNyl!WWPz`K#vrx*E`FK93o@|1pT*5Q!GW4 z;4*-}W{%_zUiW+G9F3}s&&;$Q9fS`3irnhQ$zde{vg<$+Ch2$|LWyWlE%ka z?U-Ap|3F%^2Ip4{K5H=6f8TZ!1?@a#T}CTJ0bLf*b;T^=z}#T*uZ0H2hSV*fc5s;@ z-F_rW?0)&*u8Rxza19@Mgl3WkP&jM(zc{|zXz8eS{PZbyF5#BbPs;n4=xdY5cVv$YhDEoQ40^!%c{wJTkQfQG}C0uYF|bB z$;c35DOo}$hnkQwRO8+|w5J?zGIG27-38@PFoBe%T!@>`;sV{4?2sT1IhO?~ZC&5# zq+AB;SCaka*h|NsL_hZ+f5RGMTfNZ7jktDp$YCVxHbi%WZg965RC^$gu-&MvtNr=nF39?UUJ^q)$i_X+e;-GJo01gek8Am&8B5ce+5 z2U%ru+^gJP)WVo4EQsza3veztu%GS4nXF4MH+tQ_(0Y|3SD9r6o;0=47lp-&rSZp5g6xhsr-`#*_$G+Tv=q1NNCBK9`LOU zc^qtbtWkOMwTDjMvO z)E~9#p3k)#AA%e6Wg`szTMl6lDjnx`qZ=u{qbu&5mLygyvZ1$zE_!64^VC<^H=tr ztH`d0XG^cgW^%%a$5jdH#Xi+8N;&Ll_Rp9>M)Si(=vA_wDzuhqh{wQrI_@iKRZqOhmYU^JP@#OGi5SAR$_HYeN~gWEay zSt0K`iyJq0bZ9GWC!2iy{lbCIW2x5(D6(NRq4{h7ZTVMQ*N_L>*s&+8l!I}s@EEif zP~hd4kOHT~hlwGBW_K438UwcxdtQ}R1)Khb{W(Fvl)W8-v##=V9Eh9^l1DX<0SCuW zq82J_-((&4>e#3CgNa(cvdh;#^MutN&l{2*ZPDpNmIJx}5VNwbJ^|c!|BB2ScHViE zKX(ebK&%#+&#FPws>UM*69pQ{Z&Yb9;rYp*){AF&p1oWZV+WGARueU$lq>Nd{F{74 zvld};H53ov80)IrK2fY)xG*No5sd_HtBJy9$Op*a3V)DwMIr0Wk4QdD6Zmq?Qp9N3 zj1I*SA(gdv!EGn6$8G@xShHliec{og&utHBCGcr~ygEtHVDhd*jI9*p&AwwgiwnrFN83+L7jUM9`x1=@ z8LfX*=NYq(rMdZaL=fiPsTy{&)gejo4ZS}PC~1vnKdX#9^MWeMqF9)<&wBJCzXIn=bejd9P9^dSzOakilIs|Ik0&cKEz?7P*4 zFt(E~EwuFf&i|NGKxvO$XToEPIF9x7u`h_mLNjZ9iXV*TX96OtZ{`)pT`@Qf5e`-b zZ#V^P(zc5_m{D%`HIwx32Ox!UsMff;pnu;Wh0gEz*bu#+3Qm3*p!Sb54iHm{63(io zEqgWf*t025lU6Ub9wJD3T8`;MJ|}x8`GL0OsuHQgmh@`AzW(`wxDsEbQ()arNS^Jw z*3hlXEsm73FL(@n6aQR1mK~ZtEOfT?GPe?5z8D6CB95-T1V9ojkRmfr~`Xo)AxL{e~1d9u}dHxYH5g7+EJqy9<{3k`O8n7fC#hmr&xtuEq>wpowae2 zN&0n~58?V2fc6Hk7uDG}pl1Fl>a)eMz3&}W26$*`WP$trO5M@U#aNX2_tTxZrfHWT z8z(MC8ZI!?>pgE-dkTAMU+CuRHK}{U@g3ih(xiZ^ebc!(i>edqx9YI+ruD)2-T8ti z7c8vJi8nFi>^=Az&{X10>H0hvwn|>XkbF>&-bDQ-h&n&5WSr}-XJ}C)+t#CVZ1{aY zrnJYB7lE0VRxSw3<_#@9SU_~Y_A}>zFkTuZ9B&) zUb3fcsoo_?#0W+_UkS9nKbA2Xg0U89!xp7y?h~6!fNE*>vTK#60+y^}x`>TXI@Bjj zNX|W6+wi3^NUt=0Ie|VP2y?N2-k8^jl(=Y@hh4>*`kTtg1zHWpmpb|6lQn46BD6e) zniLSHN~{E;4;Zu2+2T4qfUZYAu-g4PJ|KyVvi%HFl2xIaB7H z1S{*@ZApYFr02wu6~yE7UpKh0o>ZrOh+0!fEr~6BXE-+cu9>^_vZ3DZrwBQ2thq>_zX?ydlc+_=7t(xj{Xi2_~?x~D2vCE#a&^cNP#d& z;us-p%}#f#2nkxG+f!sCg}tO}Fe8hs>m+3ETX;>ZIW_ay=m<=wisA$&hTML#(!GJR z6DzQlmhmU&pi}vyey+_10@GcC-8j(vhzOrF@Z^)^@x^26X?;uItfkJ!f6J@Ht7O*r z* z^^e$6na*lK8Wq8Oi-yt*WzOgFWdt}|vOa~4!bLL`flnLPB*~@kB9AT{5ZP8y*c!M{ z=B%g3|KXLR3A6>p&t@rjjg9tCe<*3^KI5Qeb7S7O26Oldkb=$XNbu*u^+F@ ze>sfM?fZvhoRqS?Vw_WYooosx9~$@gWk-0*#vO@os{VL;0rnM3-Q7-#rnKPb=RuSN zW6sxmr%-G_ULZ8+ZEyu+s-%xKNWJC6HdCbvwJqoKg1>_;TrpTStP z#0DUBkEuqN+q7r;fBZ}vPt9Uz{~hPk1$5S`2Jq%#Y5EO8cEJT0r z@1Q8gARo6qi4~lM#y7>=IMM~g0xVa-;2M{uNwxyW1SeXzDunMNw5Vo-aJKJ4{)fhG z8{}56JtMO_v|2=X*#d5Yh>`fI9cRs)F*O_ z3l3Vxy!fYSzSBDzQ+(U)v6(_~q&hjS#48)x?87<)D98m$-CfGdCvF>`jS8(YaIf5q z6Db*qrL4EliH8|26p^Xfe3kD`p(v7HLz(6B7MdKE)1ZeJZ`<~L3MM6vivh%Q+$^nt z(mcR6OJm58)CITgS3<_Wpi>+VHo$wc7KcXkTss?Jz3g!KIxDH-wl+3oPyCx(`P5+3e#QlrxK}{V1 zJuWnL^rsq`KaUx+;DN?RvsIjOqH9EWCS%INzswEDe4JG8RvR}Bw@xi7IR)P|)w&V!X7Gc9 zOMB$ZkB=?E0NZ;@St*{-%Eg3IY64vchdBXeM5-CpHe8JqWYqjk1jD8KTcvKIY8vwny z27S5uy8O|*rQ)Oj%&Ju`Vd%29URsWON^#gLB0+`=h;3WX+{z9F}rbIvRyA&R3N_cIz7=0At3U9cei{9yST z{d;4<(kO9N851dox37KLefsFtzGXGiX}hJChY!Z&^7}*W=kkb65FdH|ke%Qx#E%j`iTlxpHFK7rb55_P3z z;m5V_gnQNwF8sn2OAT^Zf(Jv6q!2IU>(LLZMk#71BpqWAagH zOwv$Fg|6{Iv{}Jn_X@X1`Y(qX)JVs@8oq>}l&eFZaIP7gh~zCmo&@9wv!4MPWPieh zzA*_sHbGltgS-M(RlA)+$D>3SpB27av$dYg580SqoYu7lDEj@znt62<8A|>p<@W;v6RxOdg>q_Z$#; zATEzd=Q?vWwe|R{4Hf8tP_LJz44iXQ|L*YKC<9to?F4V0bwf_5zcg21ru5((c-~lF z^s;}1j4c1AKT`u@e(%JabA%r3WjmB9qoqdnODKp*`WrVGb<(H?z!Zt=5gOR!N-fjl zI)j@F7uJN9V%2{-uI5@+HF5gsTY9P&hzvR7SX~!QFvKS}*Kd#GjYRg9+y>GJ>j$jNklj;tCMz>XJI6^b*MHOfZ`aY2 z>rLzQbj!;w)n_gcD=Y=1^0puL$5-R6_#fqv#GR1gOKyHiDMMG^#fOBJhFYiv6n%`L z4~Lyvnslfm#hR9Wc$Dx3iPNNQHS^9};?|9)sWyLoZ+!<#Do3^?*0!C?iM~IaU@p+G z3vnzsdMp{5i;%Ci$USz5N?((^c>e!4jQRijMOtmGfLfk|7I#}Sb_`zX?_LuTK9uYN zqU`NR4u3+Q#IBJMY z+M)K8^_H{t6M_GaW{%Gdpk-SVlz;vU^lWd`5_98}MP6`3QNaxAFka#3Kc9!m-ZUc2 zJ$@L#*LPEwN25a$cmk`SG3=I7{52m!>htE(A^ob4;Ub`Y2P)T0-g5DaruK3(F!@xRZhG~P<49#AXos{BcWBNVUhe z@Z4cmJ2A!NkKS%mm*2)Pp4mpVr+jk;8;i@`&%UX7JcU`TlI;tS_sH|naCh^>$VG~! z`(U&WVhev2MBWkUK_Brmj7jpL%)^*8-PY;)4@sKZ&hyW2i_BiqY0&FHcBw<@a_6#+nP5SsgPyi2 zS~2Kfvf!*>C7n{PIvVmrbe_Wph8hvytl>isFkx%ATqE`>RR->H%Qr-#^TP-7684a| zDlU>fsfW@ldS3@JBD@Ysy0v1z(t?wy56^h<+>|%hZ|@6Dcv0aKr}X7=xc-p(Y0@S= zxsv<}-FhRl2L=A31@4#@nS)mAu@&9e`RfZSwOkRo3#FVxDr-bPKzeE2+E69gfY{m{ z6aFM-Cd6z~d?@gJo9#yEqxUykbBne#+ENnZW&3}<(j7!d5vwnCpW^v-f6|4UQ;Ek@ zNcJ?f3Nt;ntlAY-puOdFL-&_$=Eid^FL+2wi2L1e;@ze7UR3C(k(Z#kPpwUV`CP}3_W-!$`5<#o;5tM zg}MHWG~PzJA69@;&-E^eu#+mrA-d>Dc{vW`i~oV?PtwI&cFIJ(~SBqeoM)Ud1oLJ;&JNqKqqG?>ip^iv9#4$y?$>! zfuLE`<&QFBrC)L~VJ}*!MGZ+A#P_J;N(~-n2KH?yVSx7CpU0y8w+l85fYZ=(E+BP8CnY9ETIsuHF zd9)1)Jzmzv1sA+x@IV;f!R-|&67ME0?zri7O}1j{MV2M?IS*g2s&35(8*BTYPnb)y zmF^(@&FvtTWiH*%7IMc&I&ep>=}4F6CRbtyayD;TaZhzyP-SINg*9L9tn>? z^`wy1`oJWNV}*>dZ(jVa*9Styl!#P<>O1?HdrPow>XmT#h)Uq@%!l`e8}C>6cs&2) zrZCuStYWBEGP`ba1)Dtcy~gfb)oJHP&AQyq1xLc^%Aggq>OvpRa&m-%x*;aI3#6LB zc4Af9lg%z<_)|LOYOZ7SwX0(rSJXjM*(c^SG4o~GCHGuCb!Vb$7}pqulaZb+MICO{ z@F-q?^W#pZry%z}(3+#rJH?b}1$og$M4gY{MSO$5i_)KP+!cjBNJ?H*$d>4f2hxR% zMagbN1hAkRpIIuei3$S=T>e-lLkY;wSGZq$q^Cc#v_J)@x*2u-X5qmbsr~1PiJGOS zuU0ze#+Apn87YCQLbz+8!#|rn=#ge859>%-mKD`IKOy8)seQ4J(J_uN9?7S%C;P*6 zJSF9|DwL?h7XC4BOE?kgZmQ|#)(I^Dvg;Umhvz$d$(=J$kOy~QBlMK=r`dy4Te*~) zv~nYFB;rI3F_ z2H?m6vMI7hsF2&RhO&Tk0FVjIj!P??A4?;nkUu{1%;%9eL%oi2Q*Sek>LR$D>6xxC zw7RnMRd)qiJ||DgKJ{fU!o-q4I2TZQl3z%F0SdV&Y~Vsgsxv0zLV;m+w8z6QnNtS| zcPp{6mst|&1G}D%8ICk#1N%Zl^My}6`uK@j_PJ51)j5K$AiLDTD(XgNNFMNN%44Q@X3|d} z3Mp7){;O~MW?}~S2>7=@wt9uv9l{)^Vb)YjLmPE^cTMwqP=n>jky_3 zL5|1O^OqQNYZ}$zo!RhYgBO&vBHwLo*ijmRHi`e<6PYED9iW0V8^deweV9ezYRu|o zZ*Ow)qCxnqbE~=AdjD##9E2n+9mo(^9M83Jh5 z1r-u{r%tY}rv_*j+IeQOQROB;ps|(zEN81Kd=L1{jTyD|Pwf}YZNCp#UVC?E`jL^f z$W9wunpL-u_DP?kp6gT+wn-uxbatH7ED$_hgxyn04MzH{-;JCaE!7RL_3WbWl~Bi9 zutO6jLqp1pgQb(+Pw>X`Wq;A}FmzUV=QdH{V=!N7P=E7kw_emKhB1*PmR5wg>;Tv#+2f+ZAD=c=xCd*yEZJ(!~ zpo~Q4hWpxA<@sbA{#>iI>H1XyuT*sVqy#WSn1=qgL>#`7ENzz*vQE;y`|$KrLP+(O zOA+e1O1rn$ea_@f)!2I_28}Cic};7OM~P2ogXDs)#}qDE4W=+x6c{9Q71 z6L~~5ooxVXAGv%DM6s3WT2u2^PjHrU-46A6_eT1cU%k_N?vj7x-tbF} z^_1ic{*06NybIv&`R4GYXX^?*bZ*)@FgyEoz-9{4nY^e|?(SHKaOnG3 zlIN4ofA5CVEsAn{h%&6pJIi^)bWwCWFbMQ?7Castd5{=Ee5M;neH1kTWoUP}1K}pxCW97{;!IA?@O&hJCR@ zR95O?sb_9{vxn59?`mgJ+NKd9ycf6k&~=z!%X4Y%tsYb3hN`!7l`b0v`DEnJuoghA zvnS6d&{Z?O4P1n)y6D~!Lr;;R7PNz$p$Vi?yAEpZFiD9oPvwftW=0>qsmh$8nT^yD zrUR<%ipE&z`C`4X=0vpRK*DPfKdZUj(?0KWf6ldVe}U2|+c^EWwoc;F1Cc<;g4^Nr zy`?+TYb|P(3M~tkCToR=3}*yk+EeQJtmgAtWm=Ez1A=ew)bCD9xjlFg-ZHS0EV1G# z^eqxfQS$W%U+zF>BK2Z zxH3*VhbO8NNQ#3{Z9eAMdr@AO3W81qXvI0h6)80tT(LEw{=3!0DFa=VOd3}0i@RIh zEv7}V`-fq5a&Krtu^!8o2TY`mE!`Fj^FH4J>xueS)>*dL{Hb5iQC~N?o6K-qy(Ch^ zEq;sNz!gInrD2)Ux}F+sU;w2EaeHC`V{kF5niwh_=dMprPWR#3np*`l@*0Y}q(wvz z6Xlv@ej`mXb5X9ZSiNY0FT(Bc0~_I?Oy_;?iN3D@WhBPbB@Z5G}^qUIXhw5j#le21Ii=`zD zmb2M2oD9! zGEw>vX_XA1XMff?tAoQASrU+F!9vAlpw$=a+W|SoqtXJoALNEtet$0Q%IJx$A{r0J zZ|-}Wt&Dwaub$RxRD!9xlfb>^qM!a3MH7BQyxTx*VERvpPKEtk3R!36oAY+jDePfN z#LZss7xU-Fg75JV1NGOvkRPVhVj{YULsNfF4DeLTUsuTKyLJ*iaW0g3Nx8+6HHQ>| z88|OW&~guoWkE8#p!@V_Unf4E6!Oo3$nFUFQIYHfm}1vJsOrGa<4+L_RqOH4H|)A2eQk%+kXb?{(l)Ws_}Sltd@=A4osE*BnQ#SQoyST^S&db%z7jQP zf+xs*!X;fOTO^l-loP_##d732Hya*LpPaJO_v{FbUAYJ|tH7X*K+sF-xZ&iXywR># zt9To#WNMR7Wb~hpOsdXhhg$hxG`9ja9Q+dN9G+0IuZDTHW*7db`)CX1#Y}b|dT#Oo zp&j^o#4y!)N@HFify`d-&zI4{)}Jebsm8TJSgi3LOiT zhQx0PAlgI1W@y_92plO1X!)q^73i3VM%h#wNi`+}dPpnth>nkxW2XQ3eqhF7uJ}vD%4h!8fTmPK=8TPgwWK$cBsqAE7LKgZqO7pKoAky46E7kD#|R{NA4>loO!M{^Z^Hh*8;4lULo{ znG!mz%&NLLf`D9Cq4Xi5b6;H2>q|VhOq>E(yj^GNJfWx1DdnKl*rJG&Q9mEzZVA`! zF2~eK-fk+`OU40Za0y1#>w@gpj}g#rQW_UNrMY?yx-MmKL-e8ea0y8y$AeAgW1xZy zQa2%wqWcF_*Cg|@Z#mD{mAVgVKPC<7k}zDMi@%hS5y2ek9-f=X7@-&w?T}0Rg#Ay7EcSWj>7NHtR3BpGa#yOl+o=0C@d(%X!vVq{BFL8Mr9}i zKEx1=*Zk#*Q(^A4y7No*Uk+#2`Ax;FMZA1pQo0MV@G+?yZK5CYP^Vn}O-(>YeWatO z`fFC`2ZTDd!rrb=Fppshed3O=!)9H3#N_)8Z&nN5J1ld596bd}MEH9%CEg7#O6__P zO7Jl=((W|&X|LRvdg;Xi)03X}z0&R){#LtlM7(?#C&3Jno%JPdT*e--j(1uAKcb>E zs`t5}AmmvC(H1Hb=2NkB8;A-#M9l{tzXE;Ce!$Ge~}CJRju zp{t}{2rOo*H9Dg`^);vx#39`teD;E#B6Q!`rw=RjtMVo9P&v2OR#h`i#byF)huF|B zm^|O&*%a6Km7&G>g(t5n0!t-dI*9wf^{!8 z@W>k7Nz06g;P}Vc=2Y4i>O9t{!0W8EO#zbRCC3Pl42h)t{OAj@ujR|Cq8_?kq7tfu ztkYrbk!!sP=O1JrpZG`W=?|JmJ5h3GcgusGpOZjz^_QP{j($J>65X{bXd%d4;nuyQ zY}`0QP>b8v1RyfD(0{|}o2k~s=*rb<=pcxPPuce+lawz{Q^uA*gTFJe4vO-4wP_eb z-woZCx(H|447~ssldO*Qp*;j&0s7{q74ev)qLAtZG?CxSg5Cb_j_+!#qw|q%9OB77 zXf1w6NkU$DQ3Uc>Mw3o^Z^UF_e7?w{-Gb%YK&j36&jKB<7-dB(LE7|RDs_l&o=u?y z-kfFgh?xy0amUS?sfmSm-$(TNN=l!W7X?k=ylT=2F%%#fZ}vzivN_LbCEs|2?|4f zjJ*iDE+C4J=UyNps-mY=?9e%-hk=BqC_ANw@K%Ik#&4C`OW9{tCCl6j%jE_7cpr7( zd>GJV#Cliz8oyXh-QRGlNqyxW_QdVk6t~@<{Bz}8lM=dONZ1ayl1al~xdmy%R+?oy0H&u?bH;FL%lqPB;a^_{a$N-;E^`}o8l z7Tb)HLu(eC!$XcA{bZ>?kE8dPHWc#Tp=FP3w-m?9-$V41!g|3)%NC+<2siRKe@%Ti zt+c|(be4zW;}`~vsOj`I1i7;^vvi#K47UrUCCKk9Gl&MrWI>?6%vKtPAg>i=6mgvl zo(pQg6$Cjuc45e%p*%*J%o(d6ACqWp8uS5*2ZoJys77bS`m#O}J`4AqXgsat6L)xj zo;i@&XAIiJojM>`9-vup#UR#+dRe2rhw=neWa=B~fIP3;U;imzQPEN4Bz_5E>6_+EyGnIM6bIIAX~TZMEf_jj%-Z=WH8y zoVw_fgVL1`dy(__a%uqZD%MCp`mB4jTfmaY+*3T2Y|J_18 z453!X$G$IRTw(0(iCZIK&&CjGO*k_ zy$lGuF8X=BZ_e^O6AAz;Xw~|PCIbN%7oZJ=TO2*tk-;>u--+pJk)GB<*}jZ zKzETPOOSB8j?A6)vFVxBzZ?2!ro}_$ctyC=<fIY$h}D1CMo6hO-tHSO=8hfTM?Rx zqpn5f{vA`f2PyZ!p8EaYEt>BMLu}`L(#N^g1jW8hliPOc!vuVLE!yT~bfaAyco*ab zU5v`8a?>sjy%eV;ZD$Ir4}?AvwdcHf9_^x{r-8dWGg*<8SACN^UR^Ynr_)Z=z#M;Q zLQP0%l#ZBtw)fjC=;1Le0shI?_>yzheskXEy?SgGwiUuG!S-ijfv;JZuo8) z@*ndp8mIim*A4~)K5ceq-FO8Y!A~5R)h&8m?ewHs*Gzb?CMsps=An-HMBTYd)6s#j z8-68`B{Qd-5z4G$3$bcC+l&0%ZM6rg3|)_UzsVn)Zk^^mPwZX&AScPslH-*d`fZer z_ufbBg-SZim(*U=&Z9c6+?M`E&}0=qX&bH17hZ$DoyMIQtNcTfN4w9Ut{hBMs`s#N zDu2`DM1U$9Si(3y3YzAt;{^`PcfJ4Y1-qh6)lUtuppCNn^)SaI3?!Mn_?>t+lzJgnTKB67C z$W&GND4{Qpqyq6)$2aQes!-;p6=dQ99g)O>@ATz(DsB%_SK|CuI7oXyc*|vUSQawi zpoe}MN|A2kPOGf&5gA@G#}TASBcv%BD;Jo9Edxt3>^^>IdRHKc8GW5}_4Cuq4vF?d z($R2F3OvKw&na8gVVM1KB8X<#D{f!{cO#9$7PKq)^`~(3F1IF0FOSUJsH60au&{q) zEz3`o{yAZB)Z+K5?EcoI@Qf;0bkV1Y$*{H$F=}(ZHEz1pmo|uIm#sN0OwEdgJNGsF zRb7ZR_*9BFwZV(Om8dul9-+6Q$4?|>t69)B$@(7~g_|a+Q4(%%$YL1S^~(| zd;QK|t<9#J$o95L#yJSpn8#+NQ8~zMkG^awLc(xKxaib~({a0TXnId9N;wt56D>=giLOvV2W1*)lwKN7vnp(#00TqQVK@wGz(|JJL&|d% zYNMC`OIIl}#}9@TJ@et?549~VnqIR%UO_68JT}Etb`VbeyJbJW`)fc~4c6_6@2PVacK=f@pbO~__rImU>*&DhB7G-&|9ipE}*ESM`WBI~)M-gMB zQFuBs9RE-y`z@lP!i={1Qt1g=*`4gEBkK8@WM2QG#|<{zKPPPIuTl3IuE}1TiBbQp zWpvK<75n~1IAt=-v<22g{Mj(8d9U$8?q?T+sYhl@(1fS$>}aK(M5E@B!Dvf zVaV_nAMb8mTP$c9A=pwK#+_=5T`9Jjtddkx8vo%Vk?_v-E6vFnHMv|Y%d3i|b!u8Q zBM+wORj6}@Ia-40<8s9t4{4|k?ryRM}oeV4T;+|zoLz2l2IUaI_z$ELCTy)Jr z(0XV-66iKw*ieKw8!-Cm4HX|Jl-$PP`XDCVj%pj~#mUL!p}KlNJI#^~^)BVZDm9Ru(PpZy4%Zyx^WHUz&i3FE_7S&B;EQ%5_++g&WWJ8Y zk(lc1?nLd4yUxE739squ=QSDa<2O?go3Fsg+&;^Bcl6ci+%n!P!mY1ETvg(+S4cZs zD7mlnQ;qQ8m21(P4yRr>Fiv>q4HMWy>W?IjVhie?F$lRRl2rfB`@?X;${gu}2y z1MNNZGt`a(vwVwwYX{lx{jqa?^_ZFyVc}VMwy^ZiJXb9XOZ&YIuQ@&KCNC0YL(1gD zwZUyBL)KPIp|s$OC|W2!@TxoxIsc{#+Z5A6GrCE!d914IrYOQGFa!@P4T!P-ojYv% z?>zzLhc8L%UZ5v>f)u+nX)e+)Bny``OeR1GWJ}TNFitKeWP4YSbdlu`=6hJ&P4BY)*QES>@cJ`qvG?c#~TV>>MUVL0%M+wD}PHER_ux zb8nb8=5Nuu;V{IEr?GEOA(O7mQMVfM+PR-7gqW5Bl@LmqwcH z%P;4wwHhzi9k=wW_pUYNcIqTl%QY~4x_)~ey9x&vsf4h+`lw~2<$+XlA$$DpeyF(1=QSdO|e-2gsX*tA&)iu?wxk(eg<#jaRC3bBY6QXO%}nJh$$CtAx`T) zG`)V}^9McX=DN@30Au%bAcV$CYQ zRO7%{&9>`BT%F3dsr__#_i}rX_cywN5XcrYt4kUYa>#l0l1GE;-OXB#QF|+nsGNLV zMAbKz$f2Hqy`%G!-SZfZj{nS-t@)h2;AoM1Lq(0Hb`6dljDMK8~0f-TYN{ zMzWb39`Ug3SVKt6kE<8R|8995d3T?S1HUZ?I5ee>l(W={yKO{E#uh}Pq#@=(<9g<80 zMdC7OH}1`Qd`3?hZYrYJZ8rz$MkC)nrqic8?KvBYEL3}K-}IE22Q(Dhi3eUINdQ1N zz3^UI6-6Om3M(^lpP zF}6%!c49=q=g6O)r%MHRHFG{nn1j=ZNJ(<4Tvy0E?4>la#RAMgLbdLj-B-|@dc@14!2=#Q>W5YvtZO%VGNXzn@J3w7>&_GS;~ z%w*IlfDEM?zKt2F!UP5K_9am4p8}!gJ~zP8L{A2a5o|OSx7S&lASb|qu&<$j57`UV zXMx9-;Nk*JNBa@8JW*8Jg=*8)?g*{xsahZOX%*N43%$yNW^I798gpnSqx4g?V}HHR zNVIm-2{&iqJ7bk=O1l$TPw3Iuiv6imO?ueC(iv@cl7Ft#$yfL0#H~TuFl`KFe}SCY zlJerb6yADv) zAr6W>kw$Yh%R9|#%XJv}_~QCKU@i>BWY$G$&G`|pJ86G~Z`)|isxJ1bR%+j&WaCHF z_Yad4r%nr}W$GqO14n3|^qDxMYu#XT8mCYuD57raL66bo>Ak3^Yv-MRBYH`AoaatM zXCP7&aeqe$epL z7Tg0DhN$=_7tFqgXZE+pB(;36MO(8)wUquZ=e+S&O&hHqaGXg(Zh$%5BEnP{uBC7& zQ3tZ40uKbP_+$5nef;Gjuf`UKp6aa@mzsh@qtDcphe`{uzxX6L8rz#PXD7?`Jb!5p zE)a$1RKHv%@zBsg9J!+sGMVPYzs0PQAayAK4AT0R^3ntd_B6mPN$e?h^Pt8bVjnS^Z+^$oD2{=lq@dAeI`DA2a-mPcs5oCT zm#cF(cII75Wdc_fmS5%B={K~sm_SVvAjK9{p6&qg&QZ6P4%+l&<(b2fJL1G3vlvs* z_F}jWr-WLP$fD#Q2@{>Qg!Fv_Uqa1A64hE{((bK1eC2MD)bF0Lxq4d7?U4uHaxRi| zCf;d87t9du`6vY|F%GfDs>rMGx3Q~yDLQ>~d+Lz0c?($MEZ$kSsO9G8ffX(Aa>-7- zrtgyNlz!@x6b9qOv#cdbsXdF9ySW$4M%Zt&;mXlCgCv+nAc1s3YJY372Y>zkdCc^D z5uygisr?erBNW0{o~3=8DyZ@*G`HiMc{85`S`5_y$mpmMbD}3n$H#iYY$BN$f>JGd z6T*Cm{rrkMsD6KLCab|6X~=c#>L}D9DAnrgsEg%$h7XdRuV!a{TQG`2SaM(2SRB<; zMjA(8)y+l+TM7*1kLTH|7X83=j?2`21@;T^Qu|;iT3ksXb@;OF0GFqTHEjS+o6!bD zAR2f`VD*yP-TF`(1X_qBnd)pr40%4%gA+3Ly!*UXQ71%b2miYzTxKqrW>0HIPr=e; z$7u5gdcz&v7R?BJAC@JywyQ&{QhP(KCI>xO#rMXo8uXk4sYBga)`h1FMP|)cziS-y zVVQpNNszvf#A_Y{it$6?8HJixzc+YMbks~e^ozw-{)MsWFC>F1Jdq8t1RP(Qj&PBd z*p{EyYZt9n5}o|>3@7^?^fb&K)E#GNil!k8+`>;GY|71Vqx>RWd2>|fIgLy@KYgpR zZ77#dbfL&%4lGIE%(mUPpJ|DnrfCLttxYL-nBVV@9@VIILZDpJhIv{c&Uf>Yg*}09k5-sezHz#V43l|t1bH* z1g&b4=A4Mqu(o$T$rPF^TG<1xV_Bm!65+rbcK(IbmqZGKO>L!{58dZUlluY?EX3q9 z5qdH0VeIB%Ni8|56RKUemK_+sC_4(`iXVP?oeGDRd33AS-@BItkMFojia66sAo_P( zbP$DU9qGXB44HI$^v>^cn3^QTIJ!J6dgOjv4Dv|kz@@Rf((ecGk*eC+!k^q4OCn7L z8JFNts&((Mt_>~gg|%6(#bzF6rO}Y~MR@5Q7KQ9@3!+=|FoVlLyENnYUfV3?Fe=mL z>i2}7gBVIf7C57-UHwz4R%`LbG4Y>73#2gnpZ2)7ieBX@?_YzA1Zdj+yJf<6HEW}V z4$Qi!j@*|Z7D0&?=kFxAaYGcLMA{Ve=`DM6dlA=JURszhiYGI4Wf%#My}9f4VyV7| zXpnlJ7}N$>nBvndqldtRA7GNFWK#zV8)l`A?FJe`*;_004i~FlbVl16--=>PP%5+i z=Mun36!*M;wQ9plcvl^$sNnx&_t?OR2HUI~^7!rUTBd@PLaB-BOo`peaC%i1 z?KZa1Q2Dqw-k%a&_Gy@}uh$OCsanY~xTZK{XM2o*Ygzzb;&gLBkc zAhT~QmQA0aJM!@bi-4DRE8xm{;Ms5T^;1%kI`jkwg=i|@VvcZpDh!IKtR(9ahVs~u zbtSe&k7oEH5jm@QE6+r;aPaX3oCzP(AF>zVF%7qEwBHj-vbE1%M=Mi&67?bvYX>V# zEPt;SptuL&t2dxy0#wdb7}r%(<9+JF_Tl7j^3FE6J7j^S z9d8GfCmfACY?G%6zsUi}fpX-Mu0c zz185(XuXq5WN71d1iztC8Z!FCR>Muydy?XX-6rZcd7(8PnrR$g7Pi(aU-=@m{H$U&v)VPdth_ogdBYm&^{cky%l=SrcHonXSv|_S{)|3C;^2YD{wtvU} zYro9U(!tso#HiF{#EplW=Ke&F_EDMQx(77Os#NX7Q8k@+cmyXhNqdM#B=LgT-tY7` zoBLcub%rBEyJR6Etu$gDy0YAN`vZ#>t2urfN}oKo^Bz~n$25X=kcK5>yy5}m_J!Z8 zT)^sYNH+%r!%i}-?rVvT{O8Kw zOJ~EPg|>Rb)-0^2WL4G2HYeCj(s_QgR>_>&TJH3QCUOR;m|J)P!fhB8tq%{{xX*|| zXE-G_A^(sLB{xCWTqRkAx4#GL3N~+9Afu}Z7?*a**ZgbOHfpQg zYC3LDpZEP%(;-Qf=1Z6DI76)dZp$r_xBD7|dDn}870uVEA1cfdv}iY*BP-B3gh6v| z{ZHr6GSS>8t+hjRT5iQYSHHL`8kP@CL_D*H?Mi$bLgSyHLw)^JyQaMNgU|e3k|c=( z!PPA5uflE084YMTQ%_>gG~H)qW?0ITsm89RNVzni1;GRp)>%cBokiqLeUK7(3gP@D ziv_JD%2dt6hFb6-Jzk@xul(_SXm9NBgnw;TbMrW6c*RAn=%Vp{ z{lHl-q-jyLJctG_8t$*jtQ(RyDGp6gvzmxA`lE(SMjqUO zk@FhH{P-_16d}o9ggt;X4!UqE_oQk=&xFZ2O|lfApv5tB<2}LJFjuxuq&AG`II`Ma z>H9iqL-EX;l|@AicqR=vS}Rj!kl8|Q3qaTjQ>hVR8|n&IoPz-w58CA<5~xq3et)wzrG~uX;dLag;{v!6#=P93oogYwgK~sD^Y%v~ZFpG@frJ!^_brWfd8@a^^baT1?{n>3_ z7@=h$Cl?0h4aaWJfW60xm3HLr3LlqUV*6~ica>A_cy469Zp7Vv1&xE9@}mtUpFn5c z`C)j*&~aUHC?tB-#0JK{JhTbs$HnV)LdJ4N~paSAiI6`d1vS1HQZ9G6qiK`g{6la zkQQar_uFS|8h%biN>Pi^04UQxEDQWQ=7YxLu^wfR217Fu6vmdfze{{LKhipPE%a=Y zng|#y{t|_ucKK+eelk`HJ`TpR)59G@dp>XTfAvxFQaIE4_BE?c$1x9QRJtB#Y;dM_MUQ7Hlr1SbrF?QL{N#7t77byUKFqM||DerZ zTSBNd^r^#EGAP`c0=%QAtzw`hK%T_mbO8j%#Er$+ zNsN6(w`57n#2>mqoMoHrGBmvIMzn-9o93n!A3!H0JP~hE^KV)3Yr0)*g?m)zf3E>W@+Vn4*HecZKhvL3oy=p3rCDt~vA{*wtnRYIy*%a;*=(iIm{9lB&h%O`Xq^A~a{mu5NtbR+ zP!z+sh%}t)rlZUhQk0PVL0#_OEt~2Z?G2C%3*J7SnQ8{wu|=s0;0Tat2vrL*R)+SF zm>;FhnWA-?1_8}^?CbRVS|XI}Df!eDR?1KDrx?@2{|X~q?fGf*E=mJ0rzxs(waN{E zz8VX^stE6mZ=XNu>HY1?%sb6H{psiH33FN{;ushG7XbxkLH_aW{Mw?EXKQn63;tC3 z$I9C}b$Aj(HhWTN2rD@W_D&6f)+~`N{K9FUyKR$vx%66`Wy1;47csG2fRm~6`=+FxXekUTIZ}{QF^T?n^-PDE3LJb4{=DkXJH!D*T38v;}w86!h}%XokEc z2@JEd2fRzVN6mD^;};JdnKWa$ab45)<=H=7P2nA$KFFc&(C92a=s+I<3cX zAVz3i{1i+*CF@ixnJ!bi(A=zQC8;>lKN;pbSfj^73^_z;x@nhuDh>#O^j0suxPD5* z7Urg+G^B!2!B{czk+xYt+N-PV!TVqa7JRJ6x$ z4G#ljpTP0UJ zOcR)P>NKjS1{7Rgz2jA0ut2PExxt=EF~$^yTPtej^hH3Y4kOgc{oPbDYg|=m0X8(J zf*G9x?-_0Ez4?=e<_0mBZZA`FNrH05ZsY|iD-h~JahCGdV7G`Dq}4*XMZi#8jghRj zOWsTi&>VDr<<6%Z05kXm623{u0J^qh~2+8yD zY@~Wq=WI4LQ`S>!#hwBFUmL&AGaV2`dk6Bx2HA%hq-5V zqMvT?tlyeYYF3C)zdc-Y7fZ8HKj4)gFQKg-C6TA~QRf-CL+ft9+?N@>ek#Uh-rz8h zg>6G`lvA0(nm&)g%Yi~v7iQBG&;r=xdM{41$+wRIlbO^IV6L6xsTL6BE#|e(l8^Mi zuiJwveL7UT2m?xYsGXA)kmCRh1P{hwTs>ZC(|*( z^q$l~1H?udAk-GE=12$2MDbarMcnJUB3_=e(G;OwjAqf`F4CuOS8qaik^rGTAEN#2 zwZ-@RoBu7r7)o7CFxbv!0@TxBiI5@xIYd+Hc}KLN74!Hh?T%}C&|yvLXCY|v`8DfS zr`O(k86@JZ*?BhuMC@Y zfrU`_u)3jmm$j^puf(L1z6B!Z8ag^v63%$^;XZ0j!mJ%n5c{Y3!k@H78s` z2r}4PVR%3oM9B+wEyq0)TxwPpY@!6jJ21*>L49~E*55wk=S&QUsb1gz*AE zk%aG(kru68Sk|S{EM||z6!`Oe1)18*|WNTIVW3{1=YVvAb>$-khu`O z%e(1#efoJfwYDL-?vM@>Ku$8(%^5O#x|?FYgVK9dE9iP0T-{r=W?j2cAnvp9(V=~MKpeXCDVb9 zkQyQ1UX-RxRl?^?(O5904}{v@(yq5ee|RSSue@t{wZ&rtbL$onejv5i{ zlvw;d+lWe1sBkv$uL85tZfZumo(9~YUC-IKBC30HAHOa%aTK8ZDqMBt^$dJ(^|y?g zc~z5z3+?2F@vNGaM!s?XyJ}a8b8V~lY@lk|U;TI>>()DLqWu@M5aV^f*NePst%!mO zolZ|x8%z09WZKvj<9WcHlaq~LcSjkfJ)kgG`1|p->lc7%|Hz_Zr9U_pT z;|(~1mxurPGBsBEG?|>&DT41g8D7tC3cvXh?|9v*qeXhZ3U?!6Q*RWL{&41Y=<-)3 zk%I`asG1jzc{kxqQp-2ykMOyX0W*==Xi+->{N@Am+?+6wkA%ZK zs8*MKJ6Hdr7!d50Jog~+!G{`6H1$m`T~#{HV!U+|#^-DzQeQcnNl1%N zqQt?5T%F`h=l%ZkuL0k9DL+-^3qx*&p_n@O_$rUGbeTqV*3S26>6Tt7%zPC6!K@9f zKOgX+D_MW0d@fpJb9+ls|CgED9PvIgM>@i>s)X4kGk?tvvvt?*)KP1FlT)jt5tzwh zR$!=SaA#OghO5o_6-S?>M))2SS-@3ZRa493l#zd_eVb}|^eu(|8|EwxBj?#t_9r@ZsN8n^G z5@G%^&xO{?V2Oy_r9 zHCcFK&(?>FtR?YT&Uzq2V|QmYnlyP9X&)OUQ__RIP(tm*0#p5YhZ(Ach0B(@^xIl~dm@#-6E zT=k3_@nO?m_q=tYo7N zVhjuqr>eGsE_?u}Yc;S|Kd3$%{_XYm_b3ng*x#d4XhL!7O*U{9m9=^yz|HLT8~7}>H7vzpPy1H z|D!Xc)6-!99Cu-ReyuRfu+1Tu#_wVJL4L4rlwldz)_y-vffS zL9R)~QaeklwJxKWlq+%>2cjGr*9y(IDfnd(*8F^nMW$%&f{_7$zUoxksVILh6hGl0 zYMG$#pgeZLP{koV2~bW0@&&&8QNNnBSoSRA(o~9Pgqv1f-?@7JT&#+oIV>5PPDg2UbKFNlhgSsrRPMz}j)TxUVw0d*o18zHoRye?P< zF0Ee97Qr%7Rl!v~6P>CcHII2*?eYeBLUiqs~gXi8|N*`>q*!2G59D%bDeuWKm zs~&7}Dy9aiC;-v%VXm$0r6D+l^N-onyP|EtQ zn2;^QsQ})YIsxy*wo7?p`?O6}nbY%)YP(MxB`cMg)4Mlyh+3mapGHVmIK+Csdw%si z?iRYrZw`nR4Cyr@1e~Y~9MkB%sJzbWF6u0Er((Pxy_!MB8{WhPXXD5H~50 zG$yLpQ_GidoMD1-eC~YXlL|!k?TH=34b?V0-a3-vI)KI4EC=z+c~Ykdxo9=;4IR)xg*2`Q@C(ctI02Z_OSw($Tk(^dr*%Go zvYF#`c%WpucUqY+|9?HuHR1EXQ_?sm&QKPj=VYE`Bfj{Zr;;fO@)`4#_{ya=GpaQjj;L<%$#dWkzbs>5ymF-$!N!&h$D;)0s@&-IV zp|%#!?Dz(jWQ!B0Xqp8x6AKN>dPnX$;{BY8^@g-PbZ@>4Ef!jTE7zH*_i1&|qtjKh zp&@XQTA_nd8Ye_s>I{Syt2bT^7J&-(W?2r_B4A4lE z@Oq&vy=0|lifL5^GY+0cLW5uXq#7PLd2;{0qLJ!CVXL2+*7=W~J#7J6&V+Lb4gsUB z>hsIt(R?^-dhUZUeLunN4nFl5@>IQ9@zauc{g2&2)Xcv}eK0%Fs`-4$<^8QA371>% znrJ<>tI~1s3*D@dE-lP~y2uyFym*#MKTM1O(g67O&j>K_QX`;+>#_sSC7N8^w#vPJ zP(5rH@$?&T&T9%~HwH{j%oUC|goc#)j`~(*kIu3cF)r z;bnqL?+omBWZwO-7xN-oYGD(Xq@9iknl`{r;(mt;JcX=8{^-UVcy|0mo+gVWDQL-~6=%C{K5(&EOa^w2bla!(Pw zz=snamGv!NF_nGwzmi-mTz_-SzOr+C@u=uM$aPXKS8gG632HMtDkp6>)jGk@0WKd? zslGBz#VL#PS&TLYm2No&k%WWK{vUhq8Pw$Zw*Bf-M2bXuCrgnQnv~ECu#_bzC{cQk zfOL?q0RpH%=&%$BNEI=J&|7FCND^R4l`fz_f^?8XBt{8Y@BM%FJM(oE1?cJXP``Q}O=KO0$d# z3uvGBKEJ*2;i2A)L${?QNB+#fR8;J(b5O^%0tv^ka;p*-&c+h|{WJ6fhap!$+J4Ix z)!ZX(rV@1xaTk4ZCIo9xql|HPVs5QM%-aGGibRj5@JQou`vvP^8AQ?-k{Ow$4}5&j znHsN=rvTX(59}&^kWs))q8-^B=NJLJt6ol&)~dPyOHO3Dd4G45jvoADlI6MrewrUA z!h}*vEL?hBmHUkOA~F>Q!L7o;SuOo>%a{+QjvJ<0{H+GF>A7?m-_~>}>r`pbz^Dw! z9@j${kA<^QsZLVrm%vHhn_DyTZTF$^mu*Fdp6aG7JJYOGTtbZ zIwNmI2J(3&3{pHzGo|=KGsZ(YZ4J!DT~&r9?ZWdMCX(fl6Md7w@Y<{3hKFp@5KV8y zP4uKGunKPs?;fi&0%?}%z*5m2FjRJ<50tIKvy9KM&!f)Mq5YV4FTdb&rsqoD+<@~k z$Bq$SfUAtOg(*FFp+_It6>DMFF-_p{lWPQmupgG-ZhA)lN*3`dYM<2YQ;p0f0v(te?2B)VI3_pV&OEsArtSIA*}^fm=((CA%0YD) z(!~vYX+%?4O3M9O<}Hzc#No!MB=e@bd1mSTcZct7Q~hQVvChI7^;30rg5?<@fUmG6 zzzdn}mqD5xyWF{Kr1^Ts4y|>nz@tTlS83X+5+li(+Ao(}t~hkLJc&qIj40Qep^cib z&*mNJU8fzbyb zi>N>P;!_d4gc1{~LPqN`cp!eE3q&&J-7e*$>m*mYGJo4AwxvGujK*?ngkqnROEst` z^L?NgIC>+jfT|Rg&iP_k?;Yjx$6D7wH@|E3JeTXz>(B#JBeEG8p&z@T%C_YO5nB)5 zZc%Hf`k@8g2tkYVYARiO%b;x0dKhy5@c!l`)`Am=VpNR){zzNB1X9KN-AbrfnyrQd z(hkC&ETfqO&s#9c=zLG8AaRuW@oU%>`Jy9zmfCRv%#0I_@}ccJyaCGc{gsCFuW=Vp zYQ1#(^f*P7B7n6%0*N962Iq`v`O7~#*tXP2&2kBAZ zG~+B81QmT)t4XM^S3` zxK8$feAy>xjK}#hr#hd{QI?tlXmH~A>N$nG`F3>qa-#~W=mg4<^5xBx`y{Lz3+MoC z{@$iM$E$(IJEl?^5f0sXw;oB~e=&QtXo_4NH#*Lf+_%v&^dds3%hs3bo?I&5rdABG zs(I`0-#ngMgxC?~`GS(mT5JFM?NfrVg?K^@dVQUNT*&jg?%_Wjxj7~^R4S3vid{$W z#IO8?I1wkvo&a{T{R))paV50(EC2-_q-QhG0OLaqnNKxNt_RE}4GF!HJ%-Lm%p4U# zHa^YtgwxdWS9gl`%-Dk2U{~KRa7NrEW(~1Nq?^8x_Eq~F_utEom1S9XlSyAXZnd97 zS4iZ%*Hp3R{etY8s;*hnKV#5RlRm6y0|RS=k^+1g$DbB!4jdiulS;?~tz=VafI&pPayCj(Tv zqn*a$k(pBYi%{@+x_1!99rC*IFhsmEmOPKq6+SLc8d&w~bvNV4B;L(*u-zeh^bkti zTZTRcs??A;Fo5^oVX8z$BvPsfGTaPn=P$gLcf-Rgo#Z8M$D_{psA9)4TW+p?zIryv zpz#0%TtsLVoAEyJPnM;6PBVEJJI7sW+GSZrmuK0(-(HPB52zBGKmT(gn=Q_q0?sl1 zZWFp0bugtzd}%&z$O(Z~4UW5v%vr@$>2!;k_(2!b@vao~YYflCPAN>e3k6TGtLqC1SjU)`XR= zIhgP3u;&3=sx96eKyCpZ7;9X1;*Jf;BP0?+k-KVDqz5_yYylj=^$@Ud(t>yQ0VnJ- zC=!uv%p30wdV&y*JBw0g1|9veh=MUoRx%AXRvXAgptN`)Bdy_A{$Nm$Y%_DN0htfC zh&3jcO6HT;6137}?OzDssb3CwJXh5!oEq1N8Z#D!93Y%rQ(^eTzvf`gKtOP74 zNAD-FVpb5mzNPZaQ1!$fc|fGyqxRv#OgHpZzygz=3A=qOGVb?&pTDpL)1yq%(+=GB zjA5O*c$Pu}Ge&h7?-|~GYkN?uCVRkp-XC~0F_iys3!;A2EA!QU5{Ux)=S0moPukFq zm#qxHyQZ7&u)lp_63R}%#jDJt#o%LLvsi&g$n$sZjSehR!E>-!2y;ZLaXtb+MsR|L zLSy4^0AdJTCuTdN>iD&h7Rw#5QJLLhY5{P##Z!!^UQoB0z+zhX`qjbt!{VfWZdy*24?kI{H-2Pa*~w zQPC$Adv+JGD4-RsG_2L7Gjg@gO6K>#sL^TOKCSMHYd{8FV?VRB;w142u_xrzjWx*yUOU3nIIQl#7%< zg)vp$oGe;Va%*QyVV%X(8AGP% z8H@*|fclMfziNtPGkp0&pZkR*#xoqRRFgyC1Ko4#K?a9%7Fzw3JXCl%qj<)j#HFGt zYMBSpVIqK%FN+zxk{TbdXq-|;Fy2czGDqq%HfXps6ciBTTw!iegCF}40SYqAo_0ix z=fctJfQx>wPjI4)8ZhY1&@Mw8@lLP=%Rl+KDJNfRnL0f;wJ93+yR)kIu#)@bNy@KJ zdYgmWd0G-L2Ef9j);k}0=lCw-7>J@-5G3^q!`~I`b$iiq)bYo_kk1%xSJvX)QqD}L zs5X$|Ik%R%w2hxIya&lL;Hkp~NdVPN0i{C`>7v`t)U0yqQB05l4vgyE3pkRiv5r)*BI4TTg08u4Ki#4`scaBwhUC!%{u zKkiJaGwgY#gjn%&6x2Dfw|Qp>*Tf!du&axLbfjrjWcROn+C{uA)s@a5&*DtD(C>&J zIZ{X-24#G}lgS$UsPZuMj&a5w=?yZ#oSKugyf8%-O=GLDZ0SoC)Uw~Uz(OyX`Kvcr zf{_i(-oCEvr)&ve#KacuDC##lJ%tMPd$ow z!Qz~yxYY`3ilc}|rU}$p)gv;7I(|q~<>C6%Biri&zyavBQLttLQi&nYH00l-;}(*bwBDbK`=6aEyFi^Az>vLm~}ic7KncUUyNJ6#k@`ZEIZiFzCs&oKT_WU zB#o*71sFi81He^hN_I+*(vn-;(65HXuj+9^%r`_QxxuFtnrH&+ByK$D!3XBhaDUF_ z4i^p0B-E2*GH*`vCl#cQBS)ygu@(tx}m~S`I3+@a(8UBL$Ft3Wb=rfd&*GgKPRlpc}b_z zaQ2eC0mt7x(Zw3V7qa`-elqSRjYj#|4BQ!FW>w$|?v-0&^;e|str_Fz@Cl{rykE*@ zAu$k{;VG0Euv7FOmvviIqpW5W=nDO=dMwA|rg-n{#Q>M4$;ffe#jRhu0D0T~I#d58 zOOMuzE-!oc$jT9=GhJ(R7I_!tSmCebzjUeRIbb?E_lns%?3VH*jItT0^qdby?W_AKUN?$&1$kR`nMm%>dT z%}9F7xOJ{SegPlMvW{I{&WJy4B+UAa?votJ^I0bNHCVfoBL(<5`_o@`Odmv+JlwD(=*it$s>nT%D$>rpInn>cF-}+Q-B8Zm?3O`q zWZ(kUzuMdia}j8>-n>(yZ-h5;*F@ah`Us7}A;YW3XYN><*2u zhL+wB#F$Gk1#RfS>gm>h&H9ZQPCd4BwF`hJ0m>61AjmNWp`vP#4WuU#pB4Iy`GKZc zFSP+c-E2mSyukS`DYQFAMiJaC>Vq+BkM*tq_5Hf z*?M$)AcA9`AK5_enteIDe`;(7C}aQAg~d1JJZ2I_Za zLVVS>E_ksJ-5FlD)pe%4B7!cW*)HU{<^7_%!d|0jwA%Y))kK2J)%3CIbz6;jbU+e* z@3KwH=@uCm8FfX{n$|m*2w#t|HMu(|5Fz6%5p|oF#Pt}LAn>> z;D2);J>&?DWrxzXr1ZIpHQT&d%M; zJ#olZ|8e_7RD4SO7mcWYPCWSM#4n3;C*uG40QgP*dpz_1*T37p|BfgA_dA9S6OF}S zr&fU~&6?>)iFMkyqWkov?{ja(^Q-=Iq6zxORo!$3{vZ2v$Q{bN&W zVR;)%x&GDF>!_Z4Xnj^@l+PL4^)P%f%hvy zbOu2l4I~y^00s{BiE5Vl)dJPc>4D8iEQPYr>oOPWo~>XEV5%hMlF}GO%2XmVP|XBLbC?*>;*JQI!P<+$ zPtzm(0rrfi9YIBx&~I5tny9mr$#=z#{hu*>{dX{}{qJY^H@$0<|M8uJFx}uIN93t~ zH=*N7R7|LQ4Kn5(&@TIt-E)b_IUplHQ#igW@p+jTbY|R%-iCjvqSf7i^9%a~uUKEZ zhzYVHeiOs|@uX-?p})f%rBFnVbdk|Sb1FBGbF1#wNId8XGD{BaC?0XPV#QaFyJNEe!R$CR)W z`u5Y267#z@^zd>^v{5wuND6M%8Q#%7h8y#7 zK~y8p-21k%?L5f%$HOov#Zk@#Q+d13A%3^8VAF=AYu+7ROBHX6Kg?ZIF&TAr$_ucx z!mD@GEEtRb=K*$V9li)&87l__lYv0}utPey>9gwBs@Hv&Hf4J+z- zrJl&l;Xz!WnnQg%uR-f_y~V1h-IcDZ+=ggbC9ZM}4tEZAv8~HCZ^xXH?{KM~nx%6(5UG8KN-;kL}vz;~jH- z-7y!#6Y>e^G`JCw-kuJVv=&e98z!Q%)Afq92G=8Y?qs#=mqx(p- z5U6Zpfaa51tX(DI$q=yj#pVU7fkd;TioMR>+ekfvvhICgs{s9|LZDgp)JO~&4zw?L z;{;d_=HeurnGNQhZBOF?J(`fpp6X$Cron6ltUhCR*&kept-@(j+<;Zz4BFI zTMa7Wr{{TiKA-2-`n;`+Ezn|)bA;=Sh3%F;&#;9(;8Y#70l26B+T~}h%F%;9%Gx$c z{rWS==#H*7%thGe9=VV#-NcYmDQZip+=y1GBDLrAP)CDgJ{4~n!SqR{KQ9G64f|vi zY^^)wSl{L@lSCG0bbPyR~C#DGF|N<6D;1Q_OTjjki_P4 zAGJ57OAQ+%u_)=lG7P|f>VIT}lP=ARp^n3d)}z>*E{7K$?wKnYr|@D{4DNQBbr*}g zFOwUQHpiu4LE_KE7SY|Gn-evOr6Q%8)(yPI+b-f11^&=63zY+eCCN|LFgQnouS8n zJ*YdB{Cv^SVA!S&!`^{k?pzlXEreB;sF;(@U}Jjm3zk9{@J^=!$Nf)_((xnJL&4{) z6~-^OD&DqcG>`brRoG=pX<{?#@1ZVHRY*^9gEkuTDq+b08%0h&% zf-~LDrdxGSv5b18*fUJQa+Eq9l&&VTy-1!jD1IoBm))NY!X@7ilHIen7cn4i+ZEbe z{s@l)1igZKwN-$F#P9t|M~)2EO{kpHEU9Bd_?>u0FgL+#53->L@IX@4%wGhSI}yyq z>QO?xt3=C-@Aa-6KP0aqu=+A_c(dMq-4H572}v|6d|?)FMO8uVcj3tJCWftgF?8w)&3JvHiXg zI(@jsQaEAQPQKKy^e$xqxotGOqpzcIrQDw5DcMx`0+_*T8)c$4f-@5YvWLa043L2l zE}P(Lq$5#38SD+aOVUU1uYSwe7wwB;dt$r_q9eB{%%O&J6bjk4!x{|mSRoZ~!Gxgz zZ!z2U|*hBjy0Cuzo=Qjyo_1WXn?Nd+fZOKoH?Bz0xT~W_2JKwn>sR`pYvupLD>#Lj?fs$wv_Iz1E&rUr8pxe6j88wF`a=dm z1^?uAi(l+zKPUYG{%87M2OkxYXw1u20)h!!;{Epp5I}l0d}VI$R0UwE&7ovVJ0W}l z&0~WM6HK%#?~n|@#+Dgty0K`hxj^M;HfoeG)iUZ40f%C5Yw zT1~&6)NP?gWT|W!|C-+BY{rs?kK=<=JTF#u?pQ3i`>z#blqNUl0@kF<%zi!d+)c~e zUhh@4izTG27oUdI7$yakeoxv=`mw zmcI((N8O<14+L~{dsQ>7N$k@T&^P;>iMqw@FmaUz7%aH?Sxj-QF)B+IIu!2mtIg-hsOPmbTg9=GTl<1$8YCO5Qi0On z>LF0&iNY@o*dJutTRp0s#FVKd(VIZYBr$WI%?{C&m9n_Qv4!6J`Hk=F2W$NuZ6zkHM&yzPh?#5XT(5LG zh*8XJS_RJ+QE_DO{M3r>z$lo?PN-vg_AQ;EAqILA*cWLJ@zvYxOLWe}?~B<&Bue@g z0A;nOA(FLw`Q5g=W*c}Lofi7b1Ag=Kbmm%W9$a^9yQ27RmcmjE6fwR`RjE)6zA~&4 z${y{r8~L`m-r1&mavWVtv(fBgc7CX@A?7w|*BShkq}1^vWFuKhE*F_cVi{A7B||XE zi5lXj!DT*Cc&y9?Z^fz#DfnA_WDN{v4iDEEIklGMZT^cT$`fKJUUHvy&vIrG# z!?=UprF|R&;65srV7`je$4T6+Rb9n1t_oIR&n8JUWy+P!LcUZgn8Ua1yfH-vK%!8b z4IfcsbBzVMT_3&jHTarCt%J+~(S(`#E_8tTPzw1F0T(tis=>S62C7}1XO#i#CN&=y zKKCz6iSP+j+;y)SBAop)ftIfo4s^kh*h`LT7u(d@Tgh|%YlKkbh^3&YQ{AoGQf^nI z({YX-8U<;2sKEi$U0zFL{wHHi^D0_WgW99YD|*r0%y=bS`dEm=NQ)*CR-u4|wV$#O z&RwOyfNi=1bxXV_HNeaN`MYV1*k%J;3YnMOJCHI(nrn5Dn~!ii%e z<<%TYqjJYU7fq--tV!nrmUTSHPezu`msh@R5!PO4SyaEHqa%1VpxUip)r2bv=ez?T zKan0rEhz)B9zuQt?X&c#NZtzJG)7Z$>#s2dC6aq{_w_h0yEfP4@~3!xN)<6z4G!R1Uo2i0oBW&Z|?}V2On#<`2ushz4>0Up^Vy z>CSL|zvzur6__z)6PoEyvTC1!a?sdMAJo4NlC-=W4!EeGAs=g16ptAWGG}3C3hCX3tH#--7p9GygSFeH06N=;UI`;5-*X&Oi?=ULFg*u*bm)BO zu0rT5)yfK)QuVs$&M83~H@6zh8>%qGNX8fccFb%=& z8Cz%IkO6ad)}*kqRR*T}I;cJd9p(keNq8$EAgcwEt2maAVL_Ncz;QNdxfz#aq|Kfv z<76u!SU2f>gc=JxAZRqBwY$*4*(^Z%BBL=|hZ6UyVqTo|gN8;{A}v)#Hu~+GqpnSE z$E12cJv+zqK4~;ub%)h5lJoUF`x2+S>Wl;P{-HTbQiXa}rpH%TA z4Q=Zb>7xK67F#EArrNk4O5J_uB3r<$BfCgb=0s_q)kKCbn3p>COCiWi-Ws`4$l6c0 z-}L(fjUKsaH%2P0YULLUE8uvJJx@t+7jFZpw0*~Itymh$O%oW$c^nf)G?~q-L=#d1 z!-rmk?2~JsP=%5jhAE9e&pw+NF86T?2p#>{QsmtJW^(!`O_Kmm#haW%_s4sNUYeCh zF2oIp%V;_jU+Igz_Kp1Ei**IB{oLGi<#a{ruS(-QTwFa{O78(yC+aHSIW(BVPCV#=;@=0mUjYGS*e5qvOvqS} z)bjS%Gz&0XdqiX24Fr0EwS11-)zBo*4Xogg3^t~i&YACF!gRO>Rqb~wDnXk}GvoCs z_zHGW%0k`DquUGo3lpV2q>18-%y-v_ij+Y5ZG_bod1@3F1Pb437flS{Pt6E9j0G`T z0ICqrDj+Jm58_1nkWAPBcXoV1l!O2q$s^hOwv!YBZ7;v?Sj(!5hD+Sjel)8JyIB)p zq)+E-3J&5}FT%O`EkH5(F^_6TYE<989klaI99(4%CepLd3Fp#SEvz4+nHbrR)A%Bf zZ?{Ol4_($X7t*h`ySbq^^3Yw%oVYS8dCol7pNg|XDzP?_P_}=Cm~kF^dWYf7d73qJithEkm znP(KGcra7-JxOo5Fg)5+slCO>{zGp-fOI4j2cKVMv`(VaDW6Tq54!f>1@rp_<15SL zUi)01unVX($WLi7ngzorC_ILr9?m_;IDO7}2-dniy`J$lm-gXH`djldhk-kN2UbsK zLtfE&1XCZm4Rf0JTv*b6ow2%agM<56FCKlHEH*?7@~6j5#+WSB8qaLHvFAh)ple2l zHqszjT;k6ULm8t{}~Gb^n}JKb&;d@cOE^`Nn4VcT-qG3sl)_j4zzs` zmhgJbm>TZ%zEf?15!#42u9S1{l&xJ^5(SQ$Ls>@1dv{k($2N>If6}X&oj!8*TYVGC z8flswZgJzLbwg75uBXE5CP5^@u0*I4YXVBEdF^`xwCCpmyWFDyto5klT2>pKw^W)< z0-t34iL#V2R8zG+@@j<>V#`r5Dx%S>26Mg#FV%M8QMtE#XDqtfZAlLwQ~IO%S1m0x zw4uEjBfFF4VDs}Wu#5&JW4K;szuoJK0oNdkJ~PUketmwM2}E1&8db4dhI+#fixr^9 z-6nUA>r^6+MM;HI|M4Ccn3>Sz+W@)=L{)wpa9u*@Rm3cUf2-*;SHz>~>|YPE+Ia`> zOf^NxOkeRW{8H>5sTK(3g~JRt<(%3yvm0|;Ed*~;q@BJ8MMs3{8Dw_MrI;-x;@Z_N zR)R5ZyI-~_w1Q+OjU|UD6{iZzwr8cXp!C;-a@|XF|N1UY_(=jI{`iGCJA>Y2?FRm; z4{@iE>9z)8{!KR_n_ay*5fyN{OxapgbbYpxU#%Q+HSc|hU&jK$2{sWo6yd&S{U8$_ zlt`rh+_Gu!z3tG!;g^_T8^QRD=6uL%U&Q?d>aO(DkkPce`&6uNCluY;|VA4S;!;XtCQ zzPIPG%8SVL&JC-vo_C+UKzu#bH#ra^aVMNC=gh-vMeI`g?5Tu5cB_|RP1Em|h#UE~ zX;~cOcL{Kj-o*SB@ScVHMYkOtGqM4$?_As<@m7R$>@`Y#4g&LK5sInQKH$p?!?#;? zbWc%Jl-^wHp00*;IC^wKu9}^+1|LQ@hV8;UjFDY;v77Byzc;G2<%{$81?`?IJIn<@Zt-(|vc8@Xw@BF`5$L9a;I6z*zr~o_#tvC;R2ch#mL`+j+yd0&%8XlTB;ABP^{#ZZ7(^P@x^zOW z%_v(FZs^@Sl4!w>z54pupu2Pu&;_ooDP4QjoR{^yS=-2I@}Cp_F@P zk>54?jLwIrnIM{IInpA_cRB)I&#iUpjC$cSVWbL|>Y(X*b#3M=?gt<0BmV6bGYYJ6 zhdlHKPKTZw61R{$O`EGr!zKM1uB{VJsN9bAXuEKfOKZeCE@?EGTsy9-jhvn>G4{z` zm@=18PmTofckT3^?7oiesVqcco|TARcdReicDvYpq1S2HOb_;+94#?Q{04e)SSnWm`+x)l=~c`A`M|CBPXA0X1}#6F)V=x?+=@YFvM<| zsvh0k1Nj4$qJ4SHk&7$J@a)lyb=t?cS&Z%iI3=?02*#d$m`d50;QwCp&xyzEi-b97 zPTl8E3(CkCiG*M;&k>r zNiHcu+IzvF)>I_jzJXJ~==&NdIUi)rKdO2`&ay`&xhbRcIr%nq#wo&TJ&)H2Qva;{ zcVhxJg+^qSvBftSE#DT&n#e~-yeLjOKV1*`y@LSX!%P^>Fp_8osd0TW^$yp5y$<`B zw3Jj(xWCVP!4H)gm%RK*&Lq~OpcDvTifn}VJjQ+ zRj$Rg z_${9%?DTTf_z(Q8_KJPUBCpj|7JlSwP+#6M)Fjeg`Ny(%(41+08yRNYioIRyCd;)~ z1D~htC->VDkKJwkaEY~Bv7Vrmb~zVSbKA+gg?ESQ;9kiN$=o?`P7Co}zpLZt^8!^g zEVwsukr|b^!|0Bf1M7a%i2FZZeH>M1;F@P(PHX|h<9LEECveuOU~0qwI#l`DoO%FH`@M3H`@pKIn&OrA1{?#1-Ca|PiWvYKp~rCRtADO$CdqS?b*DyA;wQp+4q2Uj(R4r$GUULU1i zWo)mkjybaDdzmh#OPJ0 ztpopW9}&Qb5~&g#&3I(-pjqtF{1~$(DUUN1W%f+Pp#M%^%%h@vw(9jBAW4uK?`fR>+h2u9@PB~u!ceQcG)b%B84aR`5376q@@#W* zFC#N_baHpx{jKZ7hM&jZrtJS_^S;}4#fXm{{N!MS&$Yj^-ZjS~EaQl)gtp`^B`WB# zO=E+M`ixve^lKY5@rOgu3lbj#ue)GG)m2CDtovRxC}b+UGo-KycSQB-3gN8dREP@=Z8p=bYsPC`&EbKL5KN~E+E zV_|5>uRf#c`o2#wFuWBBwucOOPy5>Z!Uj$z;3b+9o2$l}Nz`qs(j+oE-kG6^P0YMW ztke~%NF+|yq}5$ZWHz!nnAt_%sPM;>I53&6YIKTPOG*qk=#ZF4X%uwNok|;3>^8E^ zwH+X7jcI6-zA$%*J)-i&b!Z4uLO9d`YXK6r`BnB#<_fL7A9NaNK{bAIs01xL!`vV( zz|&Z&HN%zLU01eC!E=G-(-9?RM_R5;Q_%EFZ<{*M>v~XWqscALyjy==&};B0o^i5K zzJA+;{~B7ptTl1VhT%}Cy)zl9IFo76>TeKvar;i4Wr@GmI@YNeLJY}Xk6OB2KwA$l zqA^0R>A5Ul9HIZz2}sJ4J(up_GOW^X+vnN1?AT{Vc2@>UizFw@dWpCGf+1m8yO7Z0 zuI-9p$TGso4`W}5DGwJeL6-%D#>PCllCnZ*ZB5$f>?}0>X{C4}bM4tUciPP@7iPDc z!C+HIR+cj4LFYPg~0GrbRj=K~l|0R*%2;hsZEZYhA9htFAC$g(2ySCK5&+hR zxig%HtG`pmD{;W1c?2=ngUy*9*AOZ<eEKdOV zjq-YFv6|`JC&LW{-jo5EF8vbNY*H{f+OiE3C(}MXIZSf8j-|RW(K|MDqY6A?8xb`9 z0CQG=_uB}y)Ry>3HH-RbM}@R5zU2CNaHgLcDx|rqCM#LGQcdTRRDCz_rn2ar7gYG{ zq;8;U-*Wzcqd|5Wrj6#(wS%T%PAg8H%PmGhQB-%@L<| zbY-NH$wBm(cb+CiWRW(Vg_7A+k*df(FZr4voSPG399KIUDO@u1cI26gmg)YKkqX5> zf_8`_M+qr;Y-9kD)hdgp#5^Eg^moHxZh=UF8Wo{%SeHXp-^~vWEXkVphlPO8gC7iR zprxMn3fX9vc$Eb-59o#cuqRRfXmD~Ei1h``*ansS_l%l&t39j2>M@8PN9AdcBPo6iCt9I!oFUgd%W?5on5afgb-ZPJIdnttIrPcb}s2 z+(o9wz6!vkSNVzlh!dj2lUUX-claHa=XX*tx?QID1+2>Z`}3u?g_BXy17?EG+jP=u zh~tv8WgSZ93McQMvD;dLYGODmL1Tm_MAuh8zjA-`=H%c#1#7OXilniy;wi{T^Y&qtU7tcK@W1q4 zwXZ~p{ik~SKWZ4x_u!K~vPfVnU5($nP4gU-I6`6pO(8N>Oc2Z9U> zih&slCW6{T(xrJTWN?zt)50^(7kpY~NSS;uVJ_6M&%#PFxYM zV3)^%2J&~ie&i(dQ$vu0QYNISa&$Opp;RU#?>c1QngfcMue?U|e&NbH&S7q4g*V4a zT}Sn5zpgv`jZ%?b&RuZBGO~IgGk(dgcwa0w*y_d|&M^cbzF#_+qW*4Kl$k(0-A*

      MJTc}P`->kw4QaXPt;3Adcp2C%rn zz;LSFI5qNE>*}Nmw3pwd&o3af!JmN+-t0O1^}MJS|_;XJn|Nah6lWUTxeBtmMrIq}P4Sh3$X{P3Rn*Wv46V;%`QX~F?-iY)UH z_mI-Y?Y-`-9(exwZsKB+oSI*C=+k1Xk>Bu!dM5Zh>^`81GWJ0{jpsWY&IAmk|vgU>9l?j0TdR9sNl@# zk!4TCOQ}X2hf$3ade3}U=Voaoo2HFh#Ojj4qR>A9BiEY&i8%&tUeZC-jep|7cQEhm z$~smw>XB%>wPDexppskXs@Fb_M7lX1`{>s_8CF$Nnjqf)-qY}6j3DYYnmQT)0B_!p zX;nNeG}p9JmOiR=Lp-j`RWMV@@_W&F?NtrrMV+Gx4kVFfnMj)$rcDjrv`!2#?NNJ< zce>+71lxVM0W2!85_@L(JYe5=%R^}=^`a#{vBAtTdOHj}Qg#Be znKuEKM4Rdrht}SyulGK%Bwzbq9+?w)#1pK8_tP|$vx&Ui+dHOND^>Wb3pp~Snelq7 z>xJdrWX8v8?P{zXuc?Bd^Qoi?k%~RT?pLp0Q~j&}iM>@P)CC0@zheu{qW)y;QgwPe8(T29jV+Q=Pwg4Bl`~v5CvHl9eL%gH z`EE|c-KmaO+R=RyS)GLuJ%bfh9G1?ggL6I2m=0F=QE`pdsG1DA+Ll}A*`iJ&31^g> z*5bIOfVvCMF>2rdgUKPpoitj)B0^egY}d>!T`+fZ{N*`!4>-xlI4+iMK9$iKNd>1y z=c5A&<6_H8AN>mN(*h)Z<~ZeF*D)|GNlN6R{Jl^8aFO4s;=N2^^Vosqw=wptyJ?oB zs5RGhycws2gL$4UJV44+fycar*G(R(y@5;Vzee!CZK^zP$&+tUY6;?p1&LM$SVC(;DN!n)jujlOWw;YJXgDb+~_O5rP$a?{wG7-g5G04K8B$ zYklGEhyK5OhjDgT@d2zv4%Ui~j<*a;q%IIv6$zIXf_xcM&ILOZIL~XVccqdaM8rpK z!z?Pcc7z7bcqa~vwJ%;sDk;3k8W`!rzs*~NyK@B&3D5KstT6@K>x?`RF+0u`93>wgqwjTna`um?F zoNN9*6m99zvG7t)Aioeo=E&ops|3=-4W=xb{ug`i71h-G_G{~MSpXI3Rai<5y*DE)Q9yzO2qbhOASEEu zHAq`ast`b_N)8v1fAD077MvR_6z^>}hb`;JF=THpI3ilOg| zO&Z|W_A&7MWE7!9Be_)6nrql%+W)}*{_0`qfTZStpk0OCt#nB{bK>&>aYctr9a|wj z!P9VCAqOCk&Yiyy)Uxnkr*q-!58AJz_5b=2c*K!{zAkJoNZ-CGn`!8c#@)&X*;c}Kz$l!o4sKz}^p62u9~uE^rV6vWIeb!BOVs4r74I(vcU4nB$y?L-_` zFT}3c6@yiL+i#cM2(xzA`C3YxF^@4)%L)P)Am$N8L6N#iT?MMN&b%fOEmTX<@gTml z&rY^-Xm%uLdj@xys^6Zb^U>Pd@q%e57_QV*uITNlgl>M|_!L8Uqdq^T3bmQjx3(M{ z(tL=)mUq;@Xzwppcv=f95vOSi5~fKooKfUv+Ys5`zPQ*MMoPTwT!FLe2Y+>|`dQ0H z9u<+heajN2Vg$Nb?paw~Qs}_`E^S(u=)#t%+5SJrD%`kM&-WS2DLYfc$M^3Za{$ zlSxh)MHied@Z3FIxHeqnsdY&9F#vDS6}|m(bhGkB#K7*BzD`xMiT<%%3du1tm+LZ- zK+WZvrbe-BA)+w9mjS;me3yJSSN{1!Q`v*Bl{zZ2VJ}4({ux_WN^A zP8%&-D7^Fh2N&!$x#qkMy_U^My`N&9fAj15g}MLZ)+m{6IqIKnX{KzhG?6x8=E1hQ zSFEJ#5X^2cBcAX53$$r6f6AuI z=yqd}gY&0&U$xg$m8J73&lNr-eP2-iNPgMAn>6K$9jl8PKkf+aPC zuY(uUL|mUA$iaIIiEf8o6Fr7i$UOafD2ush7mrWV4%aKLH@<$oNpu^YH-ZG+nEu>- zwa6~4RU5MX6KPt;-U5;1d#!PCgQ5R`uT@E3%-}(Cs9Khc2{}C5;qk;YSpQ@SrBc1M z#59o4xT1mQM$jq3i<;e4c4U-cXRWcshj3>=nd?@*-yJa9QCTPLjDB#7!AeUE2%E^W z8~~1o{AK#g?)aVJ_|)z>O=$!hbx_0kMpQbS%u?fH$k`M&;JH*2|2@%a_x{jyzBKPZ zUj6CKFJ;U$3(wj^&)AE%M?Z}p%BJ*byP+RkpBq5dbt|QV+w{kELmwVFp|JX>1PiUPWm- z?>@5DDBF6Py~T}{_EVb7A|J}dXNI9%>Nz`s%+gsm@xluijQN*16x+!niv!tf3y6Y# zqlZQ4!m@?qNj?>NG_v8GWzLuysiHHh9zVPj+kG7wG&;B)TSACFYmFZtTWVnwEzRUC zd)|&(=<;W> z-P&S$LywBS#)ur1`3B)QWz~n!29^c8W-h+zclNR1`{oM@2Vj#NwqEA?j!IW>ahjc5P!2a+v^F@U^W%aAr?IUbKW4x37XFGUo zv#XM-``9o2ulfcIG%6xRAOOaA8{@gMAu+t)kjEOZGP~$<9#CHiqQv?sv0MA=S&`v^dcC0GT9x((D>kD zp8<&*66k-U%L*kyI|8T5A;q5Nf%8)9Dif~#-)&SvD59Ta8{Q0vtN$pqxZ)5#T^x(X zMUdmja%&3>R--N1?jGr3*}?Y~zd;AxyWXlIvo``uuh4@N!cfweyA)!=XAaGTy9wyw z-sAI3^@P3VN#nj4uI2Ib>7T3|Ca+Ex*}e^OKD1$!mg+NH!fmm*4u7Q~ahWq;N zlA`Nze-CdiGnr4ab2q&;k*)(?q5SO364Z1=U2e#3hPW1BY$U?vQp4<1TCBC?KXh=s z+S>T#h$9p&NPXks^I(gjVYt@q=g$^ha@s@N!wF+_gUMV^=cyt*h&ra3jj+$tRW$77 z&y8Z>dGHVXTZP@C?9&T#D)BH{ICdb zVxS}5yrM+W@Sn%u@h4=!u& zVyezU)QnYQm^#Kbb*`8^Xp?_DyQMt;Jx1E$SB>(^sn!mbvc$e%Zb1Xu*{djcJg&8WKH%Kp*xGv_C%fkqPdtj6&VGPzb%Ki?7$S0GgXzkL;W-dm)<7UKk^N?Q z`n^Aj3Am>F#glXAP3EpF&Np>wPBks`O&>3@pFQ>CnLm1FdZ!fNiO6loW*8#_cYbaj zJa}N^y}e`g!6?W$?%`2uGYkS!f?ik*Fsu#S@r(S=|7+YRUOiw7cnW^p9O5oap&gYJ zSFG1ieYi zmQUHPt#iSoy@PR{X=4B!)oXF^C&y}~lE83{wYtsJr^EvOj5Ew9s2e$!ED=nkl~tAi zny&k8N5px3I_4T4bu8K1ka8!{%y%}Yb9>4Eb~dwYJ9~69`fC@;LhapmP}n3kf0=~n zpQgM~wH)hG&?w>F?dy-&vEZ@d-S+uL%Vn6%UnzjO0rx-ETXSj^#%{y-#2EG1tyd8h z!FnP*Dv%_u_j$J&p+d?Qe4>k(_RfdF3xA-G>0oVq+{iey@tB{7FEF%b3n{q5`pK*< zK^;~85Plq&pq^rpdb+*q;Jn>ZiD9Milc+rLpmeSWkK>VV@H?9a!NlmPU#$RoO2lR% z43FIG8l+(g@%vf+oJ@GT02BwzA#T{FSm5@0ev&wGrM;s&+I=PmA=B&TAqX zDo#zV9kuYLyGN3>*)BG}#kM-{u1)Tbr^C=q8@)@mz#WI~>|9EDJwe_2bU`uj%7eml zI}5gYsw(LZYV*_s_no7CY__^>tCk6dV0CsG&1c&ICrdoKu@VKhR6O$ZjKYZ;4Vt>p z*e1>%1M?jUvx=3QRVp^@_!+`Ml;S{PPQQvsbA;zeRfl7veIa&KaXUt>h}{-1P{pC) zkH-*Q=Z}Xw)D?Pnycs?~cJtp8Ev*Z&e}=As>|r}_4Ry!_D?1M!J6D+4Jp+RKCv>mVH3{thQ^d0Z&w&xx`8Hv@_{${4au{;vI1wWW@y6)L_xAysE7)Uz4*60z=f)?>_r8dp&>6pgPuNnk6QW%I(iMi_mT4 zT7}^}UX#rWXjMSwcn$rlYp%C?i{OBRrZkkpjff;HG!7V{_O+tS#i~4TXE>f>B|UyI zgm(6c(YMLCl7;OU zp;?ejk;w>@PEV!(clV8l`3=J?!%>y3tIRTygn>07O~bFeG9z^_wr4VB_@0trPTRAR z^rtus)gGT#a!1WMqa4t+POpH$brVUtN;)VA@>R$lN4-y4xxhF+Y>- znLYjPZo?O^EqVx8{duSgK5;nEkz(K%)gqxq9ePt$FZyA{LtRANX=tC$d-o_EEU-MD zQr6(Oy-r7_F!})%?V%J?3g;b2 zjdJ!_;J)|=6*WiQyu03me+>~PhjuwjMFl4drZNT2Mg_xcc+HFP2*(oCP-K81G_1Ib zhl=@rjbS6u@#h#PYfE#C)qyMnc3ig9>5>2r_Y1fFF78a&y4_IRusp@H%EureEWV9$ zx9WWw2BkQ#G5^mY=YP!|uYv&)`gzVlkFgrlBtu0t5_t~YO>tRD?y$ile?O4>nn2!Y zHF`)63PG+qt=6}dxZKQAH@^Evl@AM@b?V7T!};}7FNSoOPQ{H9HUcizH#hf=YxVc5 zrXLvh*9hTKvF;G-Bf!GEA>Q+t)0EgUv^+s`;VelzR;58yop}9;iuCx{Jn(&I%w^h zQu8klW;5n8)qBS)1|-*|q*h2FY!f*~TGWhlYEOUJ!5NclLmJLCp?{+vPkRXPJ^8g3 z^wOuT`gDv=!^a0_;C1kj#&?K(DWoId94leOC-Bgb+-Pm~L(VtWTdNcbn^IZ8&b6z>j=rdpl`r0#_IOJB z7)m^sz`$n>uRfpZg|u94QPS0@$EA-l4PMN?sxobM^^{3+s7FVdH@l?s+3^1KyU1*@ zr$&4~Kdj5*`5UdwxBu&@&(E*CX&SqIN)zza)L~|aT+h!%*Q9s-kv^vRVpeCWjN-tM2>E{yXe5Zkrd2PAB34`=z-V|8UoEE2HJhmIadk-1+b3tL z*Q-%|yQ5W${bF05Mwe}H z4C5aZHEyT9|G<=~QrY)IkXg=vRoQH0Gq zZjJeGe!ff{jdsom(5=t&5C<;DYXUvQZ2}{=uX0(@GbA(gi7nhiD#H-Iim@kwhQ@YE zp!Bw9F>E;`Ja?%c2LX?oNu56M05H1@ z>A#j5f9F;Uic>o@O`tCEkqh+-Pcl>Jzvq`~vM%G;V?o|5=~ORf%in%r>|mj5dQnh= za7c&qV|M$R6tI4VQ$84dG<&+5r+++&J1Tnio@`DG=#mh4$?!u|qx$VD>n>tLEwvj3 zU{3e3!W&}_EN7~V^O-ZYBzsRUsEwQQ78T8n?=1iJ z7ZE6opAbE9@x+O{C(fQY`O_=;e=CxIHrGt_7Bw^1glJ-5b{JR#@UoP~#=J9;*Jy0r zJJp!MKQ#{a@Q|bkpbm&p!Zk+lBs$Rl6g^_;hMHIHe*}ucW#<#!n}GB`Cn(`>LHcmcu{Q z_ejK12_AHLr{duWfM+fxmg$q{1DDgi$@jF>^TiwcMCGZ$27`Fi8XOhvI#sp09l`X6o!+&k|9Aa`>Vr`#oMP9^;qFa zj5ZlvW=}btZRIXv)7G86c;Tb&=`(T0OUAdSv-m#P zf*VEtURtb#MVZBWDG}e@%)GjwQvnACAGL-NymA?qv`mX9<#}T`3n*NP@#Q;UTAwCZ zDn;VJLpAEz4akny1bvXxcYj8A6UkdU)A5`ypyLh6?QGhj@aFZX7~7?k8&-{pqJ5_8 z_CfDMG5%xCPQ-|sM1Pk%P*=z}N(VAbpQ1O*(B1pbk^SpnX=bCF9Tuv zJ!vkJ{xrIbI=r^RD;RUVJMbT{3~?UadvLSPgbyrJu|$b|-8qv~%}KCg*1VN`BV0L; zAi@SaI$A2>_9DQ3&(E&hLfT5Az@DLSUYZ6-p>3v#@%Owmo8=(6-?`)MGOuPLF=2hM zBqOI{UGcgI;$+IlwK+%0iDjt3n6?VkMC6^p$Z)DgvG%$3i0>*`<*_=NM&o!0Y^aX2 zZS$+S$gAA`EYM<-P8<%6>N*n<4%P+x^2K@?vpmX~115}xPcl$u?bAr!OQ_k$T?yW= z0!0cJb39*d8iTr~_tJxm)`F~T8kzmiy$PF(GH*H?Eq9jRH;wAsPV1uXS@B$xc>9vk z8n16q`dcadrIpU>t<^GE-+<=pI$CJl>?tGdWF`LI_jp7z8j@H^w8ulka}Bf8ud5U$ z>kAaEI>j^!Se$(^I})N3cIY9aLGjViXq$ggXxqzB_HFxUE^;;>hV^jRbQsZesy3E5 zE81cGc#i-prhhhRpcTB^0_^Ja2$M$l?*Y=ktup654s~Aw;cX#K&LERr9`z`u5Z%q{ zFDIaDrcsWML|pvXXIeuquP2R`9m)iGSJvddiL6Cj%;Oe4-;jI}g61~#aJ5k_4jAh2 z%Nsa-!zUZ>5mvl4iIyfEh&L;MhO*=q>i3T25i4K|X_gO?Ph+Atbbvi3Um!S<>6+)G z8PzXc!27hOE=o$8Cs#i`B45qv}Gycxk4?lKHlGUOh`i zH^XYhY`pI+Z*r@+dp;rhHK)LVb3>)>@aE)|+2zIp^TrwQb-89{j@7h!ka}=@qwY=o z%?O=^nS_LsW%qvK?q4|HEuBIg))@?BU37+FrmK7np(0`l?-=z4z_Q;%1*^$u^i*4m zYnME}RLk9r>MsgQqjEy~+s?mD3%~Qw>}ii@n^Nrsdqx_X_~NnX$ZIgt%#l7~E^`W2 zt(nv7o4aoD!RyNeAsJKebQ@0KVlY{?--NcxE&|Vnvnl9Wb{0o>IbIUoO8=1#_LfRw z@Scp3mzD$v>auglwJ9;mOxph2CEgpgfu+jsx*fWnq2UD7n}WFr!${=LR{CY59}ekv zf{f0#*Iw<4&GqyM+%Jxl1Z(N$#Rtq(|5Ut-D}e&?rM!U2)k-3xRH_1NZ3wx<4zDWb zZdz4u9R?e%NUqBdYHyPi(Ay$>EbF-Q|M=5cFSyoTwqBx#h~6I%Nb0$_bw_5iIYaG!N&i7)gTD{>rH0)qw3Y6GQypN-*SoMiCCpN;QD9Lv%= zK=I}7diY>^1ye>nbr>ClAUd|^8$REu&jffz7TP#EzLZ!^8!T#@D0 zFuhZ&s@sO8d3D^{2N}W2lS(B%#KJ0h&)T2bcbZHVI54gh&IJY@2vbV}CXcizrn%i>Lvz?b&Q@>}pm{m(E-tht*5(n8In@#dVT_<(M~ zLmsA()G*wHcVAjO<_5E-NVvUnYkpc>XfXlDnX+Z}{~hbM%yT`s&*j3{8+n#$W|Chm z5=-%6gsnDlNM{k@grnAU`r(q=FlrjFpHljpX!TqD(PM(^T(qLEsPOE0a%Yl$prr`eV`g#GmWv2y&96VKb>Q?Y)LzUoaI zhzq9weC(0E`nCU2=DpjTPz1cSouNjCYK>_&>syqOD5owTCp^%G_J$y_w)23=EWlKsMHe?!d~ zs+}DABfy>j6s!L|@kkXl&Hix5TqxSCqcgoPHXsQnb;teub?5N@i~M`)iSfUGjT1x$ zK59Jl=d7}90}(9I)-^DRaB_g=qIuz7C@yAq*_AA{I+WI`0H0P83+4@4~8zr;V z{AhTPc|>f9!YHByd4J{L%Ygwrr7`iF4+P%?BZ!DZO;t=~spK|Bd_xGu;%=2g$tL#- zfs5z^j6Q{~b`b5^;HEMyy9}2>>UX?!aQ1C_rX?;SP4Rg}zNP3@3vrO&Bi~-))h8o; z%O@=Rl}pJk5g-RLBA`S`qr@dA|9O&8Xjt**Uy4+{!{<#`l(I2b#Gv8XiB|+a;y~Ac zbHmP%bw##guvv5&2+8rIAe-^Y9U?48`uadw*5XNK(pnkm2DY{LD9Tv+11JAnWO_PC zH`e|(3z?vM0ZN})w<*1@bl_7gVifT-JXn(bLt|_ftm^`N6=V>XSI7(QddhTe6beWQ zS1M)Pp0X+|xo;-vqmL}KZi7+OoD7T~ZkgHQJQYw~JyA1Fcj-@zSCQ|4vcI#11$7OmMw||@vv*gow(qSzA z)8dxn_f25{5V5aZqHfIztqyoIn|^3U+-wP1vcbC$KS3wPS`c*uo zpDU@?^N#}AdJ{MW@JJ>ak0@13vOZ*@bhc>yjz6x*ox7A#1>~U0txlx?elt3B6_x)l;M&*D=yQ4UH||zt(h(1_qye4gAWSc+eC+qybWQuodsja;I2r%7yTSp!Ze3TjuYyS6L#%Nzl zLoR(D+FJgyNS16h1U6K~Hyc8ztjiWJC}(CyC(Bd9Q&c~1SUM0M`1fHPL}oX9h2%ux zBMpaAza@)7wTjB0*_VJ;u9s<(#f20yGC+>S-YMwBFR&tlSg*+)dqt){5}@@d)qf<%Qmh!Dx;nIks6Z7L6ayz=?fNTJUCaoNm z6ir%In+r(TtC4lZ`kn6I3pMn)4;K$#!zjRtLv`vt;DkJiQ-|b%_ai^=S?^u!JUBP)|KHIE6yZzt_^Gt1&2u3wx zpV?2+(VLf}?d(vS*D7{V!jBg^gxQZ1aVnFGYVGey1+8H zla!QNI}Pk!vqY1b)9d0FJJwxnBa4dLyLKM+v_cDu`Zm$ng-) zW%|oh64+0LILtK+EkTk7O}%ob!Hy9@+D!j)ulD9 z`Jb=r^$nL$4-3NP=W)#$tDo2ebRDWNh}@C0HE2}l)FR;QmoPBuB5Y~)HS3LDZk2a5!oihzLsywI)KH^6wb}WT&qGyNxO5(=nDfA zi^o=$XS!d%h&dgg3O4g*-;^qg*ZSD=`yaWRW5d) zsqZPY0`OhBx+%a1gRaxf*sakf{aKkvp)<_@uC66s1nh%DzaB6@5S-;ND&fDNPcb^> z{K+F0JJgx)tab}fQogS6aQ16PO#4~PO~%krH1?QDS5{+^Q?vn;?Ldq+Q+giysKm(H zV0X|;AG+`9IPU-v+?--t;vjJ|4n8{yQm#Wd6YpWm?{cEF>SCl(DEp^urs(HF$J?); zid)`${zNwPb^fD=_my5Ns*FHS{9f$UzDdKI=0Rw_gh?zHjbMlpwa1Hq#%x|=?1Kj- zO!*0ly?nXrhKiD2 zQj=9%2hG2f?+6yLHc5>(+7H|X%1Y7PX_bHm{=>8#J7yY0EbYw|fMrUR7{z?G3xA#l z07H^)tFw`)luYR|o`d$D0bX&b#iD{HyFSZ-g&|xa`Y8ms#H+j);znCbC0RT8%rbU5 zpffNNs%)$Zlx8LXbzZ5YDm3>-Fm+knY%x7}d02U{DUi426n_2!%qvA}gW6q+g^`^&idhi_#xreZ#UEZ3N4{9T6>KJ;Qem@LZy`Y{GOQP?2Z9NS*!M zd;Im1U7vY(T_tWuGGy0|&7btMR0@V4D{jxKM4endmd{yU-?_9T6nA2a@tvx7%>9Px zU?QL++D%uO(BafX+6AtdT-@MCr`QCkEjeiQ;O7BJ5_a%x9Z!WnV|6W^ScAl8cxy?6` z^)K(Q+u2srpJJc%zxm*>4ojrP2(lvR&USBch%TY&665>eRnWm3A~6ZbVFO|8--v(z z1(cjm0&l1OPLlvK+5Z*G26EV)uE7ugJz;OquYvJA*MBL|!TTIev|kf}@fN!GI=jKr zSyiYyslxXE&}!QM+iKx|zY6ysv&?UqIHA23ku98cP$21g#z&W+PoFP@2L;72+nNg3 ze$N(DXh~Zi%184%6*^5kyNwwF#=h`rqy*~JyIFivKdpBbpGbvc_tVfZ4g{z{z`lR@ z6npQ>Ol|-qz4&^CL;1LrpA4Q0tfT4V?2V$;K1r6xup$(v9Rg-3<`wRbBZx!V8A{C{ zkZFkpR}};T)q)HFGtL~jgQzdR98>qYFC8z$iL&m0Kh&7rLvnF4gXgAt#P!}*0w8iF zG}>$>BkqFHw`0B|?>{;5Y9$P=Ltc99HM0qsX)McV9=#hc@b8Jcb8c=i(^{FTPGDd0 z7*~kX)4R+U;BL+1-d?5L&7-(XWzEsh7q@3Jls?QRX2bvkLw00~Qx?3iQUwtku`E0o z7!tcb(l+((Bf>ZLYpg!%p>k5gW>m!$N>tE&v$KVF>kYT4 zK9SmoD?*tA3`N?IpURU`xRn+;g>s<(E-PiJDgH@huyE^u$vm$mXZBTdW)k+$q-Cm0 zh!ahpA^BV^iK_JoSX5*+uVq9&I@8KHdVIm&eB!~%`&Y~#i9ywe%0UEFm-y8FYXD^&bvb%h2v`DZTDN%h3E~~RP7m|7>@0(g@f1mzzp1ZiZ0cDn3+@d=Ncq0fLiT)?u&hT{5%@~T+S%j(glFxjUd^PicZs9b}DL^t8s^JW`XU|)RoLBJ~FX(Wbq22Zt7{a-G=6j3T&X~k6-$6eNVezfRGo)=W1w6n+ z^t2NPXD^TM<);pt49oOgtY`z&Uf2U)urVuG{?|fNV6<}&wdWsB8KvyJu^d|cm@9=j z#VDCgH2#AVy<)PR$EszR>{wyZ;SA#<^`x#pHpNAf;|ve2XTaeV=$bL*Yd!+#Z_BNz z9k3soC^p4>=0Wh@!Y7TcGP%57j$Klm#B$boPLWVTiHhHE%UXo>HX~90Y6pXO=@e2< z=)>PKRHzgALX$(R@DZ8)mvj;=D(EbXe9d~8eSaX;AUyRrC+1NP=l;@_0p=qNSb@?d zuCgFYJ|aJ(e~ zd$<%bBJrb-lCA<2mavvsEW0wwg&O5@VdXWaTf3~Y0&XY65T6959`o1gPw(V>rtp1n^X+4#6G_ zD!+BAGKI^DnraoV%bha?wL@SJF&wi|0@t2y`-Am)Bmt`l84FA&!}iQ*N8;uv~Gf)*&I> zp)1r0_ZvdfjYqGM{on7rm41n~D_V;bYLa>uRl?~dSK*Eyk?BXx!zR?8nb56T2qSRXnr zil|UncmYNg%TLOiWmrs{Di=49gkC#I*$-Gz`tIpX>FN!~aYHcIyN|hc%S5hl(pi&B zuF}nghf)c>$kW*OSC49fA_HysZ?K-~bPJfV!g!OJfqbTQ=+nX`=U=LJs6Az}mplUh zIpmUzyL=#CyBN~x78^s!RGP_u1kT3u(G@5H4E@xoW{CZ8)b}|PKpWp0dvk02tfWF~ zi}b>PB-03NRj_V+EuQ%AiOnC$|DLeRO0r{ojnj6XJv6nXujd$xI341cH^=3YbAL82 z`KWAamiifnUcb{|U>JG_U#M>wi)F39E0a8o#Gzd%%g6x<^}l}n@_75G8lB}@L?1}$ zlC@-5or|~*Rh6djR-&_=$SOLnS^OVSkISB_HO<|RxeR6kZp2#0s%}17`vCsI zhdk-1FsAX-M@4!jfDw|n`@tKvmKSt$)5&GOBmf?Q7Hwk)YtmIQB<^QU0UVbmx{FC3 zQ!nb>oZS6+ykv-3oB=MQht7-&;*PO+5%P^~X1P-LeMH*@&b(AyZDGqjBwun0_*{X0(*o#5jn3BJMwe>VxhgsHtP zYMC zSR;ej(*hB^6P#f%6V~}@?MZwT_i7ihlNCar8Vhftb zEr?I8BJ|f>B`ay*9ED(lSZ@*qH|@!U{& z@n`HgQ>EQpoU*xQn)Q(NoT_`ZgEweMBhklj45E=}pZi~R$h5b)|LY|5o&mnbvZtq{ z@AF|f0AS^>LpzdgM{7Ec^N4yZHM1{(I+6x{bG2rr7W$;C4LCD;0E$GNl0|`YKE->CT--?j~i^ z1k9%Z2W2^^rKJ_EsnZ@nC*;EWIs=n+*`+R z>P1}|o4;%Zknd~nIy^^@%BceYpY8c19o*Y z;70@-!r*-${|DrbYwXnFpH~W0PJ^naBr?g6P~0;gqCtG%&BEO8i+?13x!WF~FXma_ z{t&R8YL)AX8Qv5ywaV80V{->X5XuAatOOCq>jTxQkx(3HOia%PW-u~ofC1+MX_adl z_`il$T_n54nnDGAK)Oa+2X9{a0X4`o6^!X{qVXWT=A&Gi9zEg-)RO~6sw zMVj9&6YZ(tE-lEHfE)T{uDxyIWhJpE%es4=0ReUejiGn7y$A<=+ie+hs4!{ghMr-QS@=HoFg=C99k0Ed(nn2I%-Q6x3zV76 zWSbpz;mshaEc#_tFR>^nj^TQw_RoNLV{Sxk8J{r1;1tj?2&ALdL&C1sUXLMKUZTm1f=%Z6Uc zQ<1CwlciU6j>+aQl+ixwhWj8Wbm`O{@42`Ulap~GXo-PiP2jJJw2Hm#%eqKr)bgVq zLjt>uXFcNiIWr82Bd^Wz19MdKk(GVPIlq$oeXjj|XF4&xXalbq-V+-Zr~fXuIaOef zJ8iE0&gVTgG5M-!^zn{k%!|TJeN3om>qDIG=<4#KI-hxscSeR|`bem5xMa+xJ;u*Q z=*3v2yg|SuUKHSP23UH6<~7#wi5;Hj2C|K<4iKDL;QkZaLna^_fBYQ-?0xfx*-tqI z!FY5Lj5*efBFyswqn77=()*EupId1WFKfsvB`Z@p-RIwk=~?PEt77`Jb8GIX@&*^L zPW0L3)*1S6f3(ho`$ykb4Ty?4O14St>xByAUaU8V)MMSl<-ixB&7sAs7l~~t$-~-8 zZI2hnFQ>Dk&YYekS$p|=X`@{MeS|sgs3Sy7naa=!w}mJlJE4zD!DtC{D# zZ2p`Ze))nXJ5rW^2u z;b2U>cu?tLKj<~(Mnr^q@_f+f^nKUysjr7-5{ftVoPE+ij(tZ_52kPwX9v8cL9^AI zuiH&b55u9B3pB1gq#5B5qz0MDUBJ+JM&!Qw7`pky2f~0zT4>_Nbe6pI{9P>-d9`$p zSzh=I>BU-GKmjJu9%mk)y_y6;-XH&OFLAg2|0VAKk|j=+XDK88Ow&X_q;z`x`Rda< zNi8Jb;FxH-tKB2qqRjPDT!0_VTi}EHRqX{2v#!Mmgnz}|YS%Lrc%>j+7=NPQnNH3S zPARfn%zPGuH*Z#|gMxt7U0LFl(uUh(tS+0fPP(0BA@d~|h91<#GJ z&eS9X{tWrhQ=;&mA8* zacFKRcSWHsTcCnu+Ip=iHn(aJo?*2M$<4dk?q;XT+F=wLCtX z*mMEeS4dm9bh@kHwUbTNlGWge23OaA;NkiA6$h`jhqjdw=$fKsz~nX-0>hhLq-hGZ zV3Tp3TV8<%wphWUJj;HNWm5*TNlKZ|;v$|qZocA=O|G^_J%2|tFG`NXp1chn9+5PhI33il6}p0VUqe?9>*Kl09I1}0J?3tC9ul(el%gKk*(^+^ zWw?RA0NxZF{Lp@23p5rtSvwKWeA5NQwf!<&kA-I`CfnGUh4uzac3AbK@x4*7!f861`6q0HWT48+;AW3&Rm+(bbvt&LcfoEdc*j@bb$dfsQ+A*$Davsz(_aq#F|3-B7oNB= zoL?cw<)XD(?B+9UKi9cg{%||P_<3!{^wP<$Q!(zGi8D#kPuDo^%e(^UMU#u81idV&rbVeKh3WW4q=S{J zW%cRVXI=n`-9z+I@Bz4O0cl8W-)r+uVg39ZLK0`fdeljfMhcN6l-0Yudaw#B5pq^DUwOz+g^aN zZTKw8f>D>nHXqAlk6OzerJaXdTObYw)(#ICvmE@msk;wku)R6QF%wb%c&x#InqO16pLGbi1NCXq*8e4*+oy+4N;#^QtM zCr*(G`9UevnS3EQoArv>USp!V3NJB&z9#HT2R(vFcFoSsyA|&q#9!k45BA?5MfRuogP&7b*8G2`=3jqcx5kl`E5J^H9snUxmBoUCF zAYg!id%eGdy-$CieYQXU&EYy)tgL4}&wbz5b$zwKjQGi9Vv&h*_6hr~O@Ce)slm}p zr7W(G-EWAc+$s2`6G`ub>u4#=9y41DTPd%twfjNGKIp%K$gBUk?c(^^&B@up_4D8> zpI6uCyIvMP9fk#j2fzd$>-6LApdYJn{&B$d>E8yS*KMM;mimv4gVBuB=v&q(%R4B` z(kHdpss~6PMywIxX&w-_bAL7$T2q>quxT6|!ak(FBEcf}d8!H6lOn4qyzMoyj= zZ`j;ivF?9p{!mKPql+3kj50$s|G=K`^-gS3IV)JZ4n9l@NlwWOsHXYBq&pNB}m6CUwbaT|)f_PlGIrQjW2J0i_W>!nyImqlZ$T9STF%_B@p1 ze0O4c(Z_95O~q3`myXy9zVGf$Eq#gbo%U~=6Nx38C%7?Q-gmKIMf^c?r~DZ1>h

      }DyiM?fDAKHfu`gLu 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

      -ISGLjzXoj^$!kMvm=DY@!U^MgzdVFts&$&^Y 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%0DQWhw-84GtA9H4enQLE@9R`w($b}vH-Nxz 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%0DE1GdsGRj{`$egc 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

      eb?r5lHnXK@swulL9@CcOp>;oJB| zgSOLlxgD>E0(3&*@{kL5@X5uy;qr=GzWjMYJwVP!M!F)9w>j>J;#J?vb%%r6o)6h! zR~1>l5e6fOPg$CG>*}-j(etUY^EN-uNF2(!ZN^=EW`dMBg}-!O=cYV944e^#8LD2T z8ReCINS^uDxlqJ;`*XZ!B&x-^8%f31JX2*j$ALVq{-@~j-l84WBC4X$9t*@@n}yrm zEet>X%TPK8gZ^i%uMz%V2Q%US2{4oX6U_Yo37AO^LxX6Mv8atUCEZkip&?#rwVkHg z*L30sgkL|$3Io?>5IYsdc(2pM`Bccx-+X$c7{agD-v=zvIY3&iG@U4Rde`Dv@gDEV zXfR1p(7*EBZ*1dDH*$ZTUweU?ZcLD6Owf_IFoz>da|zA<*76197mBt)6*BQ0*7#)# zW%&9xxATo8W4bckNA^)Es-$i11c(*1$K49|d{kxsafC6z{IOW_&9n*wOKLk8>!FS zNjrWQ>7Urh5Q>35{~vhVnAl&S%28lW0(ksu%ku&d(pu+}8wTL<`ObhchUc7*W41Hc z_R=Z#b?7rkT}_HxM5Abn9Jyx$g$N1uquZ5;!3Kx6)K>+zHMjq=t z-hF4h>udHGQXlTeEh-Du#dJ0K{DPLRQDu7#bd$)s^St=s?pf{2z)v0;1 zrgU!UDY!+Go~$TX7FPf~7GQrrCPI!82s($|qA3y_31`IH;$m}zN1TYcWSfyI~ z!H;2^>IMmptZR<8jY$?C>@O+wpZN7olg*>wO{)Gg!m1wv5A+%LU0gqfOuSZhkPva3 zb>~vuM=Wbn{4ffa)znp|L_K2jI!Hx1e=y(6=F}KV_)_Dq2Sh z1)~unMOX@c*yjO_^dvZ#R7QVGc3hu(IyXEaQJ5!@&RSkY%ft@>utNFv+#PT1 z;t*RGfE9bQD!NjYFo$ek2lAEg+Q)j^^p1K6U&_0^Ka^?Z1T>sLqxVDSHWjdZkPY8N z&;vTRTTRN3uN0_m9J*f$0iD~!Y^A(m(;Jj)jwEz@+8LHbr|Arr=TdWeCG18YH=?gs*=JVPHp=st@np;NA3Wy~_OPxd#}V+H zn9YoRoqlg93>x4$={n(=zJ~4>i}Kh=qhn;f z@=sLnCxiTxLH@}g|5%6l$sqrqv<~wV)%&@p^6!l?e(tIKe_&7LC#v@o)%%I+{Y3Tt zw?Xw(xxijZmsiiVzWoGpaTPqQ9jztF_$U?Ju5cNHTv*Z>VTT@2&i9rqY#(39#Y8WK zy6Lf&{rCS7@TGhF_{rC1F3DPyh@7HK;-@UP76V_qO6z*3a@#!36WvB3mVtNgxx{d* zWBPsE^;3#89z7iJ#m%M#u^X0UdV})@)Lwl?@A92#eC?LnRU__1+I)DFxbLyV5eByP z;{2PA86n&w2+|xVbbjQ+<{&GM>Ps0Zy}f!`=}qh(M4#>20}_9o@TeZA$dy ztNsQ+8`Q8fY^>l##FG~9pvPyYe}B_oZ2}4`J4* zYnwM<0%A8lTX($!=&;;KwO}ibG^}a=vZ0DMN*bY+^ehRUz!rDT74`^3Mq1(X$bYf- z7uBgG{p|_9D^r0@@h6?U__(YN56h;Tnuu_2H!{~Q(e2)bjchPPuMdX{ZusvH12 z``62qzQriv!ttX8J0F$YGmG1o7x?zoR*zh>`~_eDk37TB>+pQ~tlU3OdY-uUtq{YcU(9g zYl-R}JJ)7b{jkUk%Ll8+aQ=?X?3HNndmQ&4x8snP8d+AoV|J|UFyZ=2bJ3Sf|q7xna0omUljTKgVy&{SS4)U2;XXFDlLIP&LZ87>;+Z+sg&%x0%)J zX@>ArQf+u&ZH!5&IL>c6q8+(km%~C>KLp-?LVnYtQAE{wvIyU(a^bz^fVOal-;MVs zFSrfNm%rezlO=ouo$x#7?1uQKOYu4ezc)Rr6;24-pYFDLn8BVNm^+e7I)%hvJlBX%CB)l8i&Ih9d5JUMdnB zpr$Z8q;6#%u#0(#nbzfRCrvpd7xT5jI*3=g1pYeI%_1{L`PWMEcGKYXO>zdRJVIFE zVu2iuLrS==$oDZ28gav7pHyD`^w$vIglFPkTy&Z;*7&l&e$sUUST!Qr^Nu8S1W79} zQ+66{z!Q)c&+k_0h^qEiZJxcq-$*Lgqb8-{NSw{KOQY_7q6vkl{T|jdEwSXXXzE7Z zRd=OW#jhhRBjL`iQwyzGdIiTcJIZqs9jGUtH=8_VdT4CCzPX**Pc^cBi9BmZF}vp` zZP8T>J3WlPfJ*=ZR?-w$dRHV}!oUc}2279eT?K!QOy@o4kvS{OF+_||6_RZyD_1nx zg?Lt+DCau>qxrgHz3~OVG(BL9=`coJ+@TI^L;8mGKx>BO*E=m8Y=vDPRP5NWt?X)T zX`kCu1v|6jNB8fj4_Pz0U&DGW(J^Bfgnu;v%kJsV@_ulxFz2FLTr=vllHr0KW5dfr z^UnA_21cin3=C+!v>m*1FDv$UKV2;|)Xd2pYork|aqm6+AXv84F`2<2~wn)Oce8GSL8nv9gnd2MEq^QPkND zG#<`Ew5)7`Rv15=-jzn@bK`F-Oe3OA_kARypbd_0+fjE}?(P{XleC#Hm+Z`?#Xhup z;tYimC^FjR_2v#4yfj06d-nFOhxfR0f%k<9D2CTA+AgLEWx+VhovZkJh`epe;n4yc z$HdR(OI5}Nn-lcj>CXs?vj-U$md%>}ov${4+Ra&CWSOTCkspU`7jnJZ=&Glu1#pH9 zl!R=O370F_ITYC9$ULRqbJ(dZetn5=$mFQnKV6_ODk7!#vm_Y@db#rD$U(;GODIF! z=F}EDhUbG8FeI`8R;S9rD{Kj4IJHx-fSkf zBHpWzV;i0ZS2U^3RM9zbq1?mUMFs?yF%E$(w~2R$30t6uspC3CDJTB#Z$KUbZa2xR zcjv;9#RC0k#!dQiICrxpNGID0-S-KH-BvzFX2sp9#2;g0XX%vpS8lvNw3)dc`i>m6 zruCr5RtpwP)8AiamoVQUcAljV%)P0KnH!e&u1_09#V#U81b)qqjE(bl*bwdgVSn0n zalR~Kq!8KcQnufPvi6w8<=8flQtw8hsr`PA0kSALBn5-m*Vgm``HJJzR01P+tICqG2#5H2P&ZnR6U;d;90g?o!tDe!q&7_wB{&Ll(Vp}ux)eWb~Czenct0x7}18(&FAANq!trl>@~nlXI;-dJ3b6TNo*j&0wsz zlUb2R3A`{8n6UVVF6K*Cs~fykVTo zx6DDl=_p}Ei`I`Y(2kR7Vg}ueJkZNJAE29G^xdBUb zt}Zx7oca}_BL5P&-!Lbj7o3q+a`hy0GVUfR=?faN0!ALaF$(SqTwWQM(ngfyq6#)Y ze>!+w7lz0E);M%ki10I+cDZ6Wp48@*x#~Mw;hB^^T#cHBX{*oMk_STwAhkDchy9V{ z?Ip>rR+@}y(}u(X_!f70Zu(|PRRpXz#o!u7g3QVnxBo6ud*tnz%dTbg3D*1*9fo&K z%5GF1#h9#xC4~xL zLh;ieK8q$hU@9dXhAZ+nJ%$jxJA%Kinrac?Ln+@yYDi1n8^1%tFh$6U<@Gp|!~V+3 zPNAvbH?!iIBXsT!ustBL(F*6JeGF68f}ZF-cnw9EOik42{KaiLHT7KtcnJkLO>FV4 z^=Ko&TR1GjH;=0R%Gkf(+c8H!g(UP;?Na%w&*GnTHg+(--}j_+X7r05$S~8gXFZt0 zM;D~+D8O{wPYY5axfjP*3Q}{dWYZaJO=H6ZhUe4k)#Wz$iU#dogt_efi@_fc4z*8} z5>=8!#s0)t>g-l1dVH{lESy^+@Q9?O9hC$mi zP$#i?P^x%sEsI*>?(*)vbB)WygnGuwGybW#$N1#?Q>)bN$T?(p`8mq19y~o!Ut7vm z$Jmx(-|88Xav1@$gIPLen#dMA>?jh8=zGl0&%FZq?<`3uW`xTf!6Rp&;>-)gs#~!d zCwFO5VPY6DC7Ch@gPp3FQBCnmta-+0d7W|i3Ci&(MdLG z`N+m`VxKd$jU)qYu%)t>H*u&ZAfw0pJ<)BGo0}9l$<~l#8Km5y6vkAhM-Q|-;$w!0 z$M8EBTXG%SR+LVMaHiYr@Q!Cq4}Y6@AQM}tP2X^c*Va40y~+vcV(nrhqo~_2tPW*W ze6HX3&`I;YgHeJhHKmPpU=}{sq{|q!K7orNG14e{5CI?ha9KiFv3xY#DXc{Pcca~2u3B$ zx_@ogG`ED=$nGa1@k!myG%b*>8T*9-S8!P{Nl&wzRm*Be9c;_d%q;iN&s#Nmwd!lv zefVCLjs2>sV%IaGfu^U{#o&cC$_(i(-KBe4+o+n^d#uA_qIxJUOHJ=fjpQ|@Z<7)i zpLRJ_(D$*LO7>B#4&$&P%yVpO1iPYF*)ml$=j8Ubi_hZ4?pkOTjLY0+O-TDW+fba- ztg?lm*K5(EPvt7Xn6PxRRFgh8faf+yP~aI7-1pEp=w@9-;KeIVRGIK~u6#AALa^}wyWHLA z;i*+6#rDmqP}CCz9q{ogDQ?%R^n-v-w-Q9K;%UJd&$Khf z>|5AX&>s%3=2@#K`*Pb?K?6OWvBEd^0+D!@Mh=mj4ylt80??ONcFu>&8}u_nGVXTFGiej4LZ(QWxMqz)=tXc=~j(U;uI|Y{cetVyH1!H z2bfSzN-Y-b;cl&B1xP?ItooO(=i}O1hTA|P89LM1*LpD|uN<%9A9kXvSfxQGr(@BH z;B_XerX->5LV*G-p*ZJKPQ_X6vsYC^V?dQ?wZCvL(%JCvqHG(|GV_SN-qlHMHX;5X z(_>I0msLISH9pALT9xKwhP}cHs`E&0cMN}mi(_8ke9N-YYz#%Yi$C6vFLzDvAVV53 z=68{?y(ldZx;QZ9xODaraljoeC^sahJ)di)ZzY_9idnr;VE39JRY6eV!dgNK31zjt5Gz2OfOy6^=Iqk|->EB*cagdsXLo9g)#4Wq z#y6qOee>O0qKmTFtM3oCacy7WF%o8v4p5DIw^CID^;hp z(lMzhr@wOfN>}jTSvbe>rb`P0UFe#!VaBZM;M1@cY?0N@>Q@>XMwu9~JH`&}j4kf@ zq|F=*U%BDo=osH*5as91F^lxw?Pu;s>%#1f1si@1iBSh}ySJZLZ94OdP* zqt^9`;q|9dX)i!>Dh)AweP!DMQJ1Uwpm1@W8jBJuSs2+VR9 zw-qjv``Hr&Do^Y`;_;C+-%eKPkdMN8Iph}Lp{-;XHZ{P*YSD21R9wxg8<7shk|@8~ z`+1rkrGrK8j}FuNO2A>#$=y%M)O z%6eFbzs-6y!_ED7;kz>33=?7%9^kFokV%>I9t)1^ao%_79-2d3h(I4|ab%q1?x5~u z%ikO&tV&AZPgpc{6~H%78zl+%+U2H{Ywl=c#6MfnY90vK-l%_5F|%CYoTZ?c#Lc%7 zZreg6%j%-^i}7~6n=hfg)01hFHLwoyPX2`<;U0on9kj^lADAM=2_@#=n?hPsx-s=+ zF@L_|bfq%el)|~pHPB5mnQRAh?br8GeZ<4~_G7(q?)w`#PYMbSua}>Xb3qNUtDMgF zHP1M`N49xcZL-cg()ab1PS&K-U1f;c@?Y5w-}<@5eK>QvM@ zd~?mlOxNEz18L%L8)DBS=d?hU7YfyE81S7rO<*^lzMZcos3%>WOjkv{?61?6>5gFQ zMolVzfsZj5Zey>%P9@z`FG}&AFzaWOVT}R$( zKaV?<>MXC>go(ZW>;&>;u06h(8z1j#p8V>s;sang?V2k>lB)r`rh3NhjJ0=69w#XE zsw+pB=C@Q8%C%$Ir0Wn?;Fr{64V&3=;zJ4=_+;I9uz*C{6j}^ZIOs+xz+uQSGbl5$}$hUVL<Iw$ZXbuj2cPTWDegAwB~_2-kn86i5L=?zSLyPJ zY5QG|#h>5p`n!)=-fDJIR7S7hZl*KR_+035G7sftn~B|``{eA|cJpSF4!*L04NH74 zBPguvRRGW710CZcn5Mf0_fUo$$7Zyc@BpyNO=ncv3tyq->%h|A`+Xy(`}pP~reb_F zSNHZMXf5E$DNai*S(2{{-T5ve?!r(qOi$D?#3eh&q_f^0M`7K4?X_5}^V15-G!1G@ zWvWeU$HDaii|F%iDwhI-DX5-a(fb!EmseZtiWBd4mV&n0gI1P6aqQ_*2^>89R|YWWFO;%UN?U6es3Ues-|= zl9RPYOOIX3;k(V<2_eM2J*ExOydX;QD<7LO@-)S>dVMs`sYb=!Go9pInAKl+&#~Mt zDqhZbzs(+&_^0l4_U9XiX_ zl_L2-wtY{oyGgVZC_=Z3paGk~*?z+q+VGc;2FtqcHG_u7x?#s;W9Sl>6-`weOs}D( zpDDy}kn8u<;uyUqereQkOGV{#uoclLCAM~|)20Hnoo$p;ap*dJO$gqi7JXB_# zYVM+Fq3gr;4{eu@6;K6;d~OXAu`LJvN# zDlx@?IVuXy$3ey{_^94EFMI&J0L!}5u-o*@y-|}}XeNAru4o$>KK|AjPig*2l%jKa z)Buib8?L6K9TN*8(io&2??2`ie@bLwR9uL!zl(qX$NG>Wf*oh@JtD)F<2^bXUSN~P zRWoI4AKFP1jj2)9@4{zD+~OJd&ED+__E+m!C79aSlIx3ACWr_MI>)1j zL*SLcD7EGb^lGd`#hH-PX_bP9tD<&a?Yd{Oo=b?Tpga@OjO{ahOr#H|yG3kBzF6o% zVMeNOW3Qk4Mt2h*(uxIng$U#{y|%GHYY{bQTGUla_a8@V6Xi)QTSDE8rURm;el+U5 z%OEd?fE1LGe5qsmJJ?21M0LU$E~33R!CfAD8O9y3g3fXxm}IF?YP2eh6CdN)dK2D8 zlJq0$ac9X~Qo9Z*gtPbu$02j-Yt1u~@(E)Cg`snud#5<=)s;Yht@uFdCL@h$)N zZ68%lIVHR*eKVCpa z7;)in%X-z!U9&c=LBk{#&o8zxrZ6e(Xujq*cX(8Zwylt}M9$(wmB=#smG1UoMoW*{+ zTA9>yFesF`=T&5F;5RRmQMW%X4IcEeuHTw@)l|*kAt$`x_}snEDKvRRa(8e^R?|_8 zBtt&S3E&89pNl>NjF~z}OObKzJVDdG0DiQcg(pjcQ>dVj1itv(c^VcYa6eD3t~_<9 zLlZxts%Ah8yQa)jy{i1LY?kO zqa+GncLg>Qp1!7u7h#2UC$Dqp*fy@IzQHRW){uBLbC9ZCqwLmKnLz1UO{zmIm3sA+ z#NLjx*GTVh>@cecT)T3>V|ZtUuVenzqZk!a>Bnkg1I5;I1)kR1Dc0hltb6?>@`+{1 z79HKBsmE}RC27ovS12eHZUOX=$aUPPvLlxiPy2=74_R@2M|g4E>~@kQ6g<#2Df@&b z`ws8I7QOvNH*OM!@-BsFy)AZ-QJZZi3$qSNEWP>{w_RSeHeB0AV1XF|n^V+D@sOl;@;)V#;u^IiBZq(+WO-5kOiJFFx(-|jwE zQEtos00D@5YrXGHIkXtCH~{8TQw{C7t?8piEZou}H^3h1;UcCHEytEc!GoZ}%b*%C zX(ML>%5ZcM()2qPd-dXIOtNm@xUhgo^YGsX;qCzVp7|yNw!uB?XMf%)KQVvAfN>1U;k9?qD-y$c zBONTLH|q&wEjf~c(-SR~lllVZ7sArmxGJxZ9hvtIaknEz3a+|~mnwHxpO4ZsU={m& zD4jaFP}TDg42u6!+qw?#zRc}d{v}_{lZab09x!^)yXVIRD4ww^6EvCRhV&=ZDo;vf z#)h;m59=zcjEHr2IF`Bm{SPHv#WWhd=;oQ;NVF&Rn*yKNb?ye!@G@GHANvxc$j80N zGcysrIq3)=!2$ebedYS#;T(n~s4Pt3Upeoe=y3F3jamjOWY#pe*A0*2F3lF(W_ zdXn`6D9#BquZ;uoJpBsrs_tG)?+ho+^bQO;H&qSG5k2@!Zpe83Mv2}os>`ZM;v7TT zq_)8BOm%O(e8hd8eC^ef)(SU*+#JkVyrxXe1I5OfHrXM^Eh1Ip)~ zDaA%vdVDAD^*dR;EAd#aD8EaA_qN&}BBL<#> zV<)+he|qWf_sqQLsOHy;zWn&=7Pi(o#hl?%GJ1dDX-*k^6sVm_yZk)C``d)q_wY$wK8|Aa9~FhnF)G z$iw$C(>=^-X7I6QjX3xH>a#cE+GtSsnm%AO_Xdyd~I%+YdubG1ALh5c*fc|S;;hHBIS6i zeRGBMY%Nj}rRc$vys3J%sg9MV9sDgDFaFGILMOVvdPJ|>%K28!Xg#%yr=fS=-?rAR z3Keit`!%pz3Rx`oSud|^10GzvRK`K!Yjae~*KV8|$@nF_9fHz==fI(ah~QvUA<9A+ zUUH6few3^|EgXqjV@fmh*Jju+vgvT9w3&|inG^%XN|%UV|DG5+m5|4H#VxJm`4aR7 zPFIy&8(&>)gbU(2x5jBw$)T|~p}|LoLb!%jZt41!WA1|b*Qr)=f{-E(-U~jN#ppHv-;G&8~{JZ*s zz$hIWhNgVP!UN&nCXc$lf(I@zv*RehZ}{mg;h`V<_&@fkk&c2Eec1h^Q0V_aVU+Y1 zsiQb*sd%fZSQn*rDn*Ef$9Fe-b45 zBcFrv^rzlV5ia_@Q3gK;S&`K$Q75^Xc2al9Nwa((IXlgT@119|Y4~KCx*|>ths-XW zjI^@n=&5<#gIjr_V0lWpt#9kc3ybLR#O|})P*6_tv(*{&dE(W@`?W7JC;~?WO59v3g9tJcmi!idZogI&-_p&lp3P)wKl|V^O<+&lpytI0&VCaVAF#V z6NGc|nOG#*m}J0!@XsI*UQi=%EeD?5HNi75TME8rQzb!b>Op%_=-#+uv-lS+@D&^y}AJC<6a;@S|M zSdq$FD(Mt zL7Lhz5SfM!;4{@=Ul~@+R52WValv+vMph@Gpg)1(Dc*sXHQfQoyBG|~5}F2r@lf0o z-?@KE#nu=`WA&YOHQ!aNGRq5=h@Jl7=R7ktu-lW*{E~a#XxDkj07H%$B54(w={ znYPl;v<`12+sG7NF_~?WI0gTVtiVPhF(&91EcYl7E2xR4XO=%$RE(IcvGz=GZG0Yl zv~$(6&IvUg7*IlZpAc%<*=*3Or)hGC)~`?m!`j|ocPV`*JO)=<);`cfp?C;5zf%Mn z^vq9}_Rcp)Y#ib;lfNouZ9&vNvJ?bAgDMUl(J8}MmGFm?4~q+sUp-NT<88+-x$XMa z>`aXJI7SPSaUZ*S=VrWV&S8JMedB0BcE0jYdBM}a8_xcjOA+Bs6L3) zw39}0-WCIEBKHOgq=FUOP{<^j)l^@QD=<3n(KfcR<)umbfFcIP4!BcS%QY^@4K|I+ zJ6fjgJPc)6mKPJYk10*)@Ec{Di}k%S%hFu~*NxZDgc93dH#F_)QMxrKSKppRNgJO1 z8Pzt@t&;OC2M21i{X9p$l*=(f1%ARZAM&P43Kf7h}^27Jv|3dsR zA~@=?bLzxHfPdn_h20y1hcM|UKli7#c~Rz-i0PLL$c#X+okbC&1g?SS0F9{`!owp> zN%LkyD`Cl2-ad?}uxq|Kjx#U+h98lpCM|qFwV3?NZFme?$g)352|zf4*rt3GYzT32kF#Fk+l&h7@s^3JY{l!`+slIUdApGW_#h_I~Cm6 z8!xKG^L8P_&-Dzw!vckAMk5$6Y&GjE|J-0_ATHy zwY3dnPT^RxvRkes#sB@lzW9UiX|osh{&gRta^?O(Yk}{J-4tzufY_-15JY=f9HY|GyId!dd^ZZ&!mPw^zi3A;K=ih+VPW z+x^0Kdx8hw=A3@N^Z9)rg?>g>WF=wW$$fwAzbpR#{SnEZWd3VZ{$t-%N;6Cvw$|8p zhLW*2_CGZ|5A{vbpYnkze8Bo2>c?B5@T3TrGW`KA;~DD0aeRAnK^jB-A76nbBn6gt zV?{Aaf>Z54d*XV_Me8x2J=p6Mgv<7(W}4w;&%!llPh1@_J3?0A3I-MCPpKWpA}U!@Tnb1aXBMk0qbF zJo)QYg|F+{i~d{cHveWx?7Y}}g*M^lKqrxD7=snq2ceik2$m(w_qFuf?S6ew@xlkq9>n-h^>#lU! z$;DDCSSa2LqTC@1@GCF)u0RXe#7$u&g#&m|hGys-0;Ey-imfP7((fR$kD?&Zgt`Gf zr_Fp$0}$5l6>%Nt5;A38yw52yzPQTvd`s6{sssY+tYH%Y~C>+v7B-z zX=$^_U6&yvxM$)P^{LV=v&8Yk@i&q1ekz>4@{z}NvEGH5*TO9OE39QBNsZ-BuA$nl zd0zcw&gw)$R@~0taN`g}2@myx{GGdF=zt1=?A{YB;XU^H>(1LKR=o&IXbj!vG1Y`a zlWJzIoxt|1f?gCN>?E9P!ss8zW!qAXZ#TX_6^alSNdRo zv|dnnVWfxR6fj`fuN`az>q*jQO?YYne~x}{3-j1l;glU*zy;s0qr(4pOKihWiCCwmlwz*1uBtPVUw4LfyhPDPPE2XG zHPn_S?~-KrW8brPM%T*&C(3QH&VQ9U3Fq_3=S_2$^81|~-kE0sTX~LW#2>`vejF>N zP34x!|C9G%;tM|N+X|@5%h_mrA{e;Q*!!s+!5N#(yHt}!GQdr4IPze9`_J=}MXR9CktOjCkn$>gMpcrLg zEt)QxNR_=B8t`=KEoYo--RXrpk#aQIzIBy5b(m#9cdDy$PKurmRKHw%Ir5%hlZTWe za&w7gJ)P>^+aw(?F%>RUAoJ%W&yk+dXw`>zNQ`z;WCv4bTB8To#O~8wR38O5d$~py z5^eMM7yIj%v(NT1DENmZmRKDUkYrYR#H@}33+ zq;&I)6a?n+N?YBNUE@7VX3^ib4FT2!Exe%f4th+>UUo}QTB)97sxu`9jj(283WMM4 zC93lV&r9Z0k500J==uY5exo&P2YOw68mYN@S)&6sdy6_X$>&1iW17+w$Bi4Mh`*IK=(( zlB+eg*~b+u$Mcb^lte7@7CnnB9igzIrUaV_e#!70zjdL7sTlH|(8~8+sXX=dg?lx3 zBbZH-1u@C-DxgCZk=jF3pEC97911lkxYWdKZrOEgSC$+()g9#ekrz1*HnJ}SG`47@ z^j*qFDyMh3SNUf?c8>+}w5W93*vP`!69BX>uP&3weoM!`>p*2icE;vijd3)`(XLV8 zy_|%JhWJGlCN1_@N)KO~7cJmu3^vzMtzf+o{HYFxZ(@o$65{Ymf&tLX@LRr^>U|b0 z=D~(A50QtzGWNHCarYS~p?qwb5-h1q5m>|mYd!fwgDsL*M1W>l1>|&5f8Mhl{CQ?G zt*pJ%Z$G?{bo|D@w{^>_=R+>_J;dHCi3&n#3<6&0rp&Jub>D-F6zn}6>j%6w3h4L}AcUkY)Hgaiwqdk{ly-+;kII-vfk>Efz@;#d$rDh<) zo}T~SdcQAn=d#}R+mTxCoUTrP?P8(M=Mf`?!OvNe-HWE5i|NKY&HZ3*qk)7wQQ_)0 zKaZU^0D^i8r@G2G31EA1l6ZjyWWc3oV@?5W?c5FV5%vs)ioRR}CE7N<#q`W+%kz8N z+8HVgX$#_cEsp#qU858e(JI6bv)5L(@G3Rxk#mCpIY3$?$$ji9M23JvN7@8YZoeCXUgac zl|~kDnMjcfP}YJ$GVDy)E={`ihM`8h-OH3QeT8%Z2$dDjP)9gqaJBTqq`ZsNY1?uA zF9U6e>X{kOxsdjPMQO8v+U4A6i+e*K_X5+KY2sy%CVHHOuj|>*^-(hE^#wLEI2r3t zp2ZmXdPg%{&C_$n<$4hl+7ruY!3f76*}t{^yPaM}W>n;xX0@LOh*WgfZ^0jb?rS3exFwT$OB%I%HWL1l3@0ysVEiGyN5 z5yvKgo_xzd<}7G(`RxpX>VKlttFYJn-d|xAJN{wT-YpSvp*4P_m*DZ9wm;9zx8^N1 z4T7B)6Z8EF7uTpJDpfz>;ttlrB{LLsUbW6@hsh+$<-o3sj z8f9kJx3w_89hd5+5LvIU`D34t+WuKx>sFJ{=RVwzLF9K;rRNT3Uj_V!99E4>LZbUj z|M737o$b1wc_Z&>s9S6k>JCUj~>gt7esZhB1z(^aqcczWm3X`#=ga`WZSa zH8h)@A*uJt&rpdL=VM-$7pQa1(-C7~u@jXdhRCR0k7Uf$dphqxMYrvpOC(Qd>A86y zuD5@tDXT#(chB=~C_Xbg+y={1gNVg+QJl$;;q=XbwEoZi9UY5bnjHraiS<4P13E!6 z6{#tBoMGR&Y-!^6T-~v5+n4O|a(CGZC;VfSH1;M_IfRVdtKK9V&Iyi#wCde6AJxR3 zH;rSYr=gd2qucaUHOma&v0otfTTJAtbxQ5i&`FvxyhnKdn9tap#Km)GoaJ{-;|?9K zS}t_59s*TPv8QQbh`T&VGAg}61=aPw^I3{9O(L`T#+E_94#D@iymhZ`{~ENOI@%i;U|TSU-QP)hO8OOwtqAo$ zF)lEm@b`{hAe{p3$GRsUl@w3~7NCi3wkSwVTK{We(@c4t7~@>Ll4JTPd3Cl08g9ILt(anwWboA3>A>8Gj>T#r;>h(0S$o#9I6(&5b+xb~uf~Qrm)$ak4r>tkU zL*6BY4A;jYQ)_o4s45qVq6{Rsx={zzPn04ThiP7Y@1;@M#}$9K>D3iW8Z?ncUG5Du z5g#~``)<&%gXEHL{Gx=Qlh*C<{_T#^`(4&^H{Gsc9ZzgK^YKE2sB-%`5nuxm&p zFyR^SL6Ub48{eAKV~~cDGoz&XYk(fG4oww0y2+x6tBLRZpA6kWRep?R?l1Q)!eD5l zJw3vJj&=$9)2!Gqm#p{T)eTNsbMdn$De6-Bc6a$H0}ZaLE<<2z2OZhx3U7NdF7FK} zu=w7d*t4L`Ih9+@i*gHfuTIOX4p@l|D!n|=L{{tT|CkX#6tsJ_(Po`z{~Eb z^;04JCWn&~~DqSwP_V9GZhpHF<>}@sJ(0Q&U6$o)m%WR3U&P04Q z@X4((@L0~U;Wt~4B3?smbaAO-_AtTjRPFMTO#bCuu8E^>zHtd|-IHIHf4SBTUN7}w z*5Urbdh?Og%GrYE-YEHi`>gTqg|#I(8Nb`h-Kv{MB)(p1w(@{3fUI7O)m}R#6p{G- zJ;Yhq(EUGC`(5j~d%zTjApxPpSpP&gf%Dne>lcrsa_|xi4bo}o9-oq?v`uIG; zMX25m==yXjS3SMI{QjE; zh0-e@171}k<&p*`G1=iZ%IH{M*E4lZ-&+jL3@4sG3f#0Y>W>7nVyX2H`B6uEM{_Vf zkFL6FoyzmRRGV61qnI+-bdXnej}x#m`aS!&<&5Pcv#>r>P)<MD5#vDp-qNq zDy&HhI&Ty4@%!lekfXjnA2Ecn`YR2es~-ZdZd?q-p-PsmQXG7ah`U{1;JZa-krfAO zUx*WHzEs;jX1Q^!W7xyaZfgM_bw|57Q`v4VitG-_T2c2BNlaY+qF2fRg?6~e2<{xP z;;A&g>*alP&IK=3NIuE(@~F61Zn2@I!2Oq3VL*WByOHq2_Ja3dY2T#nhpIslxC_EK zK+@PN$7mAcx^^)85}i9BFEGXhY77aih5WZTFro!5#@%q*?NP#YV^hi6VD>{w{fb3x z*@}A`tjg&1S0AqD1E0EjjmS`=FfN|KXwXF7IXbo(vwS$jM}&KhoqN{9m{QoH*2u zXHa(@gK=GW*^lZh@05o;gk(s<_7b&Xbt}`Yfmp1McR{!<6&AY(QfVGT=dw*i?Q~dn z$ZSp^x!nViQb8>{I}8!8>I6l|*vBUfOa@vjcy~eyV}p@JDTHJ;ca@;{JMLl7wn?n^ z9`5kg;E3o0uJQWM>Q0{PzgsJ|5$^U()TVUfbcrOpond7YHXuYPKIVQ#X<gy(T`i{t#kYy1{G;UQS;up0 zcC5*^SjQ>};_zZn;!eWb4KhM-3#?$m3gb5dea0~$j`jHEhQz|FPXB#Vg4?Kc26mv@ zf5n>0GLV?fI)p~aEecEGh%~FoTX?D2_uaAadHuH*aaQ>_tpog|;YQ=ZmGLSMEtfYm z)ZU+gEA~;<=|guq^Dio0F42oAbE|1c&#V|w5_~(4o-?hTsnpVB)it?RNX{J@4nBD& zsPX_Qo2IO@=sX;3wY3mv>0RQ5ahVI18tF#e#{=$&RLapG`))>1OAp+Pz(^4vauIzw zGh#a}d&Q=uRFpL7Cs4~Bdbw-8%4{ZZ`flTX68ySXhQYA-uYwo;RibXl{n#ft4aWEY zIdGK~55UeK_8qOBM+H>U`SLZI^=PLuKkFP>@K99mcX|5cmDQ0WT|{Y2&l2SL>-9wi zrRU`fgC9;Uc;|)%tiln%x>Jf1?;#u9Q7lbJuI;hxlr=6MJI=lWmH#qa_AKG)!m`V* zvDr+2OmXeWVZ);P>4S|5dag#(n2=siUrjmJe6K&R2+p$Ja#gaQg=nPkihnkm{v>8t zp3^hM?Zj@zMk=CIg!82+boj235SCdT6`BgHp98AYOp;l(!0=s5Ng$7$$TN_IL|6l` zVlspLGZb45mBWS%pdd}4$cs1}f{`C3c~N-UEq*e+3DV`&j3U(%M!AHeNPH1ZhoM$^ z-VWh`IOo-ljEq1`(9>9xy)I?RJpGgX(T;@cm&#IEuC(Jcq^dX3eN88lt>dQaLbsPG z!w96+l0&^V5?1T@xseo=C=DH$oK>#pq?_Dv8qGt?OS{!L*NdA*6~bv5@`%s0Yo4`S zjnfgAOTqVi$g}>(Ac3{PaS&?SXc(@0;dj8?C61-%B4w#Pk&^vDigNjS`G`GWL^lMF6y=Jd|v#0zk4 z)m@vdQzTpL5g#K@j2i2<&bLpeMe;muMa4fuBAn_P zat>XN9?-ODLVG;^A{}DFO*l z+CW}_ek(lWFE|yEgfX4?7x-tYw{}F4_>fOe?n~s393)nLa0Yf7xmcNy7h1iWva=r_ zeX0dYVW3p0gzy{G7m`9cB&GA`qeezX0wPi6Bn~wedMjj({8Yee8dS4TOdc?+Kv$_I4XnZ^^s14p@hVhW z^AAT~IQ2#wl=p6QINY#pWEy34kz{6Hlzkaz(r>6BaFfh28H|iyr}-dmL4M$$LM`G; zJ|$_MYuAURh5;VDGwrMn!A0O82r!1-gC`N?R)5ZiZY;B#kp;Pu;(c>2TNWtgJq9-9j?a$M-ea@*bcV`f?nX}fwm~XNlzarj;h~o`j0~W(n|vHv0W)A} zwHVCgOD&bzx|W^&8k{U1sW+7>l1RS61&H19rXK;9STy+4@|9gIQ9DTj7zbu-60#pk*Mh)gyG;E zO5t;68^grRQ?kcX<32kcCy+V4^9GFApaLKGZX?-Cz;Y@Y2Waiw1CiaOkeBcvlmT485@c8s0T>t=i5ym5cyH-yYG>9ko^mEHlj^nu!-_vl(t zw#n-lJ*L#-$ie2c$jLChAgmU>C{XY$PKAR^sY>e!vbqHnVZt5+D;!w8((K!8IK;#0|IWj=gVCMtr}c&mi*6!Kdw37~Cc3%U-)e`f5ggoyk)64{zu@GT zlJf$87p)3+`=?=|6Uzse2;*7OxSOezHnF>813RF6=K)ksC)t1&$!56emo|G$$6(B0n&qsK-{&|ZwfbG%`cYLNcK6M6zx@><D*DCP-p` z6RA9EA0?Gu13kPjW{OCpNXMS})vlg&cH-K*^-ry*hs3xei8tU+uwx75fVfom3#g6I z*|SM*AJ08=pe_GFPphe-vaWPc^tt*!4>rg}Rrj}g!|fZkuS0sj@vQmLJYOdrVkUY{ zJlo?z)PeZ>yuq-&^8~qygS%)>GBFM%sR0w{pw5WHL9;%b=k6wA`F?McN#^)JfjKeL z-touDdiqK!7Dyl2s+@sHml?A7wN}TDx4Fa>`W$0N5ORAIyP&|sOIjZ@W`ah$ktt*vePg-$}JV|huD?coyZ=5qC zbI46NQg0`MHVd`0)jygN@-RT#w&gl6y3Q}+nM)1^ZXnQf^+l1&F<;3|UAT1@GD6iERu4Be17o zp)_S@09@O-1L2-PK3-5!JxR9}p!PBq{H7slH=jcmZ7pSC<&Q)7YGN8GuxxEk94`Z% zp$je$rc--dSpiY8HLcs72e8xz&p~*UATxY&jQ3~)_@-uU`P=0%85=ntsnqiHo&X)5 zN#4;b&YbvoktIvaX2&nszX&dS0&B!)ANX(f3M=2;%DMa2q7VMc zDqiGw7XAnE5@>I<+AoheqXvmS^@|;8b(PQLjX77gd>@y!yKHHOPgWTfH@&>G431- zgt^bb(?l4lHh-OFHnD!C;9~3jNj;dHa}bJEGHnD%!CgZ6<&If@tRzrKq8syZlF|C6 zLs8So)_+vt^O^e&X^xmo|2n1mR!|JM}zGuZ-8d_6J8 z1m=6~5#+-kJxUL>;*uGndkwH9>iyR~%Fj2@a9PU1x3s+q0moQaQO!w8sGkkbB1sSz zv4EIfTbN=oQ&BAiJtNfbn8#os*S0YL^znJy=~4zO0NnrNG3AM;ZCW$1&`PB^Dd zHFX4gyrZA!>m+eR#Z2vJ8S5}VQyQ1fvu*{TN0#dp#i$4>+JW`WPI8p~V9B^&XOu7b zQm&ZWB>7|C$?WH&<%wNa{r8*Ah2{PW>8&AcRLT{WVV)<`h$o4Z<{I`tvu=|~CQ2B0 zM`;q+vFhk1t54=si6Gae-|l!=4Ki=n-hIs{AM+NRWdL?*8yML&h7`bI-_AO|YH)y< z$U`P=GgTq=-=>P}-qSmA3!5pvO#bhPy0E%m%jA-) zZS!yuDKU8oCUmisY|Y%pT)tBY$uuvaqQf;*kk>t4IQEMk-p9^fqKKZEKo|^16 zw&OPLru0XJncv%|4b9OdI&Vg+(r(pwRF)}DmMP^{Pn22pbYji1fiRp(WCup0bun|8 ziVUm|Ne$xPS)ioPw^(#DsaSDrVCjADf*xGz45M||n*8?1K3T^8ut&RV*cQ%47LSth zVwPr%+wTR9z=dfo4@>>sUoPdM&2J14pAj5(K^Hw4-4i*9GJH&@_AV8v`ITH|UlG#N zt8%Y2qg6vcvnR?jvQ_!3gfF2mNh@TmrD7X)B_a|BL)}65aWV*}HpNLIHcX|5;X3|tScW|!kx>l?kGJe--ZTZ43#kLjJI7)7 z?rGAmqm+=GnIa)ZaA*vp6^c0xP=rYp#;F}+5+2oc7618ro;{M38G0iL-wL_ zx4XxS`Bbzhkg&}07CahH<5H;PBcR)tHu-inVeq{YHT~KiqOWOiW_e=DapxW$xi#_D z3Wzumc`dBx6_E>irWX|)0U2k-O&cKd6_&DpXLSJJsnblQ+8xocikONj^(pr_!hZir zl|?9Am8}jMFeCaKjvRY1o}#EHt4nx}6I-@SD6F&9lCpnwLrUR!r@yuA;>7=%?w$h= zS!$Aid_4uw-O0}2QF72{!LK%`=4VwQ0HS*y*?B5_*O*vk2Nd+-4nq&!phOTxE&iNoOQB0RdB zl>ptyF&JpJ{-zeDM^?&H40=Ck>s1_XHs=;cMjL@1AgfvdaQ#)EFy z4bxZ2UJEA0)Z;xaDZ0{CC46F43T4VkIX$IDD#NqzZdOW&D@Kh>pH_nBDu=RIjLN|xBKc!ARHtKqRys`vgPiE^{^VtLSxgp z-rj#(=gYMU`&Mml*VUfL2hJIGeQFrEsZl@@f#P;AIP6-4S)wJ<@8+JnC*w1VoZ zN>eTX^W5b=N{$jGaT}F{mD=7zdO(l=CPhxQqLetGGI!zyRLkXbGgVdc9JV9}MqSITD!mFSpp`CFiUub5#)(z6!3Yal@JD3aY^InNHp8N3Sa7V1t0gUs|Bq?@K0*n4woFULq{2~UXT zc8^^r)Sr)@*gyBHr?{EcgC);(zu(;00hX0*ZfDP;R zLuSBA>+9Gb`{alYEQ|tF#`C+~J@a?_3#p;(BDjOY-zfobJU{+F-gt||fKkj;wRhx| z#+JtESkj%79&V9^w4*G3bgymfmWmGl(R8o0LJj}^_elg2-9y3_*V*Fp`9{zCF1m

      3Y&59IgqhsRB5wBi2FNVlpqPk*ZuexBi)tdTcue)d731}G8Rx%O z2xDd0wQMU_;Q6EkD)Y52%pJ@_PkMIJO;}eN`pfp}fIMxh06<}uYR2<54^CzA7OAxl z|0Rk~(_-8e95qqMVw`gR!b#QDYxQ6a>s#L2?bGUx_*4tgA~M}KkUTN?&?R}vqC)!;dlD6 z-T=0lP~ghhOCZj&Far$_D$ZL^6Yv{|jn@QNjgej`jr4%SMkPsaLZ~Xx01djaiSsRD zoKj^$5J2T@Dy)=>3z1L^H~DK8tS7-Xi)E~nkpdDZ#%4l}WJ98I*A}eC6=&#&SsSpj zY#gBo{yYjwgzvDgb598azAO+qYS zSF>kNXYka-l6_D21Z=tG@G|8QifIE))*ULCD5ZG!7|9W-dJx{od?zs^rEA6R~WTd$mfx?Ap0jQtPFjv1D!Zu;+6Ag&-?8d&`>fElJbW?*?6n znXTSAgS`?M-%`vt19E!ksi?!9;k(yi%9}$SG}Sx*Q|F;5I_!M6<3%9JBWqwH9tO3Z za^A(?9@$6I7>~_xC>4hsJYPO$BTd3)Hd9QsX<->)EIzz%+7|H(h)Rb}>sJ*z4>XbH zGlBPdzu&Cpyyp@FjfuYcB4%voWJ??L;L|rYho}|QEVv1e$hdzi@L)C3>ZWz2NeU3Z zXD=7%BIBV^p;tR?8Pt*=>-_hbPQdx`B^E*a(6X6oyo0FX**>%4VjN>_al}z@1k!+q zU{@e2Xt1*c#REZ0TMJWZn8SkWdw)^FaMP>{P!zD-g*qA=k-=dS|$(Ay4AZx!CWHm=$J=yXt4=O!Ve z_p0%1y8-dHAg`skKY%$87sG1!qSBj6iz${qo9{jtX1i5haGA5@nb7h5EsP+ItarAE zva`kG#9WYKMXr6L1BNhZYDj0X<2U}6PP{*!TAMvsRd7Ya2chzNfQmHgh@P~#XC^v| zSm7YO_RdZ9H=&9u@fgc&Cw($m*9YQlKVxZlWA zARpNEEjvnFHhSI7xAGNP-m5Jzxx!BQZhcX(B01ns!gPv@gH*Ssz_ON7E4 z^pY!Fm+(~=+zYEvBBumye+keK1!&sjO6T#;gbNVdB9b4kdVN!9De#62 z7KWUE?7R3b&BXh_Y$TGt_y!QWjT1T0c3lIcY@s@Ve# z9n5Dfcbraz{WiK?c&b(Tq*=H%$0cRNb1cI2j{m6c?)7KoZ4;(hw#s*G?8mQM_|;=3 ze6JIkZ=rpvb=(Li^JM4hb+q|$hLYRKiF~zI@1wOT^^&$~ztGkX|A>JJkw=sYb+l*m!&ECS*QJPWSd6p8B2p4S1Mxg|G56KPwkBi@fA{LC=9^ zoT5q8fqtveFVEM^HqP_a@Rs=60-7$Li_G%0KQfOLc8lj3&9A$z1aLEJU68^daiV=8 zk+;IDv2Q;SK&8n?vU@sNQ&IOZ{Wx*FACC_~QadWuldVSo#&qiNP`&Il? z?@7T={@7PAMkJQ}Li{w=o9{ismKfQ$=1x;+1?m}( zuZ;UEQ;8I#dZms>({llZ-8z@@ZuBMFcRHY{hzGFpS4HR2&a|!0W0p=)?2Z2T63xb2 zwY&=VWbNMrJ_~FEdUKBT_}`~f-xxyT9VunGK}Xq>gN7s60kE~&nWHBi=!4KPdm0FQ z(YnVbY>!r)cZ#Gkg~O=Uc^F`Ey%b4uhT<)Huvu6U@^OLIs8E&I>2}HSJ`Hc?q z=brhbRTNM{9Hw8$ZVBd-8|{nt%6o#p$@{UU8H9r2mg4}CNyv|KKbx6iqSqVv`TIBs zB^=aQN9s2@}>z44rZOPft{fj)TWXGE90L0j(8A1%y4IV`#Qw}l^q+`v1ABT;C zXW}sP(x&&vz9VKAPyhA`D&Xg&P^4Ov;U5nT-Qnjbhs}J=79Jzo{jd35r%8Ocd{xx5 zxsNlp)l1!1bv=kAO@v%#HBK~r5X_NsGOj8hSn6~*nroSICaRtD^vuO+r;YnRzjt!k z=_npC8;BNY=s=y};?CRJmy$kSZ8QUkH`GuP;vUs$v5(pC|AEx*MabSVR3Xz=T{*Mf zv`ieHgefC%a)tc0E1x^1Ppc+>EAOKKE)gkn@{k{(%WKO4#CD!Qe^$VOyPO|!*V`_c zp$2Jjm&!nqE@q3}J+l!xqKzA*3?h4A`FwAL)T(uG#x;<6m;4Ll93fAP5gsi~oKt+* zHFpe*$RTS&Hry90H1lzq`K9h9D<{80oiRMgX2c`7rVzF71d95QGJlTqLPKGMDHYx} z5%RCBkrmAxeKz?GKi^I)qiZRqJE$X}<0xQh-BHXm=kPTo^8lglsWRF^GcII%kSXnT&gokz4m!>sTusi0uCVj!CTZ6T7tU~m%SZW@TKnj7g;3q`X!kK5S zQGEP#;!ex+0xrD^D*=yWTeAKi;?DD}sk96C&NzxniAb**WfbXM0b?>F1B@Uu9uJn?w3P` zc}JR0cr~^PL;t{@Z3bR&zPv_;rPd)r&SRJiT7~X}e8iZ0q`s3n4K*23a@@Jb;$1&# zw`x63*{;Z;G@NPX?HRb6nUbfsgEk{8b{_Il$V~lU|83dJv_Xn@JCNL?h4_*rLQiit zdp0hvE$$3%a6X%-&ir*QVyisZB6!?^RT;`2<;_a_sC7}Ar|D{+T{39V(a@2YfQk(AkgNKy`9ogi=T|(#~ zAf{nq1bG~jjXW}qH{zn;xCZa(euFT+g6$L;l0TSugol*+ojC8789r+EkTElENyrOM z<7k(0qv|gfQry(iMj@c6EgnfMy&OklS>15U{kLsx%6Rxja7#i9ZdD~26;>J)+BP2? zSTd6qRupWO(^ni_%r*JD{=*E59~m;AV-V%!M=p-MGu8?*SUux%IPI0;#V-LTl=#ql zzIfXjQmr^)X7>!_n?cA$P3Gb?t^l!!qY6Q)D@%1nt9yhkac%H;wL^@5~TU?8(b?a zFDAzE$|SHX)cSzg-uy8M*ct@-xQUaBdAeuZ< z73>x=h?(%8AMe)mYY5OkRVs>to+Fh$yxluZ_+=hfz~5ipAaVyE0!ywy2LUF8RI2`u zK4_lpY6WVlmNGfQLK6j`@QV9r(3ds4Tj`TA^Og>Ayl!Ua^^8!DxW1xUxHO4bE7X=m zob^L$$+ueOoqTFq@3*jwhi1dC=1&HA_1nSsp7WM*tK>!UBdn5d%J%o`_ChL~ zuGnv|V~;C-#ZzL^4vKWA29M#65EtNl?Noxi_ysgA`WqUIi%szs!2hMRFO3cwpk>es zw7i6?@DbJG+}Z^Y?kzk!TgL?v=+RO~Sc$z#c2gDwQTY>d!ALPEZq;0PofFI~+fx1C zuECv>mL35;wd!Db!Hz+!rlQM;Yf}Nc%lqLJ=e>0L2>;}ZgqR}0YgJ^M%JW*bq&Nu# z6~Qek#bIew>r%*F*?B3FYuX3atBj3@6a=+^Iemk2@PPD?yLA~mPk5(CVEaYaKnyS? zKrx#fAocL}$mAXUQot^5 zCDs6Rxv>D(gO62Fy#4NDD>$o-F;gAHKN%^;0J9>LFi}XFic8l&pO}qs@U%xJELd!-X`^z zk=Oul^4$Ea9{*aMaP-d^{PA#TUT=O6r12pk$uA-^p(9Ssmoyw;Ez}s9xTD!gMms0X zN*Ip@VtzBW3eZAQ?V3B=rBWow%dahRCSszcTFsB1OHX_l(qnsjT#p;q@2~Fj%vdEr z?_^cZXyAKGiraBE6q5L;-Z^gUB!87x@77?W&kkEqF#K)I*y|&tZPlG0ua-Ucc=b|n z?l9M6Cb%H9v{5ku-(^`$2i(zjT^7YtbDH{Kq;Tqg*1fj(!!S+p3-PfR{r>-mtdPG6 z=Z0w{r)C=(*uV%-0Y*n)M?SrknK?f2{907}B-FUVJ2vhTk8EhJzWm;=CUb9Vz+oz7 zUoIt&(;)bGuCF1L1r)>8ignFsr96!K?8M2K5sbRhYzwY;MUE$04l)&WtK?3YMwG(q z-XIR>BnMu!enuON)M=!^8Q{B;ktv2>{0%j7#D* zMQjU@_kbyzmWQ5LHbQwFs&%|T{5-BIgKATt9Xk>6+};1eDLGlDWu7smG^nL?*$$6NVTO72U(>bJ zN2)25Pme%3Br<`nNoVz&lV*~VJ=0-EEWSzUO|u`{TnTn6xD70!!3>C1U=KPPtW-CI zmuMaWtCj9hgc{|29s*y=ZVer1AH~Xvl^~Jnj{*9I zVSs$fH(tHVeCkQ{2s+uyQ%

      zp5^7JU>XR{7jn{2to>=mOx06%2;-MQZqB`h7TuwW--lZUjedmhD;%T?HHCkJBz`#@ ztS;4{bnXL&8~lhd`4I|s0Rdm$5t+m3aT6%;-xm)-)(1tZ{{vKsKmpd=uXlwoF9{tg zUa@eEGWyB$w}Lt`Ta-+g@J#3d&MGovm{r0yN>*`=DdJTo(5714eA_%{-i*>)w@X^~(?JG7eZT>zJX!!4^S|5S&hc z;WW8qfx6I`yR?0ne+K8%&V9D|MxNM!yZRD${GhH!R1nU~%CFo+s`pGFP@#4IU{QVM zTb^gbe&m(;CDgX%mW=G>IK3VAjTd)`=)Ls!uDQEgde#wmTIt!0u!#y268&RAkBj-_ zKVDX^KG_;12VNgk{qTH_Z)4-l`)V-$iaWQeRPSkf<0ui~NX#ZE(@Q_6 z#7yl*)#3~e+VO|Lw5&V+r0`fadq>RsA4`w}xZm@r%6A=krnB)aj}j87e`ZWXa4yeh z?p))XUIJ~l_&=O%N>DhldU?YS%)4k3WXb4(=czk4#c_9^gars3SzEp*2DQ5lW_9N) zY=AK>8jFj{&iJ!Mo|;?Z_ubVk7n}Kbz%S-v(%mXW7cRZQC+ha*Sgp8jCmfE53tBL% zS>cuMrA*RnVY~#oKBR8F9mvKU$BHcPP!EFlAGSi4p?nn15JJ_?R%M#(B!7cTwh@RZ z6@(AZKXl8Oc>>6^Ix`^ei{w=%JzOq37K)ORf zD=HNT-IDqzh_S9xFVjbiv`r)06Qe%#p2Eut=kE6kPU$R@wndf+Pr&7oUd7d5p(tg5 zQrsqyFo0_97(k2RLZ$^K{Qrag+V|%rWON5ca(8|`$i@XMZvrj}ZRv3QO$#bgq=<8F z8ZIs4HKD(UR>m2Jho{T#HGBUj1QJC|IGFFMj8+E!-7k{+bb?BBqCQTd8+9m9_g>?=Zb8E8HHq55objc#A z6^QuYM>GeGbx(kL`sQa#WA^ zw2t8{$yC;kII?=_8HelPs?@IP9(ohqUx-(|wI8=`rQrPo^sbW>0-C=5cQxnUmd*0# zU-olZTfAJ}_X?%G#sqpm%`K1N^;LyBhLlx?GJ^*@zWTl*Ucoh4Ph}atXH##*5`AB( zKTlD>sXVN^-CQtK`qs>mC`z7KIxaBeA$RvX4=RDI*vo3D`XBKEOu0LA-&i8QN5%Kb zV0FBDd0@Ucj(EUFZ~pj}Q5Ux)0wrO}u5zcVD+ONM=b!R=w9HYduk!i!7p$*Mc#ix> zfc199h>iEVIF@Ht56tZ+AatMQG(w033GO8)(thsxV4Q|)r4DKL!~=7uvh#31vq7U; z?P%;^@l>?w{ZNBa;Z;l*JReKokfq)76fZSjZocBhRW z6|WN9CX!@diSPcc7;v_`W>04{Peh(bt#gSu7V~s9hH5@WL{3RH%r7Zro#TuoQ2R@vv=1+PwoBYscOde zf{yIx9#r%$m%-(cqQFq(vaEj;7XW?dda>pE4%{eZt@;D&h%EkT8An{G^!VTr-ky*0n-qAk9()SSG;gtKTPa$ZT@aQhqH+X_5@hr* z9zM8u^9kA==SD;7t(RLRDpZ-@Ym>{7IJ+9H<;M8NQ5rkM4QuDBQK}GO5^)qB<=HMz z$D@Q46nIC%FA!MznZmOW31CxTideP%YfuMwf5-vy0Lv~Zf!!n?CY+XEQX+tFZ3g@h z-VnTN@@YNt0%KM1#i3q^T2`+mkgu}K#IaYq9U|)q6j&YB(wm!~g0Su=H?Fp6aA77dG3I$tSn~bcu#XGZi9Gdun7`}k!O9qF*$0CG z$H7{+m!$l%XRK&qa6pg%?sbZkgm&D{`|*e@^NX zTHA&VO~Z<#=nFUV#!7V66VsN{=1wDAnq(WlcDi;byHwj=?4K@GJL(9OX*ti=yDp5n zJE5G{95XE|G3BwWl86cYcUnO*`<*`&8R=%F3BKt+Ds(M*BB%S@hsFAI&r<44JoSmY zq%8OQrkbqtDMQmgRbXT5a8^hQz;Zi}krcR0<1b@XqmG7Pq~qOpdQM}T zcl*p8c-cicqm*%K^z;#vSBo-9MgmSsbJg#wF0mP|`dPb6GR=jG`E9idfkXNn)w485 z#x%uRUS){Xyr3tSD=rzBMO!uX(RR**OAX9!{gjDAD|6fM3d5lR|NJ^Sr1k!b#Ob z_7Y)hc4-@fJ~m8rzN=UIKjz9G%*b`)58NBJUljzWzmKi9YR6=jCk^guce%zqTZ?P% z-i0B2uNO`Jy^E8J5idhfC=R6>=SC_XdEAY<1}kj$Nuy2J*xP8>yQLAu;6&PFsa}rO zdz<(#KbBmFqsOXGjAOeyq$k`XhK|=f4A!TaoVQf8Np@4zG%Yj255o`lhBC!*&IjeF zkg^P<)ImXyw7?2_$we>2`t=V3dIF471{XL&0m1(s65mH&3VVa5p_HK|+LDOyaCp93 zkLFa5ku@s?ccxrmA+gLnggtVtHHp5c(LHs&ig=*Hln42>)xe~8Yo3*f1w0Kq?TXH4YA3SIhsc)x$)8Lp`E>6sr>1}wa&s^?^u!J zlfXr+v)>Dmxl#LSyq%OSLJ&+rI0L4dodM=?0S-#yZsTt7box*&Fj}uF_=-M*y12pg z`>-Uz!w1W-bhtE5q$1=V&aa2JLnWLF$A}5SYt-K^Z_A*k;%*x8JtJeUuEzT%k8tOR zm}@2>h;oC$7z6s`#{s{{dc~Gu)A~yZts$7 zR=;WmXa#bIntVaiG^w{OpBgon&tg0gp2E8ApNHakRG}Q$%w?zcoaFWrfs#qs4+F-Y z-@D^^Z$JSnLAiB_Bsc%_{iyUdpsknpgMhQxx-V*`6@4OPNk(Y+?jcB;1Kj$yor^ec4fw}fMqrov`kma)APV~R#zV3q;hhr3=NvaE5+_NH? z#(7&Q?NSruUVI*SRKGtdH;;BMUJxP={_6E3&p-H|eunuX(&8UGTnQj>tOhRyq_nE{yqidX<*`qp*xUzi3lC446 zfqw0dT0YR`IP&t7Bja>*{;_?oUhQ-=n=~D;WnjoDg>htG1iGwPA{HIrTNJ#31;y2Id z+g#(DzQ2ud*0Ma|bt1VsXM&=2txaXxgLpPEjn20n&+|Gc(mvTog(>*^WoF)REpGg5 zfKYNLRIhZY%ZNF;#3*=zt#ZA$<2UVjW+eLglZ3m_OoA5 zradxvT5lUNlOOd7bGk=!b4g@RKY2+KsV|(yBe}m-u`tS;mr8%({ZH8oRoF}E)~WEt z{XEul2rI_=MkOoYjK-`<2n{wfMV}YWUdzB=x*=E30Yht&<&-|08vEs=dr05}cERpr zQ`v^ROtkkWhm4q0o9tL7;Ei*#w?q72abt#}O*oXq$Fw`9h_11U0{_O&w9fAFZtYda zrBpxhHQ7A0giVeCq^HZmYp&ANH^+p1+^RI3MSXHo_1-+x?W-X}BY2e;OfyD*R61Qt zM8b|H4OI|_8q2H&c*v0Nf*(V*BnVD9EsJEdp#f|R-3G03cfpWELC?W&aTj`}jK8;* z{fx7MVDO|ZJpeB&+O|bcPs2dq!f{IA5c43G`@w3e^>4)S!gE~r#m$iiRaKYN#1KIa zR>Vt0W!dbk2M8+-m=cts=aK$5w_p*bnCEvo#HzuZ=;x+e?gcBDso!LBS2r&xpsAI*kF6|{hFv#z2y-v(ORqYK`r|VrDs)&jMGkq z4o|<&zy;DDK#wk(N|;}qehA-BI4Ew*&YTbqAhoz<{jeuXaHJUk{)e&&X{e?p`V|ZI z$Qlg=#0KS_vpBH-Q(`1t3YQI}tMgn2ZVhP$cFCz( zFk|!&C*_L&_JGKa*wGt_%_qKmT30(;w6Af{U`&1-y@5P2+H(wx;V}NU75y2gcKSHf zUk4RPbu37vPZvZ1zNy&U+^40swJbuQ{wZjeRYfZ)l&9_h+v#P! zwngf^>~y3?xP9y@z&|xUd!C2+!_TxwbNS^<04djKtKtzBiQ-f%5C$Fu^h4g8IYQ4%a}E*ar`r<0&eH7&&jomt7Xd+6l) zkHwDo@Q>^-^G?ed%;Zn@MhrJDfr=7u#Lls*S(^4$N24Q=r$@A1s;nv!Z#QTB=J$9g zrc*`ow12shySGK{wM=hGrSmH$p|>|}rBccj%zI2g;OlPI>1(agv$%f`A$UhFJBLn} z=w6;S$}q-`E8OpV=f@pVGo;A z)qS0h8UluAnd@FlGWAs%dtHdj`v}5|Kty~QHp!+zL@J4eH07aFJHN!1JDzH(F@wqb zK>?cYv5_qQjX)?O5Rsp3kgYwU=^r*h4cN5{1JbYpPEu-ykz6~&vZE$<<{z;uwRT)~;qAq&vw|=iW!s5Gc3Jxb+FzfmLZhX+U&WsWhNz=`3sd`AWAdwR!&W@`pw} zP6e7-&YnlJAfukb=1MJt$At{=QPr<5$12yIfB3m9L z_rn_0L<&CMok-sVR@HK3w|EK9eE~FBPdA-^~bD)myhOY4XxZjQk zb}E&Akf+=lX`UUWO~gfaWqFm3E!&ykB6wdn*gAfOU03u(2!yjB|#rbIX>!&1Xoc(CoA~O!`9#)aeQdF<>LXiaiX(+ruVSbG!#>_T%&1A!mXwXBp@TWg~dQ(ZR#O|_nJLG=YcK4oK z|LDam{u4=ZTn9va6|0C+>nVf9Ne^yN zU`qGD|4Esue~#$Us~KvX?MAA}rvr0cI!$-cLrzWprd6hQB%pw+>Cq>KLeWyf#U`|@ z8(%$sgT zOUvHY68`H}4f?aevshLbKWeLvo-G}u*dCDiGM&L{Qm`A+&yv~9F)*%O2AD+XwM~y1 zA$YRfTEcCT7}DtN^(@#d66bB;p)_dV4h9brHHb&O)3q31?APLn1vi_JWwjU6rJ*-< zdm1#Pk|_41x0#IoFGFilU{}{~j*7@uzz;3K2|>)XQgaByrBdLh1=sn;0N`xRB@L8B z?dR~SK>r|61Bm%bs`DlNGSU_j3>X)tLpoKFSDJsU9Y^^@Dh+6R@=8CI^KcN7HAWQ)uH~PBp$}lGb z%4q-OFwfgEKiH$)$5)}IE6Y;6iijjU1^zqSy2JU-0>gaH!-J*d|8hZ1oVt)!)>=vC1%2C3=0)|B z=Vn~EQIw^2{FJW_kC_UddAEP*xJikKJ@5f6k?y-pC(FH&wph~8uJ(QM<-VBMBgen7 z;o0}{Gid=ln|2Ki!0c8Hcs?YOMjNLwVP$@5C7jO4JCht;IgO-ynxhns0aH1(JeQxV zLFEwq9;zD7adL1OVOj|gecy3+QgomOn9Rasi zQQS>_pm1ubSMJ$CuZRL0-=2Tm9H}@bv9p}W-KTaj%G`NvFbofu;qjP=I9Q`}z z?c0e~U!1R!`xe>!T}Zc1KY?bjtoL)NUqL%>DtyHq;d-oNGTJbmc$xUgxu3sqWp7Ys z=*zsfjt%xl%h1g9o3*qmuM^|q-|+LtJ@%K&rE^<|;I z+f2FCKL~Zoo47NSB8RVW(+JzfZy>-9D!I^ zm4*o9J=jkH@)jJVl-N7Rgo7x>-oS@wYN-krlZ3j%oL2{+I@xDTfS1m0Et3gTHJNNP z_;Hi*SPuagzbT&)z8+&Xppu}p*0p-pbT-hV2W~QS#<%^fS>=O0yS0mhhVd#@`S>GJzI%;9fR~5 za5gBoiHn-kj^Rg3#UWe1 z_L4vna^RM+m-??bdGhqPfq#WcP&CPg0kfX&!HaGT2d&^CK#lhXl*vNZE}&U$j6NSX zJ8tje&q)2YeA?^1dVPnf?m+Iqc7yTWmoN9fa=);3kw}+nKcm7#A0?CMm@Mr!lRuo9 zO=b^0LF=u7aWQXi7ki85MAWm@E?2QSo9sOuFQ?!R&}DAggQ0%l>o*?&o zcz;Q`W@;B{UVQU;aJq7d&0mgr9%&vXDia7+AvWSVViN!&TcA=8x@hT5l@625ktSze zVwRfXRW|Qbi=CU8Kkus{^dwK(+oB)RQ;3TmEY_}z%i&51DFc&v7~S;q1MG_lM8;r_ z;cSD&{?7+sjt+xAT2d^BUh;2jqD0yXTH$kb`1g4o7ztcVUHCrUxVsg48pv4}o(m<2 zmmie%92HzSDE$hP8$s60z>f$H%V!#+MSQ&6&-q^AwfNku_K01{F_=}kL^xODR9hC< zBYWHR*uRIos`7zx(Sm}_O{y0ycxz3nEpVV&W=3Betfp!MB{g0bc^O9RTYf!QqV>IC z+oUi?9aH3xtiWpCN=Sp=I2EhJxM*RYmT*9wpP^U66U? z7*6pNim%wY5dMo4!HVtEpbPvf5QpUlUFBvSV8pnt<=&3nn&q0Q<*n>< zIm<0}`eGj!G(ctTmrrBwI&C#rjFQ`7bN+@VEh_e6^68~FQz$II$JB=)dE4>AIbMf4 zTBUoD4aP~hW4jt(#Ub5gNoTw!39gwgxfRywsPFbFM_{hU-;eYT$^ms zp5ncTs#`7F_$>NLYsEzPD-_CC5Pm?y4*mdGiW2;h>24|hxg}gI7;Yl5Ypm^=Cy2u$ z+lP4=CrF;hrywN`a*@B_ho6O)o`G^7@XxRN>Vwhl!6m4=UT~FL`Lt3X2MxXY^rI@t z__R7k=2x6Ud_9EPibbrJsv!r0A>4TtpNQSF@0;z$iNRKSJ=VHRpdO8mn8q3Qm2b-W``y)SZf&oz~#ua^Bzs`X^#c4gC%;ee>N4w*OOsh&jdZtWIkwABFL*}6~ z`(EFwLXgF*>drsfk1xuK&A;=#oH{}DZEWKM6AIU!nd*BCC}6=%S)5h=GQJ{lSwFdq z>y&~EU}Z~OZ`e?k<66_0kf!`Lz)o@6Ni1~I5E+Yn?_Y%SHd-!|{8CIcsIW=){0arA(NnhxK&*lq9e%&#_xH)Noodkhe{v+JMx0ZLY_rD26`ko@TsaAa!Z)dIUC z5to#oy)}2{Dylwsj+U~oTW1~g5V8~h9Bu(|VLwjRh>`fN+{VO@@hX%n6wg-x{&iA6 z96IMlz3E0<6qz&u#!KlP7I;Mz_S{WSQaAkAW6OkDTTa4Of9*}~=kPKK#)DesL!dLI znyYpMA)KOEXd{a2kAZ{X(al>PpYD_9cy3b5MoUtiyBP-92rGGAc3N>1qT{Gzi2^&i zHnsD)?g;l(lR<^6`~6#h{g+$KJ}ugo6V6wP^D}oW@l=&`yRi&mWS+e*QF1T*YI?uK z)UWK4C}|%pedjy+xZZ{h7TML z<<8KTT6XA|d9VGzgX-?9)ewoZMu#1O)>woLaG@&u33rCuL25k>TMkY_%7&FnLmiqk zJtsmy#mQ27+YUhDNW>jzLQL9ycxsO-mSH(+U&QInU=8Lrdpp*f)v{vkFAg`lzqrQ^ zH;o}3V?%DTAabxi@$yLxcXq+oEo0zK=bG0U@)ox>8vDapXLPSKNd|qnZ{=&Kc0;|Y z!l0>_tfdsv+c+f9JF0~DP&Y`f^-6`yO|*HQI?+c-!GqNzP##e$cwZXe27A0Eloc|T zTJwMJy?cEsRK#zE52}+v@y$WB86ynh& zf=*xxF zmGK=4XDy#sDVA#BvN`e6eBr_ic8z0|6*2Hx5aI&0SdD5Nx?)hfCyE!M2K- z9*+I&CgbKe1-=0`8N24)Oo2?*e$+t)A$Y`sU59Bs%B0p?{5s${|&!rtb)B+rPvt?>yukW{sR@sfI_G095zp3 z_)DJ0b0z?xt#s-14M|WTgs<9KH00sOQ*a-BnM4VMfb;gEje^~|aK5QqUy%3J%zCGz z;MOPOraRa}E&^0~-K;!)sigiXia&4C+0d-=Ql;8vZx*KI8@LCB+?2UKiil;SGKI=b zqb43EMHbnQdRwcuVSJ;_gv*W|BmSe|zUK}~kQz8Wo_tE{%TwFB_f_B4gqa(=rAi2X z(|I6nL{8E^nRhnt{9tpnRpx!ECo!@dQjVbv)w#Ha72x1k>-wazbxQoYrxTg@glEj% z({dVM`?*cI+<86u-&{SL+)$UC5+%pF3M<){N6{yjH^(c^rxev%mHg^RHXSPoaV}Mc zY5QnUP|2!Fpj`FgW!BD<`0UjCpOY)RH{4v`WDhVi2y#6Li0xtG^?gtI#h!jDK^Zu@ zMA&*wk>cNAaz&xF(4YGser{u@Pyx8FDcg=w} z#%eY>HE-G$PT!xZLGOwPMbGnPg=63V$PVPm_brLwNA4%2M)km|sAa^Zwktby{p_-q z%iH06bu1<7WVm_Tw@lmxj{c(_F^{7nZ32nX3F8Dxsl8?fpT?dkKT;H zhqaS3Ltg&u-C&v_7vrS>deQ8A0;#h#om)qhOw&4tJG5$D*!Su-&kg%w)R`4FfB_?< zlM5}S9#a|S;Qp=XpL{umvFE=*Y4@=eF-Ogt-jCbWK$I(DWRw2nL7lgf#qpTpmDx12 zhU?mspT?;{x%bLIX1D^FAt*s%uL4NagIFLM6H#zu%zP26Y+#9mR00eTk-qz6%0Ct? z4f@bd$|8yvMU6@k$|YUrbt5$z!BT1l4DJ2QRG|`-S?xWyfmb8)`-JDFh0^l_gs4Al z12``tgWo=0Di={Q-YwOjxsawV4u2D)j`v$1E7g$AXG1aAM~VI)VK|C_y@kmu_Iq46NYjlaVQLqX>*#s835=E@eJcI=L^b4l4 zRs6>7rY_Irxf#mJknX_fNLWx>PK$1y0z5SHJB)?evgJE}>TL%rmJjUT{^CAxg8aA~ z_Re-F_>3M4L(1{!ErDcgIkl|yi6_nX)OZyBNJuaEQ^Laqrl7d`rUEvW;(GylvLuJp z$1*rx1GUgD?ah8_jZZJJ!SqYS<^8Buh6`@)F&KZ+Obz|~zjLADpaizYp_t)VH2K~r zX!=R@*2vD%IoAgi$rVx(Z%{Eef+5-1<#OTp&-G>!g5YyP_V_Mq?a4MM zxQ;x6X`kv2TGSYeYirN9<3?sBRnBfG1)A!rdr&=G-4xrhC~PRL{Zfg_X>E6t0lS<*P9yy}x z?;Mk3P^?c;K~YRWMAOXw^(~KA%{V+E1z79fmtr#C^RT9q!>@RX4f^5B3BUJ7fJVZW zr7WZz{0Y37l-BLAY_XXsvy9jW)dZ*klqfcUJ(EQ44zB-)5H1LO+Iy$>)CT5fKr6)B z2BtzJRV@LJ@+^0biduWFIrHe6|hJF6Zu(lPdu zZxP071(t?v-CYYddP@n?@?TUc#pL_9i0iqj{KyOR>@kwqE1o#;>32>>RQA3vYw6g! z&bJK($F)Ejkd7Hk;`k9yWI0d?cu@Va*TEf}1ysRVO7~TUQkP*wOj80K{ky6xuk;Z- zlMqaJ;sgb-&y}4*p8ceHKB-^+{%;lKShxS<@;B#$X$M|3hq;jO{mw1s;Y_v)M(Uk^ zPg^!?@l2n6rj2nh;#hDI`^%e?*ocJb04EtD?anMBQWt-L#dTR|+H0OlqJg@I0T)hw zOPchL%I0W53hO{P)jlw+)?NyTnBs zJ_&@U^;qCeK>zT?Kj1`pK}FmSDykJu5 z%C~{^9ove)7y1PuBwJ~{$6yqv{OS`17KN9GT3Af#zlV~Sq&ZzYG^v;M5JKvUL-*0A z1Smz<#3jjK6~(+jEV?0BcnrGHm(zq@Xs`Iyfr-1YEZYZdA!Q8X8@n|2FUthYP2rYK z|IRehgVQ)_&$yqXl-`#*l~DEfzpU8u!;jML<-t#=RM8^7r8=u+RS;{qiU*!^IZadX znfDd5l+6C4pE2}hc)tNIQxwoVZ{rfHYrLz!0G|Z~XX$t;Jguy0jgk!y{q_c()uV_X zA{;^jrisnu&V{|xwg4lZgg*tLsXb>V_9U*26;A*7!E~Ky*#5k8p=A5>UA1Q+KIM0U z4%BGgOpy}oBZe8>$1&OaSonb8M#1ecR_GvzCd-^I231vwtZJJtRiqN_##{y4#Z2UX zwkE8p(QSz9ddh!Sv%$`hXE@l1Tskaj3lo=hBUNd!)JPc{){>21@b7MAde&rXw7963 zGxdi7Nt}CgXnKkQ<%Qp1t*s?~2vg&+CF#c-5#7^b=2wesmIG z`Xc2aK5IXjf7u-;10G3d5_$d;K@@)$dlcaS_*{)1p^IYB!0U~|vSh$4fXzd9K|TqK zH~vxssr-lCnA@mWCBtcwrdso@%=TqcszJgsqeC98tb0Yb!oN8q4)hEfoe+W`4eN}@d`DOuN7vQ%D=GL;edDyEgi5L_OxDbo`pwJgcB zgxKep#VU^Rj-;51m{CVxini%YRbUQFis!`Y-qkT@1Q>PSRg=hM_=mF_CkEVpklD;F z4c^9b1EE?l%g#z}bU+v9jv!zZN7B*Kj^iVK6rcsg`nao#Y9*#Y%Ss6f-Q;FO7m;4jZ~D<5r}ZpMi{lqVYBRCD|B>smB*j519W+ngi92jDW$ zgw$TmXVOe_l$78X7D{x@2Kz}HN(nY|8rl_n$pE1^P%VpU(VT8zWe%&#uWGJ1tD^Jo zw5eH(*dFcgws>kOpIok#l@(0&#<-<_fv6{jk~8f}0t_G}BaC~6k0U+Ev7Gee)7X#C zr6qiI{KTRjWWtZc7O}7N_Q7HJ@!mGD#5js`1&hy2F?x?VZ>^6>LUAj5;GiNCMMeL# z3EX7yu;kLiJZ2hb5oS;nao0HnmC&VQ#uiK%D(h~Xj~J!rTn9HZQ`q~Z*BNZOKc?$r z-03V+z6NKD#a`PBQ`mC#q6rK$s`HkE?MwA4kLB9SE(?mZi0btSe~%&h>T?QH!c#$$ z4`o~%3HSfBDskJu1!p?aZQRc`a7MKnzVMceO6Cma8Vy@1wd?4<%%c0nl27j9u8Y6P z)7MY-ZaMOMzpYVKN(nCF5+MSUOz6HNPtxlR{{Q?X22&i0Wsx)DvS$;#W`t+5Q`!lV8l&+$C$Z_Q9ZDh+j@gLbFvq9z zBz1y22wt!h4?H0!$kf_NCTU1>lC0rTC#T(T8BQ(8vd!$jmZ{(1NE8!uG6D4InbchG z-{fIR@%OgGo9?;$;!rKM&(=C4D8+K9itsVJC;jb?${z=ms)yhzv7X&U&n#T z86ybcK3l|DP4@=xWcU7rxB;eTrF>GaA4at#yx&tv5ZcCbP2~mnP6%`wpxo9IUv+kp zgtGGM^`4u*S10xJBrmm8r&d369WwkbtKvx=&kEsslv=0{xDJP{5IpmwOLb15wTra^ z8{dbG54`X8-bJW{qQYBiCK4r$e(sv~0}d2|N7azxZSJgH*_C&@-Qu78zjM4~Qispy zPgB|JpaCE>Fnw;a+{-vVSk$|BKz|l6cJjahdACNQ4k1QkO!Cmj?7xL`Bq?wqK%!dO;id@JqRyxfMl4V~w4q^$~*tCUlqL@T(%r@R| z;C8^)l)2fW`#QS?wpC+R`IACj?Uj+3#Az8>t9IoJSx1NvKs5aP546i=?q_qOwh8e( z2>c0>Q+h*T^JJj;h)|1qA*=HL$J?8DHFdsUytNi7lTn$+R4wxm1{n>>uTr6cg3O~t zL_k0V1SDuoRE99qs!W2UltN?-qkv)p2_%&uD1!`IAV~#5DCdaa5kkKA?fn<-TK6At zu{=5Nd7u64{n-d8z8;-D$|(s|9m8rv?LK1?`DnDtCSDsc{t3LdipzS0ET+wKsJ12+ zatb+P$@@QtClwbqVuotvGV9(S3PjU0{_$aYPJo)ZJTBOF!~#tD1Ul`gjtHZjlU5076qKY zccVE%bQWz7PEBkxg;S*TgDq<`Z3ZuhV^h*!z`!itLFIaAOJ1Ypn1_)1TgQb*G+@fGjAzly?L zP_l`6cwe%VSZcQw$c2opyxr~ZM6H?*|+ zrCA&?c@_5q$mT!SU;Pv7xzLmnIL@?Rx#2;TXkS9_k^B&d;9bFOb$!1ZEFDB0u+^Yv z^dv5iYClNW=kJ`XpC!~W8{OzV=ZY*}h$m{OGf@B7A8Mjjn735MmiyG*A9)g9SSSBP zy;-)>E%Tp#zG=lru|JBPVWKY^2LB35TcITdUv}8a+5Vp*1BN5@)I!c_?b8SSZO+BM zMPRrms}wmL7+mzd_Rcw)CaN3f4kg8x7XIilW3{zOL5?E;hI?7#!`BAuHp#Uz4*b7bu9U5FQBqp{!Yi=vB(nPTY4UbkGVsL%X(O zw$7`VXFp$?S+G#9 zS#2o=WIPAS8~;2GSX^J8GXJB2%Zx5t3J8%mJi*jN6YNJ50y8lt!_Rx`8qM~i(ztK# z4tQ6Wd6+ji1Fn>ow#m=18ijy7gV0-Ja90*EzRqG!A&xtmvGdyGLnNJDI&Lpy4Q09kF;x+nN3H&5o4ffk&UqXt$JEaI&An#D1Y~P zh~JUQu;QuVPliiYd`lBw*PhsFuROc9RNkIn-7xG&ZG0p47GVe`QS;8RsM@II`m9V2i8kKxl&|3DyQhkw< z*B|epbDr4Te6He**O2-2+>t>LqG7n@eDq;>sTbSOCoNZNb*2vHF1)P6^6s`)IBMZ! z)mC|FVlM&7M@#S1^aQM!Zr*F_bkH@q7*n#R#J9$;Ijkh?)38$ekOhZhG3cMKC1uj^ z8N*}k$2ly|chYYIkU9pU^rO@OFoLZ479>>w>_bjYh|Xi`ker}11x2C(IJ8Ja$n*=< zMjT<6|3gYByR>>Fb7-TVY&1ny9Kc-ud_0$+eG(XnY$R9xUF}G`te6Xnf;%JEBpRSw zF({@PqfjV#NV=u#+zdJ;KF5Yx<-7|ld0m&AX<2l+EmKZ2cqOm{J{JGkA<E67OD%8Nh<* z_SSG4I6eW+7g-Y$z(m`&l>teMr2Agg&`d}n- zj9`$exdO$le<^?^V$)6cavu6F+_33brJu|jj@ z4U!+;lH<>B%BMT2=Dn~i&ojF6-yzv(=aL{EeKtvCLb{pI+0p^` z;#>+TfwTHRlRxHx z5??}g=_>>&><>8E=}Rn#-tnB`13JyLowjm%z?z#Oqz)+f@wgji`Ijp#wzWb*U;6mS zh8D+|eLjKYJus)Wm`dLtq2_8X(5g0E80H-xwwSr@ozaAe&Swv)?~>>lmc3`RRM1pQ ztlm)!Bkv`pE5`T5(`yy%%D~Et2ye5(Pt!=ax|E}GCA&`J-O0enfU?n*jmKZZz~|LE ztTe&K{=!0g??=-YaDzfdfY~W>E$N5d(oROke5dM~6kPC9tXNCJBJ>?w@?VsFq@x17 zJSUkR`r*cxRk%(vHYz;+x6?1wldZ2BJB-&r%ay8LLm)oRWGkS~rCO6$NWQ>_ZF*6}3&ejWArH~R|AI#({}SfNVeL$Blv?sP62 zsjZp@`PNT0WY@SYS@!;T4T*oL?1XZ!Jjw3ybMgvE`s2O-p7JQQWiQUSPucD)3J0=%gQ(?Jg|n_22o1M1HcHL0KrL?IUS2#Ez37wAR-}_*Q)C@rQNTiARxT zYKzZINwg&+I`~~0$)n~HMg21-gKz+QW#Jc7nh-eR3b1Hl9aENgZ&9+r(YT)0K#V$( zJD}E{T8`tI0IQ~mzj zus3E8=;|IH1o>51y!QE(of}Er3@b(<$A_-$>79=`WI2cJ6Ku%iJ2~|e^&I1BYLi9) zbyI6}rRR}uVZk|hGfV+e2CiZoyT4yyMS9GL`scp`Z=K6Y;AtNB+O66A+Z~cj{_h(d z?7hz|vh_AyRB2pt&nn`ux?PXI-{MJ^E$(hr>GE-aclBpv7yO~Cv(pYC5Ew_{5m!i~c zZx35m9&T{KG1M3BZ`lc00)IzuP_-Hi$|tsL2T*q@9Z#s?JDLbXP>{Q0FFpqjcTM&e z=C?>w4e8`m@0lG307eb+$d+h-2-So!ITFpkNe+k;JV`p7QVS|4{4{FsKr5m?9_Jcz z^X#+NM_@Fyrls{6#algCCP&oEaRk-Cs??1T)dTN+5Bv3Qm~5DGqOf88y(iOo+*-XF zyC~wYid?2efYC$(ah2I@rJ7%rR~&WfY?FuTLRft1LoLmci<=E$D@&<1wns+d{{_Q^ zqT$Qd9v8WUI0aw6u^Vc2?&R%3x15?%Z|=gU;W4#{V%}blAOGPtI`8E&jmhBRT-mjg zatW;^QS66e`)M+r>sk1{fOb+c_>?gir$wX=Fs;YQ2Z(Wg&}XK~1SMJou||MnzIL!)@8k_!o+xDDs&Ww1^1f5j@G zf3EDwtv(`7p{iheEl>c@>@!O11Fpc?LaChLYr}7k@^w5+Dl^;)T-=pq6(ZGle*D!=hoHpWecK45Fioh7D zg7^Bi!oB?JVEsIDyK33{uN@n`Jo6!_REwYl+fwZ-qd8^Hhw|)P42FnS79$(-*Uvo= z#JbIf$G2rt2!?{w3`G|ys$jTKCX4@3WJOq;ExH!xWH@a2zHHGWj}kZ-*4At`Lad6M ze)wC{fNya`c7=rDP*{9uFkIxPPE`yqHj_I(()Ny~(K79O_n(rLlK#S(@<4z`_a)s# z#$)DW$I03x_uWU7@bxt2A*dwtaL@Sq=QD|bkjIJ+>^*gp^5@CwfJ-((x?9=s&Ax4y z4BBbd(`PnJ4Q4B|Wo-5H-{`d%X6y;($pU_jYhx=is@ToXUkQ(~dpXsYpf8P_;~=MT zM;a;`_-H5Xes!k)p_;WzJ6dFw8tl&>eFw&?J|S9%`UTxL5df54rsz8}L4f~gz5T{2jOP}i1WD~B1^D!&eWT`D8J zn#vaGJJ^+8c+5Z4QaLUaO2gLOlG3^W%m8ZEu0=s*_g)&=T9rC2pNEv!@!Eox4t$VZPt`M|rq5of!Tj7lA|LxL%7I1qD4{~bjS@W`zL*!TJ zcItqss*p7pmqU_;kX@gC3^+Z-nlO(3HW5QAD@vYd%78fR@aJ zc~8>2!}TjI@6lw!k8*o9Nh&|(@?P;ScEtDS_jL*xhc+POq>8=1XrIuj`1(SDcNYS%JTc%&ciFpA zCQF+6A}s#UlJ!a$WcO~~P+0NB?5}!Zyo8S{$zhrh?+lcY{f(vpB?4LuFGdPo4p%B# z4GaY~t4jMTlzG+2Cbb3>{z29tznt$XT-}9jg;7+dLJXz-9*{pLAQ20+JJ<1YSFy^l^EgjO8(Pu+vbhKlb6hy6EA~jKd{zoC%PRKeSC|UGOex#)m z?S>VKIfjffLA~%2huShNP3?EHtoEy+6!t|-w!JIaOXZl@ZnX(;nlCJp^=hF9R=p(# zocPVtD-T3!{vcU8)MBUQtcn@%V*56fg}rxE%qut-q!iD>ib00=?pd)L621e9m%-&O zXAP(LpQPCTUt`Ljp!!USlr$kR5}yX;HG6M@ZPhGpRP^9!%4*l|VjURIxfz$qYA<9H zzDMqF{R&UzU@1aECeXvYZ^Enr3QD3uEF74VA6s9tk;rUVo{qTOZt%!qd~2o|eFqZD zo#H;A2x8?POaRnkrbXG4q{Y_m)9sna@eFf&GwJk}uh*@NGgBW%R(Pimyhmos2F*;i zHm-(5Vl+2>`L|!T=QUUlcn&`HE$~?FNgO#`>~^=x1C>^gK!bZJ9YzUK0gbPr@(|;) z3yJ9Z_uZ?kW%P{V*7e=Cqe#!r&!nGspEI?|e6raarX!IupmU%HxdYLGNY@IR5D5Z> z%63y0r*MYe$NCNkm%8F3udoWxQ$8nXDjVwrALU95M{|24U}Is^=6Y80E>6UmszgES z?EihE$MpPdQ43uj|8H2vg9cbd4)t6{J6*&&3Y*B2(1=FCH`tb9L83u=%y!x2gk;HhYJ zrX_JyjADQ~tHU>i0w25?e#?+lxC9a5>ai+QWJTDX4Vtwb*POf6=}gDUB-q z$&2lTTHGELA4(L}toQwGgHj;+FW9oL#BtDFW;Huri1F4Bh~~}-(naL>4gifVjOMZ; z1M!jQY(hIG4S$J31=A`J41G9{Q zlDTHwrCoPV%_|BkDA?MY7H6Q}-emwS;L zjN+&soM*vMLbry!ie(9EY|z^`oEGHU_7sGexAb)f-gg>$4n%w{_Hfz3SiF4xT+2*@ zDQEGrn_?l9?@}mz?;GDU=bhhhKPo9PTL>wK`9DWMXym({-B$d?D{fooV9M(2h0*Ey z|9ukxq52EoHuMn=NHjhIP`Uw01960M2k=j5Yo1WaR#nS5dGB)Qp52Pxlw{F*#{73z zv8V=;{VS3cBakEyR!4%5=cK)Y*Y};dm0bJbd1>SPLGa1wjwv>4J_4|YM8^^@VcvBO zUjQ>e!tW7t?}u+Vh>x|)cx|cw9g3?1==W0i;+(h3UN`-Qhl^UQ*~zP3`GFjDZ|M_7 zzeJTShV7QztuPOWj_9t~?^JXVu`O*h)AM|(68vjeWokL!XuwIc+@BlyAYN9j=x)_e zECu@cxswkt4LXxBQ`q1IP)=-}5aQQqUACtdJwg1^N8XKzM-cuaWP*TGlx z(agRZa@r=m9HXe7T?1eC;&ks9n^7o`V(k!TC1lzNM@&bduOU$e!sYk>VqH9>(ku0? zE05m08`2%qv6MZyy;Q(D&zjwp*dbe}%urh>Dub**3f*myd`F(v808kqNycd%ynYJU z+%5ucC1yq>zznkPwv(igGlE<+5Mer4={S9&?bZ#A(6q;3lzRR<(T#(LIy#^2#tHOu ztkK^rD-t=ywPC^P!5MYJn$>ucdV#R;@l7f0&x!A-S>pc_q7>^R>__}_>OTz;dtlU| z@V3+L(P|g!UkQl1#ZGb$FSK^XB4qwS58Z(Xs6eImD4L`0e99=_kK@U9sUTY}FGffVx!AN!G#t78g{uCDC^ zO0>e>oe)wWQnGXQ14RjE5KGgcTmnxD-7%U83S=KyZC!_HtAa+7?id*$JjVdQU>?}V zw&?I)CxkD$x$FP)ZaGO`?>9ld=2>_tEBL3cQzf2*@f&|N7?onR#K%VvRSUi#m%BKP z-BBG-n^k8f3@C$Y!6FiUCphO#IM26j_{RjLPkB?v1|Y6mC{@u^gntxLB~S zO*D99BmUWz@0^eLLYsEUP;*FIqmJfYCxxsct>jA=i!8(#_b0~pE->W zDxpr2jmnHZ_=mzOyz^A`Y_O{A(w+z%SxACbaOiAVN3-9_R3=>auM|b)=U?Voa?gLf zU{MCdzvzDQ@8l8vt&tW4uvTQVK+Ya(rqO5=Ch%hFJi5`cHJ$C89~bWK*(Brs zCpJa2)JL18i5RQ-knJz<5)~gc51t9oO+Y?ENY4$2@LUG)Hd5G+Y=yk^%Zxv!Hh~ZZ zu#i}*1x5~9u~+BemBl6!$zHWk0=)XrmprVkS@QA=dUqqSjNZ z+E4S%FZ>w}gkZMcOT^7qFg#X!NRbT~_79ccBo_AX2BS0TbRP)o{i?G#QFfPgEK92I zFhcFGCf^;#G4N}4uYZR=KX!d0eK4~xA<~x?@!KG`DJGykpu*aOwzmLKcPfKSE$zS(VS#_51SxqinKS%!2L`3ROly1TW^1LCs~_^m37PwkkA zu>kk8a~j+Md0C579dX$#DG(}TsW>&QFr_>HYiK_{c-9GEpv=c{Ha`g|ipcURPI*NS zElm(roR2SUbT>w2&}F|m<2kDhcP)}&pOy118x1ArKRE>So-rvw()P zxaTeGBh@2jZfU($Uu{M5RETiE=wngBSk>*m_eph=gW=>v&AS=oy$tq5{In~vB5EH} z!!BC(nDyaD;}6=o$Z?1EhHbkjBLQ9gv9!TT=;ltwma2k)F*++PDohm}DeOtj+R zOg*~~lSR?|{i40E1}M^)ZN?673Z~4m0^Z~fNvhG08(A}*)`gO>MPgU>B4^j7$kTJc z<~^j}S2%;(%0SM+1s^%H;GMyT{~fhpmc4UIGR^9kN@ray-WN2ddD$(Nup#{a;u)`!nR>`DsUeO8M*ia*qwC|D{iwfM-Z{GD*h4cBbwc3qONvQ24QZL) zu2fXmuklyBS_PBX_$GDrBcOB^s5E0_G6&ua_A*Npqk7(7-s*HnEj)Bne)0K9ulv-z#|D_A_V`5)=pBX2GFcjR3X_RZ7q~i~f zQmzPf5i99Jz?!@7gaj@;KjG*<*mc9~(VsC5f0#XQ#`*?*{-l*=%#YG2&1+XIogDNq z-=cXHppT14Q(5g=X2Dd>=xkV+htbQJdRN~ld6z?Ph7)62>6tvNshP4@f&Q_E9Nt(` z%jdSsX5N|G530SDbAVw9-slr0%68Uy=2f(7T{btXIBF>9PQ>s5>Br-svt@z)8gEBe z@|vL0dvnJIn8tnvxl3=+XgWa-ur7auSsaQgXq>sfV~^koExT1$Bnt1qh4~d(kBDBF zT9Xkf=W-qvviJPqws6K@Fr7O%rwrHD{5WU*%39&uIX+=y1Ix_RN7K0Jj!({1#&6-N zp=gUbeXq(x%~2V=vjMYezj$Zj3d}N8oh&)81|yoLYSI`dp850~o+?^Qehf*Z_ZCzv zM|PX(2}VqkE#JJ^*Bo~LAFRjy3x=KnWji6(0dCp#Ld!gE6E>-(BU)tc3t9U`W8D?G zWLxl)w89x6Y{GN`S(U!JS#@b1@?fOXWII??oEn@Dc*NI6MU0$Yb)iS*`Yi}AeDka> z04V`+s#THTmYl#NQ=AHY44S}5ERbpPm>>FkrqxG@YSb>xh03(rb=SA4D-@CDb3vlA z^Uak3HCf~#2_d?u-v-ol(0bOaKisx`?9zD{o6IpE2@My#3{r0C)}o{Hg~Qe%?m8t( zPU`m%ihmIf#eud|Vr6pv8E#d6r0cyxbm)Krf>Oy&cOEyK=s=>fYrN6-;U_vt=KntV zDQ(Cgtfl*}`fgV(o1Ptg$v8`$5{r3z)VT$5gM!(VZ?WJ6m(tz^7ynDo)@Sz$b?QWG zXi>vzEKSX$VFanMxo1kl284K}FKcLWuq%=cr9r9^nKigvz*zH}GlQFe%VZ^tJWC?AKW+oNp>*zy%bkR#E(fmL;O6d|# za0-w$Ux=?zE}G&*OkY*vx2pfU@5yo7kW&t2nCgs|%jb#A;$-LA@NE8+ z8jM#RV%qc?MNX{1Dk&beK2`2!$3Rt^dyUpSmN?{rt;^uU#-{w#C~D2N95lWa3DelL zS^U<02*@%}GQ z2&%n%{`|n>Y!`7GxBW9a9dWUydfLZ-wvDrX8S5_ySu*YOrth-yVa0;(d6|M?pA~@- zC)>`Lqk|s$u$Wlm{jt+HY$NphVc0(1a3~tI9o{G<`LtTM9;o_MhLe*?BN=B5dgfzU zx`I3!wRMbNWN@LzL#iSYc?U=vk6g{Gv>Z*$&R6c4Dq?m9D{7R+9IMhOWmy0J0i#>^ z{{W+_y4zs*PmjdEY_dqBtf6m5wk#>aTfr#RRy{(?r6jD~#O6qo;e|^V;sYHu?3!KS z0PM$=p69XwLxCjARsTF9bqlxK(CcWsIt7E9J{vu)7zEtJ>jE_R29^tLS3g+OvOqL} z74h;Q<#HUrGbu<+VkFi`qVSgH0*y;kB+>?T)FvbvP6Ari#z&ScX&$-?tE)0Rz!{N4AvVZ+TI~LH>Z@opJ)x_o^reU>9o7sW=O6(nSJw_)>XK%>5zpD@6yrm*N#c=Tjd=_`7$ zcBvc6*;^QbO;C!;81>udS+!d|;3J`ft6H7gi(@F{M@)W)hpgBE!u1I8X#~X%+Baey zzck~3;ti@b_eE1c@S=!IN5HJysnIx}kh*Mv6@=Y}*hZLe#L%-88 z$y_@7bTYha+*(qg&vgM;7-#kNh4r&u)UgAuuPw`tvdyE?sUL*2wBI|`=h!9VtT z{@ITlO7pr5_}8{K4SI%(T&JFBw3~hXFeO151QcC`zX1QMlve zX&sB*-*JlMA<2FuW#^38cMNA8-7Z!Ey|cH!h?1b)q#0$eVet&6lUXTTOK21X?OqUV?H%r{i;!NbphYP{!!2Y zy1QDQ@{QERl!sBoL5EEv!N;(O+YNcuPW!9U2O7Cv0~c0$pL%BMG%m9I>&kbdOsO{e z?a8VJ#Jn>`MC^6TOhWERs~Txkm0D#Ip`SPC2`H7WrMCG^ptD6zBYxPTCBv@ritTF3 z&M(NvEl?!k9aZS#t-921@-fR59qmb8&!{%r z{;Fq5Bv^HY`72;u_7f>oL0-GV5Nus9_{dYu9r*yfg13U6=wzHO$dET_`C1#BM;}!@ zXvaqjzpZ7q7QA~=k3L`up%k9L-i1S(fnKd!0cj`;8_zIxMS=_hqobLbG5E~>$J*n7atf$djqF#Bhb7CracssiQ8_pWNgdU{2e*vt&s&D4)U%~6G1 z=OTxs)?=1N<_QvO|03vL-v_>RSvhpI!TN6XF;0!c%Z0kIDEsk>noQ1D`kM8Q%9$NE z$r#8WN%TI>*}%MXPg^MiRLE4*;k~TfXgPVE)`4b2Jc}gQ0GvwhINC9 zcEEe&-IQW}L3n0=w0iT7|9`n^USf1Qq6@tABuSs)|26^CR$UN5f ztjJsVt<>Ed=FtxlOUVG3kwroZ$CTm@fovR39KBoinMEak2X%p4Z{&JDSp7$UmC!y? zNEaMR6QU0izntow*z}Oo&%ku>FC~{@qv+cKm&Y};gn8sE6?SgYWf6A0U5a_^$3DEC zCHn$t<(5$=xK=`p@rDxLLte4?Ev3@;JF<3o>!m<0D? z%UV_S+=i^`%!XpHGrm+F?`NP~VL013s9cUVh?ITrQz`e|HR;2_-}sk%PWUV?J0GgA z(s#E8*o^nyMW39LkAgM|t;QO=@j8RSCsle6B1UyWBZg=5r>t_k?&WXBn0b0dpZoK@ z(p-TXQDRJAt=S=ogU4A5HKEc-*Y6U5LdH7o+z{Ko`3&mIP9fSm?xZM$Cz?;Mv?9!K z*!cE0w=Y8UY}Q4}%*trU>$q@eRbnv#v}hrQn*36#rjRr1S5p7-2iUQsM5{i%jWmVf zg~hA)T8RC+o1dI1^BNdEGV+)&*RM{tO>18cvna*h{L6|2+;gQ`Z_#%i$tRO^68uqA zwjk=%1ym$6`uhYlDl!1mqOK-vYnhW%i3$Qjcuo23jbm&uA5uiB8c6EM7 zDz*t$UHBWAbTAr378iYpd<0>R3ZqsxA^-mE=DHoPOWW%iI0XPGyeZaUl?>wdk+m*u ztLF7mgkL*n);iG5b!G0y+Ki?zUysltyYR+Dc|AS>5l#jLDAaEge|;h`lh*Cd_5sPv z%%sjl*@V8YJ*J~r)3k=fS9~a5+;5ln`*1@$Ch4rMsPM*L}agHG5v1w`GEr_};J_&Ft5=$tB`&P{a zMDyQr_HuRhJwa0FHnau%V>^FixcxpphR`Y;cty+ER{sUEWU@V|_12QztB22NA0G3u z%gMXMRkDg1O;0@iC9_?=(3;INrF-PHUv}T$*ji!B>3*@@lONY4>aK6rR1TI)8*Q1> z3j1)jKu+qUlS2PH{r)od*b;X&R9&O4Jl{c38eS*5G&vA%@xXFb`}E%zjF-eNGT>yO zdWnBwfs;&*bYNT@{wGOk_jfXym?j*(3z`ID7ce}J!b+*0-6DJhepXue_f$@A3WQ%^ z<@XxLE-;iy6tMbAfNDqk$$O9(oa2Xw`su(n$ovlS;Ib5vIQIz>(4E{x51aQXH$Ysp za>1}gDj8+)*C#Wx24Dx)hHX4J_Q^NO{Lbb6CF%4x9A3gYqovtCiM>MKjmDD9M6&)U zM9lL`eYn`;mpsy1nxXUKAW!OUz&oDZu$4Gh+Ne`oz5zc{@1#(=)M=IadLS~%*r%aj zg!tBC$nr5D!meWj+z(cHQ`>Y)qADDBjzjGN+Fi07$qKm%Q3TCYAO%t>a#%$Hg-Vu! z)*ASxOsW9A??Z8@4)kx4Qr9831k34Yhvb?rT7pTJVySrf{k^D^xY%REU^s{z`kq8RDmlY_L+jw zroqAo?<(2ur<)c5Pyapm1u#Z@ql~5-BlSp=ppa^;=(78f8rR7Pqx%mEY5xU84(MU?!qYDn9mfSLKiYk zkXUYXtS+~+Hr5cDTj6-zQXweEXi)AKzbeqw988Y2{}h#)B0bsf;}!BCp~5&%_*AVz zA;_qr-lzCVn&_AC_-VB)4UmR-~wxN7`0N}lN@pCrnBZru&Wnrz|*z3V*f<~IOpViY&E3Ht~gVcYvXtN>q zc|4JEKbxtq@N2w^aoTcNOjxu#Q3F{yR7r3$8Le`WE)x)M8fSV3)gBISw-?>gz~3fx zp6sIHuM*O>6{xF!3kXu;tK*X6Nbc56?Ssw_l<}+L zDWg%lsa#@nhebezGg=W#S9OxAT=-QK~&1-K(VBsxu~EL&Rf z#chSebVZoy3Dkif#HXR943wcV^y5dk)j5e>~BwOW_B9U0@yuPV{alXOpCL{dY zYhUB~X)V09+$zZkNHCqfg+4nb`4-Qee=E1Jephk`F=o#)Kszp;8~Pn|?E_v8AX~%F zzQMY{HGuH&J@HP`F8;)nDlb$8qG#Zv_zD_)uY4vt$m~u{1`NdC2+$iBoJ&kWo$E;` zREKR331fxJKCz~37_$dSWZ$FPk1FR5EX`D+l>3QKClgAC5PK0c2^kR|x>MU~M*D$0 zyQBs2RKl0Nn_M!w{nOe4&i04J|5{frM67a&|NAC4{xjYASPL1xHr;JB)>iu1WOG)pjg!8*Zj(dYIEqjz#-55zKhN%PN(@ z$l8|pdOg>2myIt7E52Z%6h9Mre7E?Ix-`!2{&Np~>Gxfvax+ewSxIrr{FN8pmk6~% z@86l?gsX1UNs!8|TPliDDdZ z=ofCqzs5%}4iJq+U1CKlpjF&W&RqvAGexpF;vckILD-5d5or={a%tb!%)3~%*Q%J-Kl^VxtTBlnO$L88j|J*{9 zJ=U&qpvGHDAkn{jIAdtVHIR(|XutJSxrcIojX%mgPTC>W`KWp>|EPOA7sf)V>u;is zy!&(tQbQ|kRVzmKqGO$~gOIaP=jB`09;zk$3}PY`Qp*mjawX;@!@lkE1p)H=ZG541 z6el(FxSTi2XtF{M97k@LnYV)y1^5d%fuaT-;_^S!G5{v1Fq;xtIPJuqKM0UVT>^AA zNpaes{s7L;o{2?4C#Wnn$jtP`bx_~BJZa=T^tsK2jHIrp{( zV-%6hPmK}&{bfoCKITNy+hgnqpH_y<=C)mZg??Y@X@6-XI75it@6eeVMg;U+t*M-i ze^X6vot`QHZOpS1mK8}+oIq)_>-87x8jf9i3 z?9w~qfgT+dpTjvL*W{Os*rUpZ90d=>(unB_UG=F)4$1ZGycoaS1|y&Pi9DqWQ2b)< z7^*XD@ZMhH^6)~qACc5$$4`|1*?_AEHY3<8S|GER-t9op#bt`#vpbQ$*{@4Vm# z6i10A`2||rrJsiA`xQd599sJlXo>;^p?@d=Q@1K11BAh<_MG>QKpn61+YACeWm z_G z7cEwD+PViVtzqijAUf|UrVrF3>cPsiem&7I_2cm03t$g!qgJA|2h=gOQBYK@z z)f!6A|G6B``c@E8uKQq;f%%iTJPH1jqkS?$%#M_(c?w;Lr}r71tqLvH{IU3yEAyzb z(b)&YB6fxr+y0;U{C;c-Fy=IjCB=P925@hjnxv1_ zo=Z}OqXsa!ET!J$1$4F-!Wq;-0a#bpAYO^AB(`kZEhk$OubVotnR^jR^GiXnX|M=z z2hfTxuxc=*S1m+;AAMa_#|Ty>$7b~{k&nRos={bte7F3lp)iDDQbY)UwA8_RvQd$X z&BT}w`UalVD4k_Z8yf;UdWy%#2km)0t9-l1*mBhj*Ve-C$6vH`d=S8$-BZ$o-M!D` zPM*IeZ-zE{fv}`Y{;|JYH`EzX%rO@!=d!))Zf9WsD3tvNu5mFRxKK^d`_hAtq7~c+ zi`vr+eDvQ=3%u2?Ch>lJdtnBk3Zh6SCUIuSh{vpP|BdT~LJu{uJFLe5x=yAdng69y zK9k1{wVuKn3$zKGVp@kzkrGn}GRqe6pS%C>8{bTRp9UrOzQ8c7wKupdyk@nvY!01S zcit$>z)3mioprWQkw zeZ;iB*PoU~;&b`K2Es5c8;x4y9M+_kyo$0{rKx|QnLoQ|PV-=Bfex__wuva=77(cH z32x*jfRO0#wtZ$G1_Umxkg13G?wCfSzrmS^(TF#s<49r8cd!P}M2R9x1fzFw$9C!1 z1OYnBmZFf1n%-ecVB3 zdyC4k=RsiwUbS2hbKW$++D$#{#V1lm7~NrmALag#{eIG7)Pn9_L%7^Bje6{m0JzaK%b~Y9n6(XR-VirJbSMSdkZRaKWfSy<1f4SGFkE=t;s6B z4x25nzRqt+@7`fu8lBPZ#U}{Y6~HgDD;pm~SQRS>o2T zLXRHn_Z&$e%0E+UNxgDvvOx7M{^EcA)m`g-l-m?7F5*~Z4aG(94T{seJJQTlCk>y*8H8E*K+{<+3TncHgM;s}_@awn$@|YXV0CS& zJl~-(Z_QF8=F}dKgZ5|niRzyD4op>Oe(Tt77uIm+D5d{+??J|Y=l=u~OX;@-Dud(; zyYjojt-DBT0|^BR%MHPWa>ieXT78LQ2|cn)K%6_WOoYBG`G2^3&xfY6{)<<~5u`>$ zq?1txklv)n@1m+iGQCmq7yt3J?; z7bPKI!l(R2y7PNQp%1fP=WO?0P!z^$Et(EWHYtcR=R(#{fQZ;HVV$Pcoo&vInqyL+UN23V-tE}r*lBD1A82$&W z{(`2928yTp>=dyQ20-nOI?Ah%=RLD1zXr7V0(t3}9iRI{hoJUwzE<#mk?SCnJfA6- z?PccnO{Mz1Wq$Jo4&S8KGSH~I0_%E=7hDn|*Fu##MH)Z&hG&=A=uT~6(#`}FgK)}( zQN35GGi|gh!P!f>PyY`XAzu6NJl1nzWkKj#iXeLKHO~Vi<{F5RM$qybJC-Y@x&4dt zPW+<24SC?GQKI)!=jFMoi?_cff*{UT6z8pp!>g#{)NF5Z79V~wma+7L{^He!P+jv* zWK`2d*e~u~S8iRXLI$#M(~G2|(f`g=`{L5KEZ>;9Cfw0}ehb~T{+pd#_{D#BwXECh z*1e`BsJT#JSG{Svg2=fOQFJob&!MX5wrOTDYQ)dZJxR}(t zyVi{}g5!_z>IB%TJ1ImHyG%o-E7&Cb4ZC&WQjn{5?fJD6)cf#)d8W>1{)w!*G11iO z><5uAwv=2dLLM#K?iFui+kDI4Hd(XYio5fpa*(EIt}tk4T;?2g3RCA2=66Q_YSzI= zUwy~3u55o)Z@466gO7DB365Ydwrs2?@^FWcr2m0^p$qBtO-}z}n!gSl){)!)OrBXO zM_}4!_TqL4%@ZS{66K0AjxXLti(nL?INrk3?Y#Ji#|ZU2bmawK$Mh`C)_REG-O;)x zzk5u=MhtJnb0CYtg*d6Sx@nZD03&)}Y2i0mU!*5AdFZq7x~6930UJ5SoLW>`FHIoU zXL$n^5aH73p;LXvJS$se0?mRr&!E9LUyazl*?qh^*G7-Mef2t=m`L>` zuO-s@V@E^tPjz7SO6&7|e?Cz9v&wH8Q^Y2>imr!lo$>t7k}iV_!+~D0bu$l^<<9_Z zEo8t&F>!b3D6k?R=l-NJuRlfffTa%AuWHNbIkx?%9hHRswMSoQ2|HyG@q*{p(IRgN zC>}XI8Y?xx^%LzkS|px%G1cKD{un&%Jg5C*de8CUt|SwXK+IiPQcPZODhe_lEY`M|!9P|II(!K3lJuDJM`?rlLdKYL z!6F*u#zgRi|2NPYS%i65d@)u|YdjY<)eH4IB~^%29PvtSMueYS+ayiHxYhP4Q}m0A zuYFjHZOe=jnhT$v{FAdT0o~es2g|QV^Qe3J;7nhr2V@60`5<2KQJz#0vr?WkgWbKI zPgE74WC>gUYekBlAe$V4f5(K{1KDw&6=C0at%s_MbeD%*uUBp>2rdhM#SXFXCE=3lrx+9U8TA;7MR|pV zZAM?r4oau6GM65Jo7W!OByFdX=qjN1d`}GaOva-D$v@Zu!cM1bft9?+E(zw z#~0}kG~$>GyWq!-TgQaauzc?Cok$6scOHI6vVslnVikNos2zdKQWJnl^qDH9t>#0| zZa1x0Y*_x6px7JF0A;d zr9)5vwBPDkU+J%_HqE!IdW?l$5IUD0l8xgQCB*~L5}2?N zLxHgmFNcY$I>*bE2*b-AUrc*yh3($52uJVku>fnkI-+#H@@h7kv0#|W#pTlUn(XV) z`-Gv;JfVNt1*(46!n{bxA*|ueH_t_m-HDTA&Yn*pUJs>ki4zzO&rrJ{yuCV4@Ns-J z_F60Uw}CId`kKG9-5L5CkkIyoGdwJD=$t<=vNS<*Y}s#tpg7XKo{F@{<;06=Q!RxrFtA| zewqI3@kI%Cpne(4JCVc0Nf4NS%&5bn4<5aqf33bglO7nQ)xK@-dOsrgc?7%l-hD;k z_mujbdRYH7I#k6mwqNBO%fdV3!cUrE!eZ)zQcQ(f;o&E7Oj##GF0KCs0hrJ4_j&YA zrg+UfAfAxEnXfgJZkRBib>e}v1g}S_q5MdTG5cM47~l4QYwaPbB2P^=t9d`uF8;7v z;K!gUZP(f};I&28p|KsYvs;$sBO!?uDQzrsI#w9ZN+>t%PKKR(-By6~=O1!AibY2> zitgerMT?O}aV@x1T1XLjk5ETIO)|$RV{U|Q8O;+l!A&O$lw64tr{F7PTS_BMNYf$* zs9{9Xd0@Eq>neITQR}Y{*8vPwQWRw97p3Uw2}38?`x&8@?>({^ypOJf%|d798@G%h zcsBg_N9V$`LdrSm7D1{^H;W`y_s1GJNB5-nxsMvXu~m3kU(7f1$~i<)6vPx5 zeT(yzuiBYk6d^}cW|P~#_u*5?d$E$Ff$J59%}DK*DKP@6euRA4%tFez)L#)<7QXE% zr}FM1x(dQG-ri!6TgGxtozi~VX2#=EmB#LhW(!Yq$CAD;s5Td!fiFX6x?@kwB!As0 z4y+JOZ}uuYP#p=(%O1n4FR7Vi=iykY;b2^Og)=p|8Z$_dhDMgM8ZAOB7Q-y27#1Bq zt1-_GLipK|e(4tqHuA;6$Z(ldQcY@g+R){I*e=Ns>55>hFNJD#{lQng;v=O+Dt1rA zA6!xyl7tRoJH9Ng$8PN*jpN%>*)MGPkv$5Cdi@7-yT@8C@O=AhSNF(=(>vrj=v{

      st&Kgg>?>hQ@I|OW2hyO!Ft|g7vFj~?XMk=3`P(y zizEDI+?x(lN~e6Gu48rr@fZI$bqrrx_{z&qA^d{>YxfaCTX=>mv5tW>MU^n|!7BlK z>0sa6qoAGuwGey(c-!ze60U$W!v6{;QE<*oCRFzE;$u^r{t^C(tOu`fsK0>wuOsij z`fzi*l0@%Hp6of{W7d3H$}QnSWQz$kxw9Ah`kgw<&ebFNX+A2V$n zHDygv@>nmbb-i?-m(;oKvkK|aPf)i#;6WQvR!`&U>FDr_1Mdmqu zC$wjdx>Hi!8|(}RRPzqgpeZ7#GdF}KiT8thh1ZM@-~)vv!{|kcArx#-=gN|D{~1Vj z`C(87h`v3j#hcz08ZrB zphIpYzR6@x?i(@TA>8X++3pk912mX|DxYFK-I4eB^A+|akhm{}b%~n63X1to4tIk& z?p!NALX}y@;XRe$tD#HanV%4x zEM0y~<}KZXFXa~c=o7x1B@fAVGB;bCAFK%sboqmB-5%~*A zxd^Ke?k##o00QWMOJ0N40M8&xMc?NEZm}>djV9I&uY?;R&NeQ5F#7|=s@x}%7bY^W zu+?szYOr#2(U3v`v*v6@^}E8=CnzT%JhGYo4JU->iHa*wh!xxS?{^}{Y)+j=wR3+A zRK(u*UX4O(n~NtoLa^Ufp9*a^+i%WCNfY`f3cvIt-F#>}wilLQ_8N`{)1R;|a$;59 znvp&Ruii=^G5OWIbtQu8tf3IEoKY)|v9foVceC%Er@FkaheV0DiCoIk9`P~4%Zr3( zi%61i|HK9)x)COFNq5A$t6{tnkzRfVTvfc+8ytj0Npnn%y*4igPpnp|$2(ydo|Q6# zTIbYU5ykn{1V+m$aq`k*IO$(Fr!pI>D*N##SP7z+3 znBeP%L|h3LNB?x#H+ zcW_x@xnhbPWCA=jo*AT-gl+<0Q~=z#p)lCEXU+aOx9*(6*PBVRaM|LSr(YtzzXL3@ zN<*-+C7!%~W=31o8+Rs#^_+5_-_qk?IUfIM4$7O>AEek~52mq=g5iG*K%<0vxK~@K z-9n@q9=+Q^I3k`RDk6`8#nA3{-$vGZ@am2MD95$I*$)#XpMCBo@+(zvZftrdHczaH zL;j2N^E#axe_#-Wd&n;tdAhhF7$Qnvqcv_0>}9e;GC468F&*_mCwVQv*y@TEIo!2l z`R?$`^avm?;bWi62wK*m2#;t8S+G?X$e|@j4G+*I(x}9TIzyq}MN-K(BVlf`yLE-j zy#bi@D}k}fYoS+*U05#|ms)Y-w(78%aQ+oR9Y0RAEyw(BD0jGyYvNV!K}jK_=0p&u zeP8%)30{d?nM*v(E)j;Y#797l9XXNG?x4khBlE57i@<^r?B2n%XyMOr(iQO=U8pQ-}6-N_+I#nZLJ|{(+(~duNB74hyqb%0q z0@>2rHNyFE%sk%U#;4v9zIH(QZZ14XfH0Fv(7wyfVH&16xZ_gHN0!0)AV^UV!;D!$ zouLNg>xVb$HRy14&@iLMzG%q+M>&fu_YYx&2_oPEEuq79`-zdXg}p3zJBCd=@By_a zp^|h;tOjNip$nwLR6mOPK~o13su{_i=Nn}PXkoLgfm52uInnW^(+oRcBXyk?jX#6T z6YETwH*k2myu#@p@1;ZgZF1|R)Q#0`%ee}wg`eE&NW&qojd-*1ZT%jk(6y6ERW!6wE8xYBW){?t#ppVWF0p zmwWt@b*Hbt=0NwD_VAE-!g1#E5_X8G*lNmH#@pxdUQduuQKBUI_`y!RG}6aCZcwxQ z`YPxkWV=zbtIiciXAO@Pn+_hz+l%4^=Z?h8o-w7QH~Exs;B6$4{L&U1NL+ii<4jnD zhO7r6f_H}aC&<0gE7aaf1nkpM!O^58)pevX_(X7;314)>?3TT9K7~>yXh#kn8JH6P z2ClLhoS}=vC@@)H&bxi4|7tTX&arFel_Sp2PEz3>KsLoG!l)326=%5jVrJXFEPbHnHl+5hbU z4bf{UfjgE?JLkI7ktS!?Y3t#EJJL&dITO56CwPxanCi=`P#ln8zJjVe79ZKUTUOPU z&GwNvES+YJZjyplpneL7>4zM0l5U-0|jxZ^?`_Ut64 zR7%nV(a>j;flx;D#nY^}s=G~tNIVh@=Nm`_fGCabJiPQ{T;GNl00JR%qz!19cOiU9 z32~lZ+wm^}{`Qq0ILf1C;8DRe9C;2q2+XkW&>~cB>C&=HFXSD`#T$kcg??w!?9xw= zwT!Fmnb!;iQFMtCSGN7Z49-_S>8Sj@nS6XVYKUu6W`|Z^I+)44^tE0l9ZpW=W%3$# ztnznG8R?8H_nhPj6He}^$^{&ap&tqbbNunsuMG z*D^Zx3O_#b{I8?sz+fi%c*(grk%3W$xq-HC0TZd)(bXbEksi-P{W_QoW8FA~=_{%r zKcSefFg-gurlZ%JHn?PEqic`;tk`0`@WR{T5s@yedWCvduN-qK;%tKRwL_f;r>PFt zt6dClUavTLez=CGxR@8O+czCP6JP&4;n?F3b1u0NS9i0rj+DF4P8MI!4}CG(zxi*^w_?>j z|GoGhWN(?43gt{sW+LT9_}v<@o;TjHeMTg?;|NYME9E+|BqiiNNB=km@i6`jblAKf z`ZoAdeAI?tr!|eYNQ6?;9)x@XZ+soT_m)YERGPa7rY`)kznrb=p%X$gpn2jlo{t8% zdSCss%4XFIKdF{8ZZdzKVO%g`6>MVCKw>#xth2T2v|Pl#!g*%uQzlGLXJAXt!z{;N7wEh)LzU7awN_Zar16pJP{$IBGqRsTg=@h5 zb|29r&>7Z=>u%gix9or{+^awR)wtrj`iSsqoSRKM@Hzk1 ztzBxhJ*DH`(iO}XN(Vp?<_o`Cj7&1edJOjfuZ}kG@{&v5mz!XYkAcNG+!mE)Jp>t@ zgPYJ}*MCO_KIE^iDE}}Yq~(&2+IdCYP&9n3%^%gRX_w-d;uiEm=1siiEvf z`qtnupPEvg&U{`{5U3H|7>C*V!jmHIn{HZ{tMH@2OQyysnRSx~wIR=hyzzY0@xLf( zX$XUTZW69jZrkuhrL7Pke;xK1R5Y*|sXR95dnM*Y!mi}Smz(R7ZuA!xyKwL4oqEz}r@s42nHs^xM%i5K;dbX=*zXluzK7bg ztfFNvLtP1q_xZ%|+~~W7E^n+XiG5C?Dh-Mrn#bG0G@xLP7Ugjn)WJ*!zxG^A!%2t7 z$7iyJp0h)QoQS^GDzw~f_VWtWyxb_{Y5hXVUDi~2w32RYooC@k4`@s5;IV4w-aDgO zh`@|2wM>WaXo3&7&Vn{VUv~ga5+C~ry+YqmS=b{`KO8GI7M&A9UF3~P)+Zs#hx`q! z9J+A|dsyUD4?egW0aJJyS^HtpV|@Qxl!V_RN8PhD7OVLl5i**DQd{Z4(hSsZv6do;Voaj6_ z(@?hJl@p4r3C@UL)(OSU*C)i5mY=nD|A@I*rR+jE_mIh$u5)N?u)r+te$H-{HLJ*K zAeSwgl*i===DyOh3RVg!-DcO`G;b__PabiluGP6wZtYmdP;dE&?zs$fcCO#TZnUo4 zoMaGXA}bZ~Fk#;3uMnX{3?-4|;^Ea^uU^mBq{Y^NtDl&OHwW01$P*Q(sw{T<$x1E$ z){a-5#}<`W`jt*~=l=$ae)nR`c-k^WiS>6yVjeqY9jVgb;93LR8*-b_33F+1e(<A)A{$k12a*0R3kX$2CNh{V*Mkm2?f6_ zg(?o(ogZEx*qnmQNH4e_FMW-Y!InVMj$%3es&c{m{1JqH3$*7x)fsW50V`cRHy-N+ z-ME!xeaMROH6J}GUy`Cz%TBqmlSs;!%qEUkIhyhPh$=xnuFB;#h|@^zXU0U2@pkQ# z?_Th&3r)Z>%tWlpDXk3Mccv3Ug}4LDErl`PKH37ewxE4GkjSs03-g#GP(=HjV`@~ zJTi;}23S?jw0f;2;9p4=K~mU8d`oPTPr8evti81LJx+{w!l9nUPjXf(DiskHaq0

      &j4FxmeameodmK>J}>ECWYy}q_# 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

      *;cF1_xF!kem?o`%uU7G4X|oqQqs}?V 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

      Fvl5U^~k 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 literal 0 HcmV?d00001 From 55f563bed495e68f777a302c4b92c4b9e1e9287e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 15 May 2019 17:39:19 +0200 Subject: [PATCH 0519/1786] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6e43cfcf2..658fcd410 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ You can obtain BULL from Maven Central: **The project provides two different builds**, one compatible with `jdk 8` (or above) and one with `jdk 11` or above. -In case you need to integrate it in a `jdk 8` (or above project) please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) file or to [CHANGELOG](CHANGELOG.md) otherwise . +In case you need to integrate it in a `jdk 8` (or above project) please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) file or to [CHANGELOG](CHANGELOG.md) otherwise. ## Maven build From dc9e56611c190a4eef2c4bea1bc49b80be151d59 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 16 May 2019 10:21:15 +0200 Subject: [PATCH 0520/1786] Fixed typos in readme file --- README.md | 13 +++++++------ docs/site/markdown/transformer/samples.md | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 658fcd410..34e2d9b76 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); ### Different field names copy: -From class and To class with custom annotation usage and different field names: +From class and To class with different field names: ~~~Java public class FromBean { public class ToBean { @@ -311,7 +311,7 @@ ToBean toBean = beanUtils.getTransformer() ### Map a primitive type field in the source object into a nested object: -This example shows of to map a primitive field into a nested object into the destination one. +This example shows how to map a primitive field into a nested object into the destination one. Given: @@ -341,7 +341,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on all fields matching with the given one: -This example shows of a lambda transformation function can be applied on all fields matching with the given one independently from their position. +This example shows how a lambda transformation function can be applied on all fields matching with the given one independently from their position. Given: @@ -364,7 +364,8 @@ public class FromSubBean { public class ToSubBe // getters... // getters... } } ~~~ -Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +Assuming that the lambda transformation function should be applied only to the field: `name` contained in the `ToSubBean` object, the transformation function has to be defined + as follow: ~~~Java FieldTransformer nameTransformer = new FieldTransformer<>("name", StringUtils::capitalize); @@ -467,8 +468,8 @@ where `nestedObject` is the name of the field in the destination object. This feature allows to **transform an object keeping the data from different sources**. To better explain this function let's assume that the `ToBean` (defined above) should be transformed as follow: -- `name` field value has be taken from the `FromBean` object -- `nestedObject` field value has be taken from the `FromBean2` object +- `name` field value has been taken from the `FromBean` object +- `nestedObject` field value has been taken from the `FromBean2` object the objective can be reached by doing: ~~~Java diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 75e4c807e..a632d92f0 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -27,7 +27,7 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); ### Different field names copy: -From class and To class with custom annotation usage and different field names: +From class and To class with different field names: ~~~Java public class FromBean { public class ToBean { @@ -235,7 +235,7 @@ ToBean toBean = beanUtils.getTransformer() ### Map a primitive type field in the source object into a nested object: -This example shows of to map a primitive field into a nested object into the destination one. +This example shows how to map a primitive field into a nested object into the destination one. Given: @@ -265,7 +265,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on all fields matching with the given one: -This example shows of a lambda transformation function can be applied on all fields matching with the given one independently from their position. +This example shows how a lambda transformation function can be applied on all fields matching with the given one independently from their position. Given: From 1711659ea6b85fd5fc2cbf6aae03c88458ac7509 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 17 May 2019 22:20:07 +0200 Subject: [PATCH 0521/1786] Typo fix --- .../beans/transformer/ImmutableObjectTransformationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index b0cd509e6..e03ab5704 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -319,7 +319,7 @@ public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String te * @throws CloneNotSupportedException if the clone fails */ @DataProvider(parallel = true) - private Object[][] dataCAdvancedFieldsCopyTesting() throws CloneNotSupportedException { + private Object[][] dataAdvancedFieldsCopyTesting() throws CloneNotSupportedException { FromFooAdvFields emptyOptionalSourceObject = fromFooAdvFields.clone(); emptyOptionalSourceObject.setName(Optional.empty()); return new Object[][] { From e1922db5310be1e34961cc6932108f87758e5166 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 17 May 2019 23:39:00 +0200 Subject: [PATCH 0522/1786] - Updated dependencies - Disabled maven licence plugin on "fast" profile --- pom.xml | 891 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 454 insertions(+), 437 deletions(-) diff --git a/pom.xml b/pom.xml index 6b6ddaeb8..ec20fa1f2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,445 +1,462 @@ - - 4.0.0 - BULL - Bean Utils Light Library - com.hotels.beans - bean-utils-library - https://github.com/HotelsDotCom/bull - 1.4.1-SNAPSHOT - jar - 2019 - - This BeanUtils library is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and - incredibly fast. It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. - + + 4.0.0 + BULL - Bean Utils Light Library + com.hotels.beans + bean-utils-library + https://github.com/HotelsDotCom/bull + 1.4.1-SNAPSHOT + jar + 2019 + + This BeanUtils library is a Java Bean to Java Bean transformer that recursively copies data from one object to + another, it is generic, flexible, reusable, configurable and + incredibly fast. It's the only library able to transform Mutable, Immutable and Mixed bean without any custom + configuration. + - - com.hotels - hotels-oss-parent - 4.0.1 - + + com.hotels + hotels-oss-parent + 4.0.1 + - - UTF-8 - UTF-8 - 11 - ${jdk.version} - ${jdk.version} - 3.11.0 - 2.1.3.RELEASE - 1.18.4 - 3.8.1 - 0.11 - 2.8.5 - 6.14.3 - - 2.0.1.Final - 6.0.14.Final - 1.7.25 - 3.0.0 - 2.2.6 - - 0.8.2 - 0.85 - 0.85 - 0.85 - 0.85 - 0.85 - 0.85 - - 3.2.0 - 0.12 - github - + + UTF-8 + UTF-8 + 11 + ${jdk.version} + ${jdk.version} + 3.12.0 + 2.1.5.RELEASE + 1.18.8 + 3.9 + 0.11 + 2.8.5 + 6.14.3 + + 2.0.1.Final + 6.0.16.Final + 1.7.26 + 3.0.0 + 2.2.6 + + 0.8.2 + 0.85 + 0.85 + 0.85 + 0.85 + 0.85 + 0.85 + + 3.3.2 + 0.12 + github + - - - scm:git:git@github.com:HotelsDotCom/bull.git - scm:git:git@github.com:HotelsDotCom/bull.git - https://github.com/HotelsDotCom/bull - HEAD - - - - sonatype-nexus-snapshot - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - + + + scm:git:git@github.com:HotelsDotCom/bull.git + scm:git:git@github.com:HotelsDotCom/bull.git + https://github.com/HotelsDotCom/bull + HEAD + + + + sonatype-nexus-snapshot + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + - - - org.projectlombok - lombok - ${lombok.version} - provided - - - org.apache.commons - commons-lang3 - ${apache.commons-lang3.version} - - - - javax.validation - validation-api - ${validation-api.version} - - - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish.web - javax.el - ${glassfish.javax.el.version} - - - org.hibernate.validator - hibernate-validator - ${hibernate-validator.version} - - - - org.springframework.boot - spring-boot-starter-test - ${spring-boot.version} - test - - - org.slf4j - slf4j-api - ${slf4j-api.version} - test - - - com.shazam - shazamcrest - ${shazamcrest.version} - test - - - com.google.code.gson - gson - ${gson.version} - test - - - org.testng - testng - ${testng.version} - test - - + + + org.projectlombok + lombok + ${lombok.version} + provided + + + org.apache.commons + commons-lang3 + ${apache.commons-lang3.version} + + + + javax.validation + validation-api + ${validation-api.version} + + + javax.el + javax.el-api + ${javax.el-api.version} + + + org.glassfish.web + javax.el + ${glassfish.javax.el.version} + + + org.hibernate.validator + hibernate-validator + ${hibernate-validator.version} + + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + + + org.slf4j + slf4j-api + ${slf4j-api.version} + test + + + com.shazam + shazamcrest + ${shazamcrest.version} + test + + + com.google.code.gson + gson + ${gson.version} + test + + + org.testng + testng + ${testng.version} + test + + - - - - full - - true - - - false - true - false - true - false - - - - relaxed - - true - false - true - true - false - - - - fast - - true - false - true - true - true - - - - - release - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven.gpg.plugin.version} - - - sign-artifacts - verify - - sign - - - - - - - - + + + + full + + true + + + false + true + false + true + false + + + + relaxed + + true + false + true + true + false + + + + fast + + true + false + true + true + true + + + + + com.mycila + license-maven-plugin + + + none + + + + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven.gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + + + + + + - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven.compiler.plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - true - true - - - - org.apache.maven.plugins - maven-jar-plugin - ${maven.jar.plugin.version} - - - **/config/** - **/logback*.xml - **/banner.txt - **/*.yml - **/stats/** - - - - - org.apache.maven.plugins - maven-source-plugin - ${maven.source.plugin.version} - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven.javadoc.plugin.version} - - ${javadoc.skip} - - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${maven.checkstyle.plugin.version} - - - validate - validate - - config/checkstyle/rules.xml - config/checkstyle/suppression.xml - UTF-8 - true - true - ${checkstyle.check.skip} - ${checkstyle.includeTestSourceDirectory} - - - check - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.surefire.plugin.version} - - false - - - - org.jacoco - jacoco-maven-plugin - ${jacoco.version} - - - - prepare-agent - - - - report - prepare-package - - report - - - - jacoco-check - - check - - - ${jacoco.check.skip} - - com/hotels/beans/** - - - **/Test*.* - **/*Test.* - **/*Application.* - com/hotels/beans/model/** - com/hotels/beans/error/** - com/hotels/beans/annotation/** - - - - PACKAGE - - - COMPLEXITY - COVEREDRATIO - ${jacoco.complexityRatio} - - - CLASS - COVEREDRATIO - ${jacoco.classRatio} - - - METHOD - COVEREDRATIO - ${jacoco.methodRatio} - - - BRANCH - COVEREDRATIO - ${jacoco.branchRatio} - - - LINE - COVEREDRATIO - ${jacoco.lineRatio} - - - INSTRUCTION - COVEREDRATIO - ${jacoco.instructionRatio} - - - - - - - - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura.maven.plugin.version} - - false - true - - - - none - - - - - - org.apache.maven.plugins - maven-pmd-plugin - ${maven.pmd.plugin.version} - - ${jdk.version} - true - false - false - false - java - ${pmd.check.skip} - - - - process-sources - - check - - - - - - - org.apache.maven.plugins - maven-site-plugin - ${maven.site.plugin.version} - - ${project.basedir}/docs/site - true - - - - org.apache.maven.wagon - wagon-ssh - ${wagon-ssh.version} - - - - - com.github.github - site-maven-plugin - ${github.site.maven.plugin.version} - - Creating site for ${project.artifactId} ${project.version} - - - - - site - - site - - - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - public - - - - + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + true + true + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + **/config/** + **/logback*.xml + **/banner.txt + **/*.yml + **/stats/** + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven.source.plugin.version} + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + ${javadoc.skip} + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven.checkstyle.plugin.version} + + + validate + validate + + config/checkstyle/rules.xml + config/checkstyle/suppression.xml + UTF-8 + true + true + ${checkstyle.check.skip} + ${checkstyle.includeTestSourceDirectory} + + + + check + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.plugin.version} + + false + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + + prepare-agent + + + + report + prepare-package + + report + + + + jacoco-check + + check + + + ${jacoco.check.skip} + + com/hotels/beans/** + + + **/Test*.* + **/*Test.* + **/*Application.* + com/hotels/beans/model/** + com/hotels/beans/error/** + com/hotels/beans/annotation/** + + + + PACKAGE + + + COMPLEXITY + COVEREDRATIO + ${jacoco.complexityRatio} + + + CLASS + COVEREDRATIO + ${jacoco.classRatio} + + + METHOD + COVEREDRATIO + ${jacoco.methodRatio} + + + BRANCH + COVEREDRATIO + ${jacoco.branchRatio} + + + LINE + COVEREDRATIO + ${jacoco.lineRatio} + + + INSTRUCTION + COVEREDRATIO + ${jacoco.instructionRatio} + + + + + + + + + + org.codehaus.mojo + cobertura-maven-plugin + ${cobertura.maven.plugin.version} + + false + true + + + + none + + + + + + org.apache.maven.plugins + maven-pmd-plugin + ${maven.pmd.plugin.version} + + ${jdk.version} + true + false + false + false + java + ${pmd.check.skip} + + + + process-sources + + check + + + + + + + org.apache.maven.plugins + maven-site-plugin + ${maven.site.plugin.version} + + ${project.basedir}/docs/site + true + + + + org.apache.maven.wagon + wagon-ssh + ${wagon-ssh.version} + + + + + com.github.github + site-maven-plugin + ${github.site.maven.plugin.version} + + Creating site for ${project.artifactId} ${project.version} + + + + + site + + site + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + public + + + + From 431b29ce699de37845040c50810dee12b75b21cb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 17 May 2019 23:55:26 +0200 Subject: [PATCH 0523/1786] Removed isSyntethic check for special type discovr --- src/main/java/com/hotels/beans/utils/ClassUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/src/main/java/com/hotels/beans/utils/ClassUtils.java index ba942a4c7..f6c69ec13 100644 --- a/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -159,7 +159,7 @@ public boolean isSpecialType(final Class clazz) { final String cacheKey = "isSpecial-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || Temporal.class.isAssignableFrom(clazz) - || clazz.isSynthetic() || clazz.isAnonymousClass(); + || clazz.isSynthetic(); CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); From fe8352dc33dd89db83ecc379bed2414cbad1dfe6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 00:01:48 +0200 Subject: [PATCH 0524/1786] Fixed data provider name --- .../beans/transformer/ImmutableObjectTransformationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index e03ab5704..39e1a51cb 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -291,7 +291,7 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { * @param targetObjectClass the target object class * @param isNameFieldEmpty true if the name field should contain a value, false otherwise */ - @Test(dataProvider = "dataCAdvancedFieldsCopyTesting") + @Test(dataProvider = "dataAdvancedFieldsCopyTesting") public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String testCaseDescription, final FromFooAdvFields sourceObject, final Class targetObjectClass, final boolean isNameFieldEmpty) { //GIVEN From 79b85de5ecc6f74c9b70c5f6aea2b7e2dcfd118d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 09:52:38 +0200 Subject: [PATCH 0525/1786] Removed not needed null check --- .../java/com/hotels/beans/utils/ReflectionUtils.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index e3c9f7237..111e4b8f7 100644 --- a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -21,7 +21,6 @@ import static java.lang.invoke.MethodHandles.privateLookupIn; import static java.lang.invoke.MethodType.methodType; import static java.lang.reflect.Modifier.isPublic; -import static java.util.Objects.isNull; import static org.apache.commons.lang3.StringUtils.capitalize; @@ -404,13 +403,12 @@ public Class getGenericFieldType(final Field field) { */ public MapType getMapGenericType(final Type fieldType, final String declaringClass, final String fieldName) { final Class fieldClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); - if (isNull(fieldClass) || !Map.class.isAssignableFrom(fieldClass)) { - throw new IllegalArgumentException( - "Type for object: " + fieldName + " is invalid. " - + "It cannot be assigned from: " + Map.class.getName() + "."); - } final String cacheKey = "MapGenericFieldType-" + fieldClass.getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, MapType.class).orElseGet(() -> { + if (!Map.class.isAssignableFrom(fieldClass)) { + throw new IllegalArgumentException("Type for object: " + fieldName + " is invalid. " + + "It cannot be assigned from: " + Map.class.getName() + "."); + } final ParameterizedType genericType = (ParameterizedType) fieldType; final MapElemType keyType = getMapElemType(genericType.getActualTypeArguments()[0], declaringClass, fieldName); final MapElemType elemType = getMapElemType(genericType.getActualTypeArguments()[1], declaringClass, fieldName); From 6c28b488f47fa2f9de192a76205dcf956b36303b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 09:59:35 +0200 Subject: [PATCH 0526/1786] Removed setValidationDisabled method as was deprecated --- .../beans/transformer/AbstractTransformer.java | 9 --------- .../com/hotels/beans/transformer/Transformer.java | 9 --------- .../hotels/beans/transformer/TransformerTest.java | 15 --------------- 3 files changed, 33 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 2c85e8ab2..2ba40468c 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -159,15 +159,6 @@ public Transformer setValidationEnabled(final boolean validationEnabled) { return this; } - /** - * {@inheritDoc} - */ - @Override - public Transformer setValidationDisabled(final boolean validationDisabled) { - settings.setValidationEnabled(!validationDisabled); - return this; - } - /** * {@inheritDoc} */ diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/src/main/java/com/hotels/beans/transformer/Transformer.java index 61754559b..56e2fa9df 100644 --- a/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -106,15 +106,6 @@ public interface Transformer { */ Transformer setValidationEnabled(boolean validationEnabled); - /** - * It allows to disable the object validation. - * @param validationDisabled if true the validation is skipped. - * @return the {@link Transformer} instance - * @deprecated the bean validation is disabled by default since version: 1.4.0. To enable it use {@code setValidationEnabled}. This method will be removed in version 1.4.1 - */ - @Deprecated(since = "1.4.0", forRemoval = true) - Transformer setValidationDisabled(boolean validationDisabled); - /** * Allows to specify all the fields for which the transformation have to be skipped. * @param fieldName the destination object's field(s) name that have to be skipped diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 5755cdcf5..5f5f54c92 100644 --- a/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -157,19 +157,4 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro //WHEN getSourceFieldValueMethod.invoke(underTest, null, null, null, false); } - - /** - * Test that the method: {@code setValidationDisabled} works properly. - */ - @Test - public void testSetValidationDisabledWorksProperly() { - //GIVEN - - //WHEN - underTest.setValidationDisabled(false); - - //THEN - assertTrue(underTest.settings.isValidationEnabled()); - underTest.setValidationDisabled(true); - } } From 29fed48a8a77f0740dd9e6ec0afbe3233eabe768 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:01:59 +0200 Subject: [PATCH 0527/1786] updated changelog --- CHANGELOG-JDK8.md | 5 +++++ CHANGELOG.md | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 7ab4f70f3..581a430d8 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.1.18] 2019.05.18 +#### Changes +* Removed deprecated method: `setValidationDisabled` +* Updated dependencies + ### [1.1.17] 2019.05.13 #### Changes * **Modified project behaviour:** since this version the **"Bean Validation" is disabled by default**, to enable it, the following instruction needs to be executed: `transformer.setValidationEnabled(true);` diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d0ccc73c..60af5a922 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.4.1] 2019.05.18 +#### Changes +* Removed deprecated method: `setValidationDisabled` +* Updated dependencies + ### [1.4.0] 2019.05.13 #### Changes * **Modified project behaviour:** since this version the **"Bean Validation" is disabled by default**, to enable it, the following instruction needs to be executed: `transformer.setValidationEnabled(true);` From 11a3653428f491ebbbc8151d30452bb84beb3a4a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:06:13 +0200 Subject: [PATCH 0528/1786] minor: static import --- .../com/hotels/beans/transformer/AbstractTransformer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 2ba40468c..02eb61641 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -16,6 +16,7 @@ package com.hotels.beans.transformer; +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static java.util.Arrays.asList; import static com.hotels.beans.validator.Validator.notNull; @@ -24,7 +25,6 @@ import java.util.function.Function; import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.cache.CacheManagerFactory; import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.utils.ClassUtils; @@ -70,7 +70,7 @@ abstract class AbstractTransformer implements Transformer { this.classUtils = new ClassUtils(); this.validator = new ValidatorImpl(); this.settings = new TransformerSettings(); - this.cacheManager = CacheManagerFactory.getCacheManager("transformer"); + this.cacheManager = getCacheManager("transformer"); } /** From 4a51395abffb46d5ef625d383f68215a3ffd8b88 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:31:51 +0200 Subject: [PATCH 0529/1786] modified travis configuration in order to execute the quality check only when a tag is available --- .travis.yml | 8 +++++--- .../com/hotels/beans/transformer/AbstractTransformer.java | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6bd342359..9ca0241d3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,11 +18,13 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - if: NOT branch = master + if: tag IS blank install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dsonar.branch.name=${TRAVIS_BRANCH} -Dsonar.branch.target=master - - stage: "Build and Quality Check" + - stage: "Build, Test and Quality Check" name: "Building, testing and performing quality check" - if: branch = master AND type NOT IN (pull_request) + if: branch = master AND type NOT IN (pull_request) AND tag IS present + before_install: + - mvn versions:set -D newVersion=${TRAVIS_TAG} install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - stage: "Site Build and Publish" name: "Building site and publishing on GitHub pages" diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 02eb61641..91041d87c 100644 --- a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -16,10 +16,10 @@ package com.hotels.beans.transformer; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static java.util.Arrays.asList; import static com.hotels.beans.validator.Validator.notNull; +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import java.util.Map; import java.util.function.Function; From d7f398dee68dabc67a72f43c6e06b73ffc8f2147 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:41:48 +0200 Subject: [PATCH 0530/1786] modified travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9ca0241d3..9d204decf 100755 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ jobs: - stage: "Build" name: "Build and Test" if: tag IS blank - install: travis_retry mvn clean install -Dmaven.javadoc.skip=true -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dsonar.branch.name=${TRAVIS_BRANCH} -Dsonar.branch.target=master + install: travis_retry mvn clean install - stage: "Build, Test and Quality Check" name: "Building, testing and performing quality check" if: branch = master AND type NOT IN (pull_request) AND tag IS present From 667e253731f400eaa516038c733ef07bb33e9117 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:48:18 +0200 Subject: [PATCH 0531/1786] [maven-release-plugin] prepare release 1.4.1 --- pom.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index ec20fa1f2..db5144022 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 BULL - Bean Utils Light Library com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1-SNAPSHOT + 1.4.1 jar 2019 @@ -60,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.1 From 3fdda504d4a31485231e6f7d5b275aed4295dc07 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:48:25 +0200 Subject: [PATCH 0532/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index db5144022..c70d0c0df 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1 + 1.4.2-SNAPSHOT jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.1 + HEAD From 30e7fd3cc356860db4a4d85eec20dcd7a35157f4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:49:56 +0200 Subject: [PATCH 0533/1786] modified travis build condition --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9d204decf..71d558a27 100755 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ jobs: install: travis_retry mvn clean install - stage: "Build, Test and Quality Check" name: "Building, testing and performing quality check" - if: branch = master AND type NOT IN (pull_request) AND tag IS present + if: branch = master AND (type NOT IN (pull_request) AND tag IS present) before_install: - mvn versions:set -D newVersion=${TRAVIS_TAG} install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} From 17bfe2e6e52252b89f56e18f9552e59647427d3b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:50:55 +0200 Subject: [PATCH 0534/1786] downgraded pom version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c70d0c0df..6eca6bd15 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.2-SNAPSHOT + 1.4.1-SNAPSHOT jar 2019 From 1ada0bf28c7f7f84300c0c52ecdd0a3c93e62fa9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:51:36 +0200 Subject: [PATCH 0535/1786] [maven-release-plugin] prepare release 1.4.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6eca6bd15..db5144022 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1-SNAPSHOT + 1.4.1 jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.1 From 5b0940626318520d4ffe58cebd129eae0eef9231 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:51:44 +0200 Subject: [PATCH 0536/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index db5144022..c70d0c0df 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1 + 1.4.2-SNAPSHOT jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.1 + HEAD From e47783c8d8e734cad54ff0188dfa43942edce074 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:54:10 +0200 Subject: [PATCH 0537/1786] modified travis condition --- .travis.yml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 71d558a27..555df78d7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ jobs: install: travis_retry mvn clean install - stage: "Build, Test and Quality Check" name: "Building, testing and performing quality check" - if: branch = master AND (type NOT IN (pull_request) AND tag IS present) + if: tag IS present AND branch = master AND type NOT IN (pull_request) before_install: - mvn versions:set -D newVersion=${TRAVIS_TAG} install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} diff --git a/pom.xml b/pom.xml index c70d0c0df..6eca6bd15 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.2-SNAPSHOT + 1.4.1-SNAPSHOT jar 2019 From 80ffb1902b5ed79d210697e036dc179235669fd1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:55:02 +0200 Subject: [PATCH 0538/1786] [maven-release-plugin] prepare release 1.4.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6eca6bd15..db5144022 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1-SNAPSHOT + 1.4.1 jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.1 From 4ff466dc5f55497d0c80f36f9b34f1f30b1eadbd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:55:12 +0200 Subject: [PATCH 0539/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index db5144022..c70d0c0df 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1 + 1.4.2-SNAPSHOT jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.1 + HEAD From 2074cd251be889a78be0c2951342a01a628ed05e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:56:20 +0200 Subject: [PATCH 0540/1786] modified travis condition --- .travis.yml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 555df78d7..d4bb3b8cb 100755 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ jobs: install: travis_retry mvn clean install - stage: "Build, Test and Quality Check" name: "Building, testing and performing quality check" - if: tag IS present AND branch = master AND type NOT IN (pull_request) + if: branch = master AND tag IS present before_install: - mvn versions:set -D newVersion=${TRAVIS_TAG} install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} diff --git a/pom.xml b/pom.xml index c70d0c0df..6eca6bd15 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.2-SNAPSHOT + 1.4.1-SNAPSHOT jar 2019 From 8ce8a510afee142cf3ed5403822f9d52b680df30 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:57:17 +0200 Subject: [PATCH 0541/1786] [maven-release-plugin] prepare release 1.4.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6eca6bd15..db5144022 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1-SNAPSHOT + 1.4.1 jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.1 From 85551877db9c8f830ba3542c7afefcdc75c54f1b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 10:57:24 +0200 Subject: [PATCH 0542/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index db5144022..c70d0c0df 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1 + 1.4.2-SNAPSHOT jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.1 + HEAD From a2cac0fa0a3b32e418f2728914785a1b3aa9b398 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 11:01:44 +0200 Subject: [PATCH 0543/1786] modified travis config --- .travis.yml | 13 +++---------- pom.xml | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index d4bb3b8cb..dd94c34db 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,20 +18,13 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - if: tag IS blank install: travis_retry mvn clean install - - stage: "Build, Test and Quality Check" - name: "Building, testing and performing quality check" - if: branch = master AND tag IS present - before_install: - - mvn versions:set -D newVersion=${TRAVIS_TAG} - install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build and Publish" - name: "Building site and publishing on GitHub pages" + - stage: "Site Build and Quality check" + name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install site:site -Dmaven.test.skip=true -B + - travis_retry mvn install sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true -B deploy: provider: pages local-dir: target/site diff --git a/pom.xml b/pom.xml index c70d0c0df..6eca6bd15 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.2-SNAPSHOT + 1.4.1-SNAPSHOT jar 2019 From 85a79273c7bffe013cd8012a150992330aad42c0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 11:02:25 +0200 Subject: [PATCH 0544/1786] [maven-release-plugin] prepare release 1.4.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6eca6bd15..db5144022 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1-SNAPSHOT + 1.4.1 jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.1 From 1100aa12f161684ac620a684e01ce005b5995415 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 11:02:33 +0200 Subject: [PATCH 0545/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index db5144022..c70d0c0df 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1 + 1.4.2-SNAPSHOT jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.1 + HEAD From 1af50458b9e3317d2391cfb4c9ceb017d90ff415 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 11:05:26 +0200 Subject: [PATCH 0546/1786] modified travis config --- .travis.yml | 13 ++++++++++--- pom.xml | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index dd94c34db..9d204decf 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,13 +18,20 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" + if: tag IS blank install: travis_retry mvn clean install - - stage: "Site Build and Quality check" - name: "Publishing site and performing a code quality check" + - stage: "Build, Test and Quality Check" + name: "Building, testing and performing quality check" + if: branch = master AND type NOT IN (pull_request) AND tag IS present + before_install: + - mvn versions:set -D newVersion=${TRAVIS_TAG} + install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} + - stage: "Site Build and Publish" + name: "Building site and publishing on GitHub pages" if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true -B + - travis_retry mvn install site:site -Dmaven.test.skip=true -B deploy: provider: pages local-dir: target/site diff --git a/pom.xml b/pom.xml index c70d0c0df..6eca6bd15 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.2-SNAPSHOT + 1.4.1-SNAPSHOT jar 2019 From f897d666d07312c4d3ad8934549ced2aa2b61d48 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 11:06:40 +0200 Subject: [PATCH 0547/1786] [maven-release-plugin] prepare release 1.4.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6eca6bd15..db5144022 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1-SNAPSHOT + 1.4.1 jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.1 From c8b32720127bffb11b0e815c76bb6200071278bc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 11:06:47 +0200 Subject: [PATCH 0548/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index db5144022..c70d0c0df 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1 + 1.4.2-SNAPSHOT jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.1 + HEAD From f8e9df8dfc502529c80f7cc2ed070629a8ed670e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 11:07:50 +0200 Subject: [PATCH 0549/1786] Modified travis config --- .travis.yml | 13 +++---------- pom.xml | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9d204decf..dd94c34db 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,20 +18,13 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - if: tag IS blank install: travis_retry mvn clean install - - stage: "Build, Test and Quality Check" - name: "Building, testing and performing quality check" - if: branch = master AND type NOT IN (pull_request) AND tag IS present - before_install: - - mvn versions:set -D newVersion=${TRAVIS_TAG} - install: travis_retry mvn clean install -B sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} - - stage: "Site Build and Publish" - name: "Building site and publishing on GitHub pages" + - stage: "Site Build and Quality check" + name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install site:site -Dmaven.test.skip=true -B + - travis_retry mvn install sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true -B deploy: provider: pages local-dir: target/site diff --git a/pom.xml b/pom.xml index c70d0c0df..6eca6bd15 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.2-SNAPSHOT + 1.4.1-SNAPSHOT jar 2019 From 13f79f09178a4f56cab6325795357cd157390f46 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 11:08:36 +0200 Subject: [PATCH 0550/1786] [maven-release-plugin] prepare release 1.4.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6eca6bd15..db5144022 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1-SNAPSHOT + 1.4.1 jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.1 From 5d7a8933ec4a644f15081418ef5071a149a8e6aa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 18 May 2019 11:08:43 +0200 Subject: [PATCH 0551/1786] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index db5144022..c70d0c0df 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library https://github.com/HotelsDotCom/bull - 1.4.1 + 1.4.2-SNAPSHOT jar 2019 @@ -59,7 +59,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.1 + HEAD From 406b76d36f38fcaae86efc03e6b53b58b8d779d0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 May 2019 10:17:53 +0200 Subject: [PATCH 0552/1786] Added contributing badge --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6ad7a4906..061a1652d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -Contributing +Contributing [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/dwyl/esta/issues) ============ If you want to contribute to the project and make it better, your help is very welcome. Contributing is also a great way to learn more about social coding on Github, new technologies and and their ecosystems and how to make constructive, helpful bug reports, feature requests and the noblest of all contributions: a good, clean pull request. From 27d4892d8bc8a9f82e49e0f75e813565d5ca4540 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 May 2019 12:31:01 +0200 Subject: [PATCH 0553/1786] Implemented mechanism for recognizing if a type can be automatically converted --- .../beans/conversion/ConversionAnalyzer.java | 118 ++++++++++++++ .../beans/conversion/ConversionProcessor.java | 126 +++++++++++++++ .../ConversionProcessorFactory.java | 73 +++++++++ .../conversion/StringConversionProcessor.java | 144 ++++++++++++++++++ .../hotels/beans/conversion/package-info.java | 20 +++ 5 files changed, 481 insertions(+) create mode 100644 src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java create mode 100644 src/main/java/com/hotels/beans/conversion/ConversionProcessor.java create mode 100644 src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java create mode 100644 src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java create mode 100644 src/main/java/com/hotels/beans/conversion/package-info.java diff --git a/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java b/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java new file mode 100644 index 000000000..b046e7ade --- /dev/null +++ b/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java @@ -0,0 +1,118 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import static java.util.Optional.empty; +import static java.util.Optional.of; + +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.conversion.ConversionProcessorFactory.getConversionProcessor; + +import java.util.Optional; +import java.util.function.Function; + +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.utils.ClassUtils; + +/** + * This class analyzes the two classes received in input, and returns the conversion processor to be used. + */ +public final class ConversionAnalyzer { + /** + * CacheManager instance {@link CacheManager}. + */ + private static final CacheManager CACHE_MANAGER = getCacheManager("conversionAnalyzer"); + + /** + * Class utils instance {@link ClassUtils}. + */ + private final ClassUtils classUtils; + + /** + * Default constructor. + */ + public ConversionAnalyzer() { + this.classUtils = new ClassUtils(); + } + + /** + * Analyzes Fields given as input and returns the conversion processor. + * @param sourceFieldType source field class + * @param destinationFieldType the destination field class + * @return an {@link Optional} containing the conversion function (if exists) + */ + public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { + Optional> conversionFunction = empty(); + if (destinationFieldType != sourceFieldType && classUtils.isPrimitiveType(sourceFieldType) && classUtils.isPrimitiveType(destinationFieldType)) { + conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); + } + return conversionFunction; + } + + /** + * Returns the type transformer function for the given type. + * @param conversionProcessor the {@link ConversionProcessor} for the given type + * @param sourceFieldType the source field class + * @return the conversion function + */ + @SuppressWarnings("unchecked") + private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { + Optional> conversionFunction; + if (sourceFieldType == String.class) { + conversionFunction = of(conversionProcessor.convertString()); + } else if (sourceFieldType == Byte.class) { + conversionFunction = of(conversionProcessor.convertByte()); + } else if (sourceFieldType == byte.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveByte()); + } else if (sourceFieldType == Short.class) { + conversionFunction = of(conversionProcessor.convertShort()); + } else if (sourceFieldType == short.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveShort()); + } else if (sourceFieldType == Integer.class) { + conversionFunction = of(conversionProcessor.convertInteger()); + } else if (sourceFieldType == int.class) { + conversionFunction = of(conversionProcessor.convertInt()); + } else if (sourceFieldType == Long.class) { + conversionFunction = of(conversionProcessor.convertLong()); + } else if (sourceFieldType == long.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveLong()); + } else if (sourceFieldType == Float.class) { + conversionFunction = of(conversionProcessor.convertFloat()); + } else if (sourceFieldType == float.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveFloat()); + } else if (sourceFieldType == Double.class) { + conversionFunction = of(conversionProcessor.convertDouble()); + } else if (sourceFieldType == double.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveDouble()); + } else if (sourceFieldType == Character.class) { + conversionFunction = of(conversionProcessor.convertCharacter()); + } else if (sourceFieldType == char.class) { + conversionFunction = of(conversionProcessor.convertChar()); + } else if (sourceFieldType == Boolean.class) { + conversionFunction = of(conversionProcessor.convertBoolean()); + } else if (sourceFieldType == boolean.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveBoolean()); + } else { + conversionFunction = empty(); + } + CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); + return conversionFunction; + }); + } +} diff --git a/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java b/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java new file mode 100644 index 000000000..26c270015 --- /dev/null +++ b/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java @@ -0,0 +1,126 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import java.util.function.Function; + +/** + * Conversion methods for all primitive types. + */ +public interface ConversionProcessor { + /** + * Converts a byte type. + * @return the converted value + */ + Function convertPrimitiveByte(); + + /** + * Converts a {@link Byte} type. + * @return the converted value + */ + Function convertByte(); + + /** + * Converts a short type. + * @return the converted value + */ + Function convertPrimitiveShort(); + + /** + * Converts a {@link Short} type. + * @return the converted value + */ + Function convertShort(); + + /** + * Converts an int type. + * @return the converted value + */ + Function convertInt(); + + /** + * Converts an {@link Integer} type. + * @return the converted value + */ + Function convertInteger(); + + /** + * Converts a long type. + * @return the converted value + */ + Function convertPrimitiveLong(); + + /** + * Converts a {@link Long} type. + * @return the converted value + */ + Function convertLong(); + + /** + * Converts a float type. + * @return the converted value + */ + Function convertPrimitiveFloat(); + + /** + * Converts an {@link Float} type. + * @return the converted value + */ + Function convertFloat(); + + /** + * Converts a double type. + * @return the converted value + */ + Function convertPrimitiveDouble(); + + /** + * Converts a {@link Double} type. + * @return the converted value + */ + Function convertDouble(); + + /** + * Converts a char type. + * @return the converted value + */ + Function convertChar(); + + /** + * Converts a {@link Character} type. + * @return the converted value + */ + Function convertCharacter(); + + /** + * Converts a boolean type. + * @return the converted value + */ + Function convertPrimitiveBoolean(); + + /** + * Converts a {@link Boolean} type. + * @return the converted value + */ + Function convertBoolean(); + + /** + * Converts a {@link String} type. + * @return the converted value + */ + Function convertString(); +} diff --git a/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java b/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java new file mode 100644 index 000000000..9affbb8b5 --- /dev/null +++ b/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import static lombok.AccessLevel.PRIVATE; + +import lombok.NoArgsConstructor; + +/** + * Creates a {@link ConversionProcessor} instance for the given class. + */ +@NoArgsConstructor(access = PRIVATE) +public final class ConversionProcessorFactory { + /** + * Returns a conversion processor for the given type. + * @param clazz the class for which the conversion processor has to be retrieved. + * @return a conversion processor for the given type + */ + public static ConversionProcessor getConversionProcessor(final Class clazz) { + ConversionProcessor conversionProcessor = null; + if (clazz == String.class) { + conversionProcessor = new StringConversionProcessor(); + } +// else if (clazz == Byte.class) { +// conversionProcessor = new ByteConversionProcessor(); +// } else if (clazz == byte.class) { +// conversionProcessor = new PrimitiveByteConversionProcessor(); +// } else if (clazz == Short.class) { +// conversionProcessor = new ShortConversionProcessor(); +// } else if (clazz == short.class) { +// conversionProcessor = new PrimitiveShortConversionProcessor(); +// } else if (clazz == Integer.class) { +// conversionProcessor = new IntegerConversionProcessor(); +// } else if (clazz == int.class) { +// conversionProcessor = new IntConversionProcessor(); +// } else if (clazz == Long.class) { +// conversionProcessor = new LongConversionProcessor(); +// } else if (clazz == long.class) { +// conversionProcessor = new PrimitiveLongConversionProcessor(); +// } else if (clazz == Float.class) { +// conversionProcessor = new FloatConversionProcessor(); +// } else if (clazz == float.class) { +// conversionProcessor = new PrimitiveFloatConversionProcessor(); +// } else if (clazz == Double.class) { +// conversionProcessor = new DoubleConversionProcessor(); +// } else if (clazz == double.class) { +// conversionProcessor = new PrimitiveDoubleConversionProcessor(); +// } else if (clazz == Character.class) { +// conversionProcessor = new CharacterConversionProcessor(); +// } else if (clazz == char.class) { +// conversionProcessor = new CharConversionProcessor(); +// } else if (clazz == Boolean.class) { +// conversionProcessor = new BooleanConversionProcessor(); +// } else if (clazz == boolean.class) { +// conversionProcessor = new PrimitiveBooleanConversionProcessor(); +// } + return conversionProcessor; + } +} diff --git a/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java b/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java new file mode 100644 index 000000000..1f0711f06 --- /dev/null +++ b/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java @@ -0,0 +1,144 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import java.util.function.Function; + +/** + * Provides all method for converting any primitive type to a String. + */ +public class StringConversionProcessor implements ConversionProcessor { + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveByte() { + return val -> Byte.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertByte() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveShort() { + return val -> Short.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertShort() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertInt() { + return val -> Integer.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertInteger() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveLong() { + return val -> Long.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertLong() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveFloat() { + return val -> Float.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertFloat() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveDouble() { + return val -> Double.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertDouble() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertChar() { + return val -> Character.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertCharacter() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveBoolean() { + return val -> Boolean.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertBoolean() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertString() { + return val -> val; + } +} diff --git a/src/main/java/com/hotels/beans/conversion/package-info.java b/src/main/java/com/hotels/beans/conversion/package-info.java new file mode 100644 index 000000000..eb89044b2 --- /dev/null +++ b/src/main/java/com/hotels/beans/conversion/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Type conversion processor package. + */ + +package com.hotels.beans.conversion; From c3deebda48de5663e96768cee143f33011113287 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 May 2019 12:33:53 +0200 Subject: [PATCH 0554/1786] cached object where possible --- .../beans/conversion/ConversionAnalyzer.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java b/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java index b046e7ade..a2da54a56 100644 --- a/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java +++ b/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java @@ -55,12 +55,17 @@ public ConversionAnalyzer() { * @param destinationFieldType the destination field class * @return an {@link Optional} containing the conversion function (if exists) */ + @SuppressWarnings("unchecked") public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { - Optional> conversionFunction = empty(); - if (destinationFieldType != sourceFieldType && classUtils.isPrimitiveType(sourceFieldType) && classUtils.isPrimitiveType(destinationFieldType)) { - conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); - } - return conversionFunction; + final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { + Optional> conversionFunction = empty(); + if (destinationFieldType != sourceFieldType && classUtils.isPrimitiveType(sourceFieldType) && classUtils.isPrimitiveType(destinationFieldType)) { + conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); + } + CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); + return conversionFunction; + }); } /** From b4b4634ac797997ec825bd7fb10420885d171b6b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 May 2019 16:45:15 +0200 Subject: [PATCH 0555/1786] Divided project into three different modules: - core: containing the transformer function and all core functionalities - common: containing all classes common to multiple modules - conversion: containing all conversion related functions --- bull-common/pom.xml | 16 ++++ .../beans/annotation/ConstructorArg.java | 0 .../hotels/beans/annotation/package-info.java | 0 .../java/com/hotels/beans/base/Defaults.java | 0 .../com/hotels/beans/base/package-info.java | 0 .../com/hotels/beans/cache/CacheManager.java | 0 .../beans/cache/CacheManagerFactory.java | 0 .../com/hotels/beans/cache/package-info.java | 0 .../com/hotels/beans/constant/ClassType.java | 0 .../com/hotels/beans/constant/Filters.java | 0 .../hotels/beans/constant/MethodPrefix.java | 0 .../hotels/beans/constant/Punctuation.java | 0 .../hotels/beans/constant/package-info.java | 0 .../error/InstanceCreationException.java | 0 .../beans/error/InvalidBeanException.java | 0 .../beans/error/MissingFieldException.java | 0 .../beans/error/MissingMethodException.java | 0 .../com/hotels/beans/error/package-info.java | 0 .../com/hotels/beans/model/EmptyValue.java | 0 .../java/com/hotels/beans/model/ItemType.java | 0 .../com/hotels/beans/model/MapElemType.java | 0 .../java/com/hotels/beans/model/MapType.java | 0 .../com/hotels/beans/model/package-info.java | 0 .../java/com/hotels/beans/package-info.java | 0 .../com/hotels/beans/utils/ClassUtils.java | 0 .../hotels/beans/utils/ReflectionUtils.java | 0 .../com/hotels/beans/utils/package-info.java | 0 .../com/hotels/beans/validator/Validator.java | 0 .../hotels/beans/validator/ValidatorImpl.java | 0 .../hotels/beans/validator/package-info.java | 0 .../com/hotels/beans/base/DefaultsTest.java | 0 .../com/hotels/beans/base/package-info.java | 0 .../beans/cache/CacheManagerFactoryTest.java | 0 .../hotels/beans/cache/CacheManagerTest.java | 0 .../com/hotels/beans/cache/package-info.java | 0 .../java/com/hotels/beans/package-info.java | 0 .../hotels/beans/sample/AbstractClass.java | 0 .../java/com/hotels/beans/sample/FromFoo.java | 0 .../hotels/beans/sample/FromFooAdvFields.java | 0 .../com/hotels/beans/sample/FromFooMap.java | 0 .../hotels/beans/sample/FromFooSimple.java | 0 .../beans/sample/FromFooSimpleNoGetters.java | 0 .../hotels/beans/sample/FromFooSubClass.java | 0 .../sample/FromFooWithPrimitiveFields.java | 0 .../com/hotels/beans/sample/FromSubFoo.java | 0 .../sample/immutable/ImmutableFlatToFoo.java | 0 .../sample/immutable/ImmutableToFoo.java | 0 .../immutable/ImmutableToFooAdvFields.java | 0 .../ImmutableToFooCustomAnnotation.java | 0 .../immutable/ImmutableToFooDiffFields.java | 0 .../immutable/ImmutableToFooInvalid.java | 0 .../sample/immutable/ImmutableToFooMap.java | 0 ...ImmutableToFooMissingCustomAnnotation.java | 0 .../ImmutableToFooNoConstructors.java | 0 .../ImmutableToFooNotExistingFields.java | 0 .../immutable/ImmutableToFooSimple.java | 0 .../ImmutableToFooSimpleWrongTypes.java | 0 .../immutable/ImmutableToFooSubClass.java | 0 .../immutable/ImmutableToFooWithBuilder.java | 0 .../sample/immutable/ImmutableToSubFoo.java | 0 .../ImmutableToSubFooCustomAnnotation.java | 0 .../beans/sample/immutable/package-info.java | 0 .../hotels/beans/sample/mixed/MixedToFoo.java | 0 .../sample/mixed/MixedToFooDiffFields.java | 0 .../MixedToFooMissingAllArgsConstructor.java | 0 .../mixed/MixedToFooMissingConstructor.java | 0 .../sample/mixed/MixedToFooMissingField.java | 0 .../mixed/MixedToFooNotExistingFields.java | 0 .../sample/mixed/MixedToFooStaticField.java | 0 .../sample/mixed/MixedToFooWithBuilder.java | 0 .../beans/sample/mixed/package-info.java | 0 .../beans/sample/mutable/MutableToFoo.java | 0 .../sample/mutable/MutableToFooAdvFields.java | 0 .../sample/mutable/MutableToFooInvalid.java | 0 .../MutableToFooNotExistingFields.java | 0 .../sample/mutable/MutableToFooSimple.java | 0 .../mutable/MutableToFooSimpleNoSetters.java | 0 .../sample/mutable/MutableToFooSubClass.java | 0 .../mutable/MutableToFooWithBuilder.java | 0 ...leToFooWithBuilderMultipleConstructor.java | 0 .../beans/sample/mutable/MutableToSubFoo.java | 0 .../beans/sample/mutable/package-info.java | 0 .../com/hotels/beans/sample/package-info.java | 0 .../hotels/beans/utils/ClassUtilsTest.java | 2 +- .../beans/utils/ReflectionUtilsTest.java | 5 +- .../com/hotels/beans/utils/package-info.java | 0 .../hotels/beans/validator/ValidatorTest.java | 0 .../hotels/beans/validator/package-info.java | 0 .../org.mockito.plugins.MockMaker | 0 bull-converter/pom.xml | 24 ++++++ .../beans/conversion/ConversionAnalyzer.java | 0 .../beans/conversion/ConversionProcessor.java | 0 .../ConversionProcessorFactory.java | 0 .../conversion/StringConversionProcessor.java | 0 .../hotels/beans/conversion/package-info.java | 0 .../org.mockito.plugins.MockMaker | 1 + bull-core/pom.xml | 32 ++++++++ .../main/java/com/hotels/beans/BeanUtils.java | 0 .../com/hotels/beans/model/FieldMapping.java | 0 .../hotels/beans/model/FieldTransformer.java | 0 .../com/hotels/beans/model/package-info.java | 20 +++++ .../java/com/hotels/beans/package-info.java | 20 +++++ .../beans/populator/ArrayPopulator.java | 0 .../beans/populator/CollectionPopulator.java | 0 .../beans/populator/ICollectionPopulator.java | 0 .../hotels/beans/populator/MapPopulator.java | 0 .../beans/populator/OptionalPopulator.java | 2 +- .../com/hotels/beans/populator/Populator.java | 0 .../beans/populator/PopulatorFactory.java | 0 .../hotels/beans/populator/package-info.java | 0 .../transformer/AbstractTransformer.java | 0 .../hotels/beans/transformer/Transformer.java | 0 .../beans/transformer/TransformerImpl.java | 0 .../transformer/TransformerSettings.java | 0 .../beans/transformer/package-info.java | 0 .../src}/main/resources/banner.txt | 0 .../main/resources/config/application-dev.yml | 0 .../main/resources/config/application.yml | 0 .../config/logging/logback-appenders.xml | 0 .../config/logging/logback-properties.xml | 0 .../src}/main/resources/logback-test.xml | 0 .../src}/main/resources/logback.xml | 0 .../java/com/hotels/beans/BeanUtilsTest.java | 4 +- .../java/com/hotels/beans/package-info.java | 20 +++++ .../beans/performance/PerformanceTest.java | 2 +- .../beans/performance/package-info.java | 0 .../beans/populator/ArrayPopulatorTest.java | 0 .../beans/populator/PopulatorFactoryTest.java | 0 .../hotels/beans/populator/package-info.java | 0 .../hotels/beans/sample/AbstractClass.java | 32 ++++++++ .../java/com/hotels/beans/sample/FromFoo.java | 47 +++++++++++ .../hotels/beans/sample/FromFooAdvFields.java | 46 +++++++++++ .../com/hotels/beans/sample/FromFooMap.java | 37 +++++++++ .../hotels/beans/sample/FromFooSimple.java | 41 ++++++++++ .../beans/sample/FromFooSimpleNoGetters.java | 34 ++++++++ .../hotels/beans/sample/FromFooSubClass.java | 42 ++++++++++ .../sample/FromFooWithPrimitiveFields.java | 38 +++++++++ .../com/hotels/beans/sample/FromSubFoo.java | 38 +++++++++ .../sample/immutable/ImmutableFlatToFoo.java | 39 ++++++++++ .../sample/immutable/ImmutableToFoo.java | 47 +++++++++++ .../immutable/ImmutableToFooAdvFields.java | 48 ++++++++++++ .../ImmutableToFooCustomAnnotation.java | 77 +++++++++++++++++++ .../immutable/ImmutableToFooDiffFields.java | 49 ++++++++++++ .../immutable/ImmutableToFooInvalid.java | 58 ++++++++++++++ .../sample/immutable/ImmutableToFooMap.java | 37 +++++++++ ...ImmutableToFooMissingCustomAnnotation.java | 46 +++++++++++ .../ImmutableToFooNoConstructors.java | 27 +++++++ .../ImmutableToFooNotExistingFields.java | 33 ++++++++ .../immutable/ImmutableToFooSimple.java | 37 +++++++++ .../ImmutableToFooSimpleWrongTypes.java | 32 ++++++++ .../immutable/ImmutableToFooSubClass.java | 58 ++++++++++++++ .../immutable/ImmutableToFooWithBuilder.java | 47 +++++++++++ .../sample/immutable/ImmutableToSubFoo.java | 38 +++++++++ .../ImmutableToSubFooCustomAnnotation.java | 57 ++++++++++++++ .../beans/sample/immutable/package-info.java | 20 +++++ .../hotels/beans/sample/mixed/MixedToFoo.java | 48 ++++++++++++ .../sample/mixed/MixedToFooDiffFields.java | 52 +++++++++++++ .../MixedToFooMissingAllArgsConstructor.java | 55 +++++++++++++ .../mixed/MixedToFooMissingConstructor.java | 39 ++++++++++ .../sample/mixed/MixedToFooMissingField.java | 35 +++++++++ .../mixed/MixedToFooNotExistingFields.java | 35 +++++++++ .../sample/mixed/MixedToFooStaticField.java | 32 ++++++++ .../sample/mixed/MixedToFooWithBuilder.java | 47 +++++++++++ .../beans/sample/mixed/package-info.java | 20 +++++ .../beans/sample/mutable/MutableToFoo.java | 41 ++++++++++ .../sample/mutable/MutableToFooAdvFields.java | 40 ++++++++++ .../sample/mutable/MutableToFooInvalid.java | 43 +++++++++++ .../MutableToFooNotExistingFields.java | 33 ++++++++ .../sample/mutable/MutableToFooSimple.java | 37 +++++++++ .../mutable/MutableToFooSimpleNoSetters.java | 30 ++++++++ .../sample/mutable/MutableToFooSubClass.java | 39 ++++++++++ .../mutable/MutableToFooWithBuilder.java | 67 ++++++++++++++++ ...leToFooWithBuilderMultipleConstructor.java | 76 ++++++++++++++++++ .../beans/sample/mutable/MutableToSubFoo.java | 38 +++++++++ .../beans/sample/mutable/package-info.java | 20 +++++ .../com/hotels/beans/sample/package-info.java | 20 +++++ .../transformer/AbstractTransformerTest.java | 0 .../BuilderObjectTransformationTest.java | 9 +-- .../ImmutableObjectTransformationTest.java | 2 +- .../MixedObjectTransformationTest.java | 0 .../MutableObjectTransformationTest.java | 0 .../beans/transformer/TransformerTest.java | 0 .../beans/transformer/package-info.java | 0 .../org.mockito.plugins.MockMaker | 1 + pom.xml | 37 ++++++++- 185 files changed, 2131 insertions(+), 18 deletions(-) create mode 100644 bull-common/pom.xml rename {src => bull-common/src}/main/java/com/hotels/beans/annotation/ConstructorArg.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/annotation/package-info.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/base/Defaults.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/base/package-info.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/cache/CacheManager.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/cache/CacheManagerFactory.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/cache/package-info.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/constant/ClassType.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/constant/Filters.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/constant/MethodPrefix.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/constant/Punctuation.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/constant/package-info.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/error/InstanceCreationException.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/error/InvalidBeanException.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/error/MissingFieldException.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/error/MissingMethodException.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/error/package-info.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/model/EmptyValue.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/model/ItemType.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/model/MapElemType.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/model/MapType.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/model/package-info.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/package-info.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/utils/ClassUtils.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/utils/ReflectionUtils.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/utils/package-info.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/validator/Validator.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/validator/ValidatorImpl.java (100%) rename {src => bull-common/src}/main/java/com/hotels/beans/validator/package-info.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/base/DefaultsTest.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/base/package-info.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/cache/CacheManagerTest.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/cache/package-info.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/package-info.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/AbstractClass.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/FromFoo.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/FromFooAdvFields.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/FromFooMap.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/FromFooSimple.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/FromFooSubClass.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/FromSubFoo.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/immutable/package-info.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mixed/package-info.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/mutable/package-info.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/sample/package-info.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/utils/ClassUtilsTest.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java (99%) rename {src => bull-common/src}/test/java/com/hotels/beans/utils/package-info.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/validator/ValidatorTest.java (100%) rename {src => bull-common/src}/test/java/com/hotels/beans/validator/package-info.java (100%) rename {src => bull-common/src}/test/resources/mockito-extensions/org.mockito.plugins.MockMaker (100%) create mode 100644 bull-converter/pom.xml rename {src => bull-converter/src}/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java (100%) rename {src => bull-converter/src}/main/java/com/hotels/beans/conversion/ConversionProcessor.java (100%) rename {src => bull-converter/src}/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java (100%) rename {src => bull-converter/src}/main/java/com/hotels/beans/conversion/StringConversionProcessor.java (100%) rename {src => bull-converter/src}/main/java/com/hotels/beans/conversion/package-info.java (100%) create mode 100644 bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker create mode 100644 bull-core/pom.xml rename {src => bull-core/src}/main/java/com/hotels/beans/BeanUtils.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/model/FieldMapping.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/model/FieldTransformer.java (100%) create mode 100644 bull-core/src/main/java/com/hotels/beans/model/package-info.java create mode 100644 bull-core/src/main/java/com/hotels/beans/package-info.java rename {src => bull-core/src}/main/java/com/hotels/beans/populator/ArrayPopulator.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/populator/CollectionPopulator.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/populator/ICollectionPopulator.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/populator/MapPopulator.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/populator/OptionalPopulator.java (97%) rename {src => bull-core/src}/main/java/com/hotels/beans/populator/Populator.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/populator/PopulatorFactory.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/populator/package-info.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/transformer/AbstractTransformer.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/transformer/Transformer.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/transformer/TransformerImpl.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/transformer/TransformerSettings.java (100%) rename {src => bull-core/src}/main/java/com/hotels/beans/transformer/package-info.java (100%) rename {src => bull-core/src}/main/resources/banner.txt (100%) rename {src => bull-core/src}/main/resources/config/application-dev.yml (100%) rename {src => bull-core/src}/main/resources/config/application.yml (100%) rename {src => bull-core/src}/main/resources/config/logging/logback-appenders.xml (100%) rename {src => bull-core/src}/main/resources/config/logging/logback-properties.xml (100%) rename {src => bull-core/src}/main/resources/logback-test.xml (100%) rename {src => bull-core/src}/main/resources/logback.xml (100%) rename {src => bull-core/src}/test/java/com/hotels/beans/BeanUtilsTest.java (100%) create mode 100644 bull-core/src/test/java/com/hotels/beans/package-info.java rename {src => bull-core/src}/test/java/com/hotels/beans/performance/PerformanceTest.java (100%) rename {src => bull-core/src}/test/java/com/hotels/beans/performance/package-info.java (100%) rename {src => bull-core/src}/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java (100%) rename {src => bull-core/src}/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java (100%) rename {src => bull-core/src}/test/java/com/hotels/beans/populator/package-info.java (100%) create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/AbstractClass.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/FromFoo.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/FromFooMap.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/FromFooSimple.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/FromFooSubClass.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/FromSubFoo.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java create mode 100755 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/immutable/package-info.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mixed/package-info.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/mutable/package-info.java create mode 100644 bull-core/src/test/java/com/hotels/beans/sample/package-info.java rename {src => bull-core/src}/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java (100%) rename {src => bull-core/src}/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java (99%) rename {src => bull-core/src}/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java (99%) rename {src => bull-core/src}/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java (100%) rename {src => bull-core/src}/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java (100%) rename {src => bull-core/src}/test/java/com/hotels/beans/transformer/TransformerTest.java (100%) rename {src => bull-core/src}/test/java/com/hotels/beans/transformer/package-info.java (100%) create mode 100644 bull-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bull-common/pom.xml b/bull-common/pom.xml new file mode 100644 index 000000000..41124ec74 --- /dev/null +++ b/bull-common/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + bull-common + jar + Contains all classes required from more than one module + + + bean-utils-library + com.hotels.beans + 1.4.2-SNAPSHOT + + + \ No newline at end of file diff --git a/src/main/java/com/hotels/beans/annotation/ConstructorArg.java b/bull-common/src/main/java/com/hotels/beans/annotation/ConstructorArg.java similarity index 100% rename from src/main/java/com/hotels/beans/annotation/ConstructorArg.java rename to bull-common/src/main/java/com/hotels/beans/annotation/ConstructorArg.java diff --git a/src/main/java/com/hotels/beans/annotation/package-info.java b/bull-common/src/main/java/com/hotels/beans/annotation/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/annotation/package-info.java rename to bull-common/src/main/java/com/hotels/beans/annotation/package-info.java diff --git a/src/main/java/com/hotels/beans/base/Defaults.java b/bull-common/src/main/java/com/hotels/beans/base/Defaults.java similarity index 100% rename from src/main/java/com/hotels/beans/base/Defaults.java rename to bull-common/src/main/java/com/hotels/beans/base/Defaults.java diff --git a/src/main/java/com/hotels/beans/base/package-info.java b/bull-common/src/main/java/com/hotels/beans/base/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/base/package-info.java rename to bull-common/src/main/java/com/hotels/beans/base/package-info.java diff --git a/src/main/java/com/hotels/beans/cache/CacheManager.java b/bull-common/src/main/java/com/hotels/beans/cache/CacheManager.java similarity index 100% rename from src/main/java/com/hotels/beans/cache/CacheManager.java rename to bull-common/src/main/java/com/hotels/beans/cache/CacheManager.java diff --git a/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java b/bull-common/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java similarity index 100% rename from src/main/java/com/hotels/beans/cache/CacheManagerFactory.java rename to bull-common/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java diff --git a/src/main/java/com/hotels/beans/cache/package-info.java b/bull-common/src/main/java/com/hotels/beans/cache/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/cache/package-info.java rename to bull-common/src/main/java/com/hotels/beans/cache/package-info.java diff --git a/src/main/java/com/hotels/beans/constant/ClassType.java b/bull-common/src/main/java/com/hotels/beans/constant/ClassType.java similarity index 100% rename from src/main/java/com/hotels/beans/constant/ClassType.java rename to bull-common/src/main/java/com/hotels/beans/constant/ClassType.java diff --git a/src/main/java/com/hotels/beans/constant/Filters.java b/bull-common/src/main/java/com/hotels/beans/constant/Filters.java similarity index 100% rename from src/main/java/com/hotels/beans/constant/Filters.java rename to bull-common/src/main/java/com/hotels/beans/constant/Filters.java diff --git a/src/main/java/com/hotels/beans/constant/MethodPrefix.java b/bull-common/src/main/java/com/hotels/beans/constant/MethodPrefix.java similarity index 100% rename from src/main/java/com/hotels/beans/constant/MethodPrefix.java rename to bull-common/src/main/java/com/hotels/beans/constant/MethodPrefix.java diff --git a/src/main/java/com/hotels/beans/constant/Punctuation.java b/bull-common/src/main/java/com/hotels/beans/constant/Punctuation.java similarity index 100% rename from src/main/java/com/hotels/beans/constant/Punctuation.java rename to bull-common/src/main/java/com/hotels/beans/constant/Punctuation.java diff --git a/src/main/java/com/hotels/beans/constant/package-info.java b/bull-common/src/main/java/com/hotels/beans/constant/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/constant/package-info.java rename to bull-common/src/main/java/com/hotels/beans/constant/package-info.java diff --git a/src/main/java/com/hotels/beans/error/InstanceCreationException.java b/bull-common/src/main/java/com/hotels/beans/error/InstanceCreationException.java similarity index 100% rename from src/main/java/com/hotels/beans/error/InstanceCreationException.java rename to bull-common/src/main/java/com/hotels/beans/error/InstanceCreationException.java diff --git a/src/main/java/com/hotels/beans/error/InvalidBeanException.java b/bull-common/src/main/java/com/hotels/beans/error/InvalidBeanException.java similarity index 100% rename from src/main/java/com/hotels/beans/error/InvalidBeanException.java rename to bull-common/src/main/java/com/hotels/beans/error/InvalidBeanException.java diff --git a/src/main/java/com/hotels/beans/error/MissingFieldException.java b/bull-common/src/main/java/com/hotels/beans/error/MissingFieldException.java similarity index 100% rename from src/main/java/com/hotels/beans/error/MissingFieldException.java rename to bull-common/src/main/java/com/hotels/beans/error/MissingFieldException.java diff --git a/src/main/java/com/hotels/beans/error/MissingMethodException.java b/bull-common/src/main/java/com/hotels/beans/error/MissingMethodException.java similarity index 100% rename from src/main/java/com/hotels/beans/error/MissingMethodException.java rename to bull-common/src/main/java/com/hotels/beans/error/MissingMethodException.java diff --git a/src/main/java/com/hotels/beans/error/package-info.java b/bull-common/src/main/java/com/hotels/beans/error/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/error/package-info.java rename to bull-common/src/main/java/com/hotels/beans/error/package-info.java diff --git a/src/main/java/com/hotels/beans/model/EmptyValue.java b/bull-common/src/main/java/com/hotels/beans/model/EmptyValue.java similarity index 100% rename from src/main/java/com/hotels/beans/model/EmptyValue.java rename to bull-common/src/main/java/com/hotels/beans/model/EmptyValue.java diff --git a/src/main/java/com/hotels/beans/model/ItemType.java b/bull-common/src/main/java/com/hotels/beans/model/ItemType.java similarity index 100% rename from src/main/java/com/hotels/beans/model/ItemType.java rename to bull-common/src/main/java/com/hotels/beans/model/ItemType.java diff --git a/src/main/java/com/hotels/beans/model/MapElemType.java b/bull-common/src/main/java/com/hotels/beans/model/MapElemType.java similarity index 100% rename from src/main/java/com/hotels/beans/model/MapElemType.java rename to bull-common/src/main/java/com/hotels/beans/model/MapElemType.java diff --git a/src/main/java/com/hotels/beans/model/MapType.java b/bull-common/src/main/java/com/hotels/beans/model/MapType.java similarity index 100% rename from src/main/java/com/hotels/beans/model/MapType.java rename to bull-common/src/main/java/com/hotels/beans/model/MapType.java diff --git a/src/main/java/com/hotels/beans/model/package-info.java b/bull-common/src/main/java/com/hotels/beans/model/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/model/package-info.java rename to bull-common/src/main/java/com/hotels/beans/model/package-info.java diff --git a/src/main/java/com/hotels/beans/package-info.java b/bull-common/src/main/java/com/hotels/beans/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/package-info.java rename to bull-common/src/main/java/com/hotels/beans/package-info.java diff --git a/src/main/java/com/hotels/beans/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java similarity index 100% rename from src/main/java/com/hotels/beans/utils/ClassUtils.java rename to bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java diff --git a/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java similarity index 100% rename from src/main/java/com/hotels/beans/utils/ReflectionUtils.java rename to bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java diff --git a/src/main/java/com/hotels/beans/utils/package-info.java b/bull-common/src/main/java/com/hotels/beans/utils/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/utils/package-info.java rename to bull-common/src/main/java/com/hotels/beans/utils/package-info.java diff --git a/src/main/java/com/hotels/beans/validator/Validator.java b/bull-common/src/main/java/com/hotels/beans/validator/Validator.java similarity index 100% rename from src/main/java/com/hotels/beans/validator/Validator.java rename to bull-common/src/main/java/com/hotels/beans/validator/Validator.java diff --git a/src/main/java/com/hotels/beans/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java similarity index 100% rename from src/main/java/com/hotels/beans/validator/ValidatorImpl.java rename to bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java diff --git a/src/main/java/com/hotels/beans/validator/package-info.java b/bull-common/src/main/java/com/hotels/beans/validator/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/validator/package-info.java rename to bull-common/src/main/java/com/hotels/beans/validator/package-info.java diff --git a/src/test/java/com/hotels/beans/base/DefaultsTest.java b/bull-common/src/test/java/com/hotels/beans/base/DefaultsTest.java similarity index 100% rename from src/test/java/com/hotels/beans/base/DefaultsTest.java rename to bull-common/src/test/java/com/hotels/beans/base/DefaultsTest.java diff --git a/src/test/java/com/hotels/beans/base/package-info.java b/bull-common/src/test/java/com/hotels/beans/base/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/base/package-info.java rename to bull-common/src/test/java/com/hotels/beans/base/package-info.java diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java b/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java similarity index 100% rename from src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java rename to bull-common/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java diff --git a/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java similarity index 100% rename from src/test/java/com/hotels/beans/cache/CacheManagerTest.java rename to bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java diff --git a/src/test/java/com/hotels/beans/cache/package-info.java b/bull-common/src/test/java/com/hotels/beans/cache/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/cache/package-info.java rename to bull-common/src/test/java/com/hotels/beans/cache/package-info.java diff --git a/src/test/java/com/hotels/beans/package-info.java b/bull-common/src/test/java/com/hotels/beans/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/package-info.java rename to bull-common/src/test/java/com/hotels/beans/package-info.java diff --git a/src/test/java/com/hotels/beans/sample/AbstractClass.java b/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/AbstractClass.java rename to bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java diff --git a/src/test/java/com/hotels/beans/sample/FromFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/FromFoo.java rename to bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java diff --git a/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/FromFooAdvFields.java rename to bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java diff --git a/src/test/java/com/hotels/beans/sample/FromFooMap.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/FromFooMap.java rename to bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java diff --git a/src/test/java/com/hotels/beans/sample/FromFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/FromFooSimple.java rename to bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java diff --git a/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java rename to bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java diff --git a/src/test/java/com/hotels/beans/sample/FromFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/FromFooSubClass.java rename to bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java diff --git a/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java rename to bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java diff --git a/src/test/java/com/hotels/beans/sample/FromSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/FromSubFoo.java rename to bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java diff --git a/src/test/java/com/hotels/beans/sample/immutable/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/immutable/package-info.java rename to bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java rename to bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java rename to bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java rename to bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java rename to bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java rename to bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java rename to bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java rename to bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java diff --git a/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java rename to bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java diff --git a/src/test/java/com/hotels/beans/sample/mixed/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mixed/package-info.java rename to bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java diff --git a/src/test/java/com/hotels/beans/sample/mutable/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/mutable/package-info.java rename to bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java diff --git a/src/test/java/com/hotels/beans/sample/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/sample/package-info.java rename to bull-common/src/test/java/com/hotels/beans/sample/package-info.java diff --git a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java similarity index 100% rename from src/test/java/com/hotels/beans/utils/ClassUtilsTest.java rename to bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 99430a337..cb0769f8e 100644 --- a/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -54,8 +54,8 @@ import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mixed.MixedToFooMissingConstructor; -import com.hotels.beans.sample.mixed.MixedToFooWithBuilder; import com.hotels.beans.sample.mixed.MixedToFooStaticField; +import com.hotels.beans.sample.mixed.MixedToFooWithBuilder; import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; diff --git a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java similarity index 99% rename from src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java rename to bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index cf7f1780d..3498eff8c 100644 --- a/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -18,7 +18,6 @@ import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; - import static java.util.Objects.isNull; import static org.junit.Assert.assertEquals; @@ -43,13 +42,13 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import org.mockito.InjectMocks; -import com.hotels.beans.error.MissingMethodException; import com.hotels.beans.error.MissingFieldException; +import com.hotels.beans.error.MissingMethodException; import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.mutable.MutableToFoo; diff --git a/src/test/java/com/hotels/beans/utils/package-info.java b/bull-common/src/test/java/com/hotels/beans/utils/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/utils/package-info.java rename to bull-common/src/test/java/com/hotels/beans/utils/package-info.java diff --git a/src/test/java/com/hotels/beans/validator/ValidatorTest.java b/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java similarity index 100% rename from src/test/java/com/hotels/beans/validator/ValidatorTest.java rename to bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java diff --git a/src/test/java/com/hotels/beans/validator/package-info.java b/bull-common/src/test/java/com/hotels/beans/validator/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/validator/package-info.java rename to bull-common/src/test/java/com/hotels/beans/validator/package-info.java diff --git a/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-common/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker similarity index 100% rename from src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker rename to bull-common/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml new file mode 100644 index 000000000..2f3ce4d3c --- /dev/null +++ b/bull-converter/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + bull-converter + jar + Provides the conversion related classes + + + com.hotels.beans + bean-utils-library + 1.4.2-SNAPSHOT + + + + + com.hotels.beans + bull-common + ${project.version} + + + + \ No newline at end of file diff --git a/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java similarity index 100% rename from src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java diff --git a/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java similarity index 100% rename from src/main/java/com/hotels/beans/conversion/ConversionProcessor.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java diff --git a/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java similarity index 100% rename from src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java diff --git a/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java similarity index 100% rename from src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java diff --git a/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/conversion/package-info.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java diff --git a/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/bull-core/pom.xml b/bull-core/pom.xml new file mode 100644 index 000000000..ab4548517 --- /dev/null +++ b/bull-core/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + bull-core + jar + + + com.hotels.beans + bean-utils-library + 1.4.2-SNAPSHOT + + + + + com.hotels.beans + bull-common + ${project.version} + + + com.hotels.beans + bull-converter + ${project.version} + + + + + + ${parent.artifactId}-${project.version} + + \ No newline at end of file diff --git a/src/main/java/com/hotels/beans/BeanUtils.java b/bull-core/src/main/java/com/hotels/beans/BeanUtils.java similarity index 100% rename from src/main/java/com/hotels/beans/BeanUtils.java rename to bull-core/src/main/java/com/hotels/beans/BeanUtils.java diff --git a/src/main/java/com/hotels/beans/model/FieldMapping.java b/bull-core/src/main/java/com/hotels/beans/model/FieldMapping.java similarity index 100% rename from src/main/java/com/hotels/beans/model/FieldMapping.java rename to bull-core/src/main/java/com/hotels/beans/model/FieldMapping.java diff --git a/src/main/java/com/hotels/beans/model/FieldTransformer.java b/bull-core/src/main/java/com/hotels/beans/model/FieldTransformer.java similarity index 100% rename from src/main/java/com/hotels/beans/model/FieldTransformer.java rename to bull-core/src/main/java/com/hotels/beans/model/FieldTransformer.java diff --git a/bull-core/src/main/java/com/hotels/beans/model/package-info.java b/bull-core/src/main/java/com/hotels/beans/model/package-info.java new file mode 100644 index 000000000..610dabb69 --- /dev/null +++ b/bull-core/src/main/java/com/hotels/beans/model/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Pojo package. + */ + +package com.hotels.beans.model; diff --git a/bull-core/src/main/java/com/hotels/beans/package-info.java b/bull-core/src/main/java/com/hotels/beans/package-info.java new file mode 100644 index 000000000..99cdebc36 --- /dev/null +++ b/bull-core/src/main/java/com/hotels/beans/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Main package. + */ + +package com.hotels.beans; diff --git a/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bull-core/src/main/java/com/hotels/beans/populator/ArrayPopulator.java similarity index 100% rename from src/main/java/com/hotels/beans/populator/ArrayPopulator.java rename to bull-core/src/main/java/com/hotels/beans/populator/ArrayPopulator.java diff --git a/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/bull-core/src/main/java/com/hotels/beans/populator/CollectionPopulator.java similarity index 100% rename from src/main/java/com/hotels/beans/populator/CollectionPopulator.java rename to bull-core/src/main/java/com/hotels/beans/populator/CollectionPopulator.java diff --git a/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/bull-core/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java similarity index 100% rename from src/main/java/com/hotels/beans/populator/ICollectionPopulator.java rename to bull-core/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java diff --git a/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bull-core/src/main/java/com/hotels/beans/populator/MapPopulator.java similarity index 100% rename from src/main/java/com/hotels/beans/populator/MapPopulator.java rename to bull-core/src/main/java/com/hotels/beans/populator/MapPopulator.java diff --git a/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bull-core/src/main/java/com/hotels/beans/populator/OptionalPopulator.java similarity index 97% rename from src/main/java/com/hotels/beans/populator/OptionalPopulator.java rename to bull-core/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index 0566ded11..cf484731c 100644 --- a/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/bull-core/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -24,7 +24,7 @@ import com.hotels.beans.transformer.Transformer; /** - * Populator for {@link java.util.Optional} type. + * Populator for {@link Optional} type. */ class OptionalPopulator extends Populator { diff --git a/src/main/java/com/hotels/beans/populator/Populator.java b/bull-core/src/main/java/com/hotels/beans/populator/Populator.java similarity index 100% rename from src/main/java/com/hotels/beans/populator/Populator.java rename to bull-core/src/main/java/com/hotels/beans/populator/Populator.java diff --git a/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/bull-core/src/main/java/com/hotels/beans/populator/PopulatorFactory.java similarity index 100% rename from src/main/java/com/hotels/beans/populator/PopulatorFactory.java rename to bull-core/src/main/java/com/hotels/beans/populator/PopulatorFactory.java diff --git a/src/main/java/com/hotels/beans/populator/package-info.java b/bull-core/src/main/java/com/hotels/beans/populator/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/populator/package-info.java rename to bull-core/src/main/java/com/hotels/beans/populator/package-info.java diff --git a/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bull-core/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java similarity index 100% rename from src/main/java/com/hotels/beans/transformer/AbstractTransformer.java rename to bull-core/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java diff --git a/src/main/java/com/hotels/beans/transformer/Transformer.java b/bull-core/src/main/java/com/hotels/beans/transformer/Transformer.java similarity index 100% rename from src/main/java/com/hotels/beans/transformer/Transformer.java rename to bull-core/src/main/java/com/hotels/beans/transformer/Transformer.java diff --git a/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-core/src/main/java/com/hotels/beans/transformer/TransformerImpl.java similarity index 100% rename from src/main/java/com/hotels/beans/transformer/TransformerImpl.java rename to bull-core/src/main/java/com/hotels/beans/transformer/TransformerImpl.java diff --git a/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bull-core/src/main/java/com/hotels/beans/transformer/TransformerSettings.java similarity index 100% rename from src/main/java/com/hotels/beans/transformer/TransformerSettings.java rename to bull-core/src/main/java/com/hotels/beans/transformer/TransformerSettings.java diff --git a/src/main/java/com/hotels/beans/transformer/package-info.java b/bull-core/src/main/java/com/hotels/beans/transformer/package-info.java similarity index 100% rename from src/main/java/com/hotels/beans/transformer/package-info.java rename to bull-core/src/main/java/com/hotels/beans/transformer/package-info.java diff --git a/src/main/resources/banner.txt b/bull-core/src/main/resources/banner.txt similarity index 100% rename from src/main/resources/banner.txt rename to bull-core/src/main/resources/banner.txt diff --git a/src/main/resources/config/application-dev.yml b/bull-core/src/main/resources/config/application-dev.yml similarity index 100% rename from src/main/resources/config/application-dev.yml rename to bull-core/src/main/resources/config/application-dev.yml diff --git a/src/main/resources/config/application.yml b/bull-core/src/main/resources/config/application.yml similarity index 100% rename from src/main/resources/config/application.yml rename to bull-core/src/main/resources/config/application.yml diff --git a/src/main/resources/config/logging/logback-appenders.xml b/bull-core/src/main/resources/config/logging/logback-appenders.xml similarity index 100% rename from src/main/resources/config/logging/logback-appenders.xml rename to bull-core/src/main/resources/config/logging/logback-appenders.xml diff --git a/src/main/resources/config/logging/logback-properties.xml b/bull-core/src/main/resources/config/logging/logback-properties.xml similarity index 100% rename from src/main/resources/config/logging/logback-properties.xml rename to bull-core/src/main/resources/config/logging/logback-properties.xml diff --git a/src/main/resources/logback-test.xml b/bull-core/src/main/resources/logback-test.xml similarity index 100% rename from src/main/resources/logback-test.xml rename to bull-core/src/main/resources/logback-test.xml diff --git a/src/main/resources/logback.xml b/bull-core/src/main/resources/logback.xml similarity index 100% rename from src/main/resources/logback.xml rename to bull-core/src/main/resources/logback.xml diff --git a/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-core/src/test/java/com/hotels/beans/BeanUtilsTest.java similarity index 100% rename from src/test/java/com/hotels/beans/BeanUtilsTest.java rename to bull-core/src/test/java/com/hotels/beans/BeanUtilsTest.java index 8744f1484..39f2636ed 100644 --- a/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-core/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -34,10 +34,10 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.immutable.ImmutableToFoo; +import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooSimple; import com.hotels.beans.transformer.Transformer; diff --git a/bull-core/src/test/java/com/hotels/beans/package-info.java b/bull-core/src/test/java/com/hotels/beans/package-info.java new file mode 100644 index 000000000..89f2b1b61 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Test package. + */ + +package com.hotels.beans; diff --git a/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bull-core/src/test/java/com/hotels/beans/performance/PerformanceTest.java similarity index 100% rename from src/test/java/com/hotels/beans/performance/PerformanceTest.java rename to bull-core/src/test/java/com/hotels/beans/performance/PerformanceTest.java index 69e4eda28..cd0510b7b 100644 --- a/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bull-core/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -39,7 +39,6 @@ import org.testng.annotations.Test; import com.hotels.beans.BeanUtils; -import com.hotels.beans.transformer.Transformer; import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSubClass; @@ -49,6 +48,7 @@ import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.sample.mutable.MutableToFooSubClass; +import com.hotels.beans.transformer.Transformer; import lombok.extern.slf4j.Slf4j; diff --git a/src/test/java/com/hotels/beans/performance/package-info.java b/bull-core/src/test/java/com/hotels/beans/performance/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/performance/package-info.java rename to bull-core/src/test/java/com/hotels/beans/performance/package-info.java diff --git a/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-core/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java similarity index 100% rename from src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java rename to bull-core/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java diff --git a/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-core/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java similarity index 100% rename from src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java rename to bull-core/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java diff --git a/src/test/java/com/hotels/beans/populator/package-info.java b/bull-core/src/test/java/com/hotels/beans/populator/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/populator/package-info.java rename to bull-core/src/test/java/com/hotels/beans/populator/package-info.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/AbstractClass.java b/bull-core/src/test/java/com/hotels/beans/sample/AbstractClass.java new file mode 100644 index 000000000..adba701d9 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/AbstractClass.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Abstract class for testing purpose. + */ +@AllArgsConstructor +@Getter +public abstract class AbstractClass { + private final String name; + private final BigInteger id; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFoo.java b/bull-core/src/test/java/com/hotels/beans/sample/FromFoo.java new file mode 100644 index 000000000..d9662e008 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/FromFoo.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.math.BigInteger; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Sample immutable object. + */ +@AllArgsConstructor +@Getter +@Setter +public class FromFoo implements Cloneable { + private final String name; + private BigInteger id; + private final List nestedObjectList; + private final List list; + private final FromSubFoo nestedObject; + + public FromFoo clone() throws CloneNotSupportedException { + return (FromFoo) super.clone(); + } + + @Override + public String toString() { + return "FromFoo"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bull-core/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java new file mode 100644 index 000000000..1c197b967 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.util.Optional; + +import com.hotels.beans.constant.ClassType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * Sample object containing java advanced fields. + */ +@AllArgsConstructor +@Getter +@Setter +@ToString +public class FromFooAdvFields implements Cloneable { + private Optional name; + private final Optional age; + private final String indexNumber; + private final ClassType classType; + private final String locale; + private final float price; + + public FromFooAdvFields clone() throws CloneNotSupportedException { + return (FromFooAdvFields) super.clone(); + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooMap.java b/bull-core/src/test/java/com/hotels/beans/sample/FromFooMap.java new file mode 100644 index 000000000..cc7721358 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/FromFooMap.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.util.List; +import java.util.Map; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object containing extremely complex map. + */ +@AllArgsConstructor +@Getter +@ToString +public class FromFooMap { + private final Map sampleMap; + private final Map> complexMap; + private final Map> veryComplexMap; + private final Map> extremeComplexMap; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooSimple.java b/bull-core/src/test/java/com/hotels/beans/sample/FromFooSimple.java new file mode 100644 index 000000000..944a7d5bd --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/FromFooSimple.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Sample immutable object. + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class FromFooSimple { + public String name; + public BigInteger id; + + @Override + public String toString() { + return "FromFooSimple"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java b/bull-core/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java new file mode 100644 index 000000000..e5b34d849 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Sample object without getter methods. + */ +@NoArgsConstructor +@AllArgsConstructor +@Setter +public class FromFooSimpleNoGetters { + public String name; + public BigInteger id; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooSubClass.java b/bull-core/src/test/java/com/hotels/beans/sample/FromFooSubClass.java new file mode 100644 index 000000000..73171eaae --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/FromFooSubClass.java @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; + +import lombok.Getter; +import lombok.ToString; + +@Getter +@ToString +public class FromFooSubClass extends FromFoo { + private final String surname; + private final int phone; + private final boolean check; + private final BigDecimal amount; + + public FromFooSubClass(final String name, final BigInteger id, final List nestedObjectList, final List list, final FromSubFoo nestedObject, + final String surname, final int phone, final boolean check, final BigDecimal amount) { + super(name, id, nestedObjectList, list, nestedObject); + this.surname = surname; + this.phone = phone; + this.check = check; + this.amount = amount; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java b/bull-core/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java new file mode 100644 index 000000000..35ebf6aab --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object. + */ +@AllArgsConstructor +@Getter +@ToString +public class FromFooWithPrimitiveFields { + private final String name; + private final int id; + private final int age; + private final List nestedObjectList; + private final List list; + private final FromSubFoo nestedObject; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromSubFoo.java b/bull-core/src/test/java/com/hotels/beans/sample/FromSubFoo.java new file mode 100644 index 000000000..fdddae4b8 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/FromSubFoo.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.util.List; +import java.util.Map; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object. + */ +@AllArgsConstructor +@Getter +@ToString +public class FromSubFoo { + private final String name; + private final int[] phoneNumbers; + private final Map sampleMap; + private final Map> complexMap; + private final Map> veryComplexMap; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java new file mode 100644 index 000000000..4e70caf49 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object containing properties available in the source object inside other objects. + *

      + * e.g. phoneNumbers field is available inside FromFoo.nestedObject.phoneNumbers + *

      + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableFlatToFoo { + private final String name; + private final BigInteger id; + private final int[] phoneNumbers; + +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java new file mode 100644 index 000000000..0b68fa7ea --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigInteger; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Sample immutable object. + */ +@AllArgsConstructor +@Getter +public class ImmutableToFoo { + private final String name; + @NotNull + private final BigInteger id; + @NotNull + private final List list; + @NotNull + private final List nestedObjectList; + @NotNull + private final ImmutableToSubFoo nestedObject; + + @Override + public String toString() { + return "ImmutableToFoo"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java new file mode 100644 index 000000000..919e3fea7 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.util.Locale; +import java.util.Optional; + +import com.hotels.beans.constant.ClassType; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object. + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableToFooAdvFields { + private final Optional name; + private final Integer age; + private final String indexNumber; + private final ClassType classType; + private final Locale locale; + private final Price price; +} + +@AllArgsConstructor +@Getter +class Price { + private final float netPrice; + private final float grossPrice; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java new file mode 100644 index 000000000..a37c75802 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigInteger; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import com.hotels.beans.annotation.ConstructorArg; + +import lombok.ToString; + +/** + * Sample immutable object. + */ +@ToString +public class ImmutableToFooCustomAnnotation { + @NotNull + private final String name; + @NotNull + private final BigInteger id; + @NotNull + private final List list; + @NotNull + private final List nestedObjectList; + @NotNull + private final ImmutableToSubFooCustomAnnotation nestedObject; + + public ImmutableToFooCustomAnnotation(@ConstructorArg("name") final String name, + @ConstructorArg("id") final BigInteger id, + @ConstructorArg("list") final List list, + @ConstructorArg("nestedObjectList") final List nestedObjectList, + @ConstructorArg("nestedObject") final ImmutableToSubFooCustomAnnotation nestedObject) { + this.name = name; + this.id = id; + this.list = list; + this.nestedObjectList = nestedObjectList; + this.nestedObject = nestedObject; + } + + public String getName() { + return name; + } + + public BigInteger getId() { + return id; + } + + public List getList() { + return list; + } + + public List getNestedObjectList() { + return nestedObjectList; + } + + public ImmutableToSubFooCustomAnnotation getNestedObject() { + return nestedObject; + } +} + + diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java new file mode 100644 index 000000000..6fdf751c3 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigInteger; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object with different fields than source object. + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableToFooDiffFields { + @NotNull + private final String name; + + @NotNull + private final BigInteger identifier; + + @NotNull + private final List list; + + @NotNull + private final List nestedObjectList; + + @NotNull + private final ImmutableToSubFoo nestedObject; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java new file mode 100644 index 000000000..014863100 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigInteger; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import lombok.Getter; + +/** + * Sample immutable object with constructor containing parameter in a different order than expected. + */ +@Getter +public class ImmutableToFooInvalid { + @NotNull + private final String name; + @NotNull + private final BigInteger id; + + private final List list; + @NotNull + private final List nestedObjectList; + @NotNull + private final ImmutableToSubFoo nestedObject; + + /** + * Constructor. + */ + public ImmutableToFooInvalid(@NotNull final String name, @NotNull final BigInteger id, @NotNull final List nestedObjectList, + @NotNull final ImmutableToSubFoo nestedObject) { + this.name = name; + this.id = id; + this.list = null; + this.nestedObjectList = nestedObjectList; + this.nestedObject = nestedObject; + } + + @Override + public String toString() { + return "ImmutableToFooInvalid"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java new file mode 100644 index 000000000..190e0ed96 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.util.List; +import java.util.Map; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object containing extremely complex map. + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableToFooMap { + private final Map sampleMap; + private final Map> complexMap; + private final Map> veryComplexMap; + private final Map> extremeComplexMap; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java new file mode 100644 index 000000000..75d4d7d7a --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import javax.validation.constraints.NotNull; + +import com.hotels.beans.annotation.ConstructorArg; + +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object without all constructor's parameter annotated with {@link ConstructorArg}. + */ +@Getter +@ToString +public class ImmutableToFooMissingCustomAnnotation { + @NotNull + private final String name; + + private final int id; + + /** + * Constructor. + */ + public ImmutableToFooMissingCustomAnnotation(@ConstructorArg("name") final String name, final int id) { + this.name = name; + this.id = id; + } +} + + diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java new file mode 100644 index 000000000..4515faab2 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +/** + * Immutable object without constructor. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ImmutableToFooNoConstructors { +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java new file mode 100644 index 000000000..d5af1278b --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Sample immutable object that contains a field not existing in the source object. + */ +@AllArgsConstructor +@Getter +public class ImmutableToFooNotExistingFields { + private final String name; + private final BigInteger id; + private final int age; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java new file mode 100644 index 000000000..c93c28c6c --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Sample immutable object. + */ +@AllArgsConstructor +@Getter +public class ImmutableToFooSimple { + private final String name; + private final BigInteger id; + + @Override + public String toString() { + return "ImmutableToFooSimple"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java new file mode 100755 index 000000000..1a15f9947 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object with different field than the source object. + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableToFooSimpleWrongTypes { + private final Integer id; + private final String name; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java new file mode 100644 index 000000000..75829bfa5 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import lombok.Getter; + +/** + * Sample immutable object extending a class. + */ +@Getter +public class ImmutableToFooSubClass extends ImmutableToFoo { + @NotNull + private final String surname; + @NotNull + private final int phone; + @NotNull + private final boolean check; + @NotNull + private final BigDecimal amount; + + /** + * Constructor. + */ + public ImmutableToFooSubClass(final String name, final BigInteger id, final List list, + final List nestedObjectList, final ImmutableToSubFoo nestedObject, final String surname, + final int phone, final boolean check, final BigDecimal amount) { + super(name, id, list, nestedObjectList, nestedObject); + this.surname = surname; + this.phone = phone; + this.check = check; + this.amount = amount; + } + + @Override + public String toString() { + return "ImmutableToFooSubClass"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java new file mode 100644 index 000000000..5dbc13cd9 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.math.BigInteger; +import java.util.List; + +import com.hotels.beans.sample.FromSubFoo; + +import lombok.Builder; +import lombok.Getter; + +/** + * Immutable bean instantiable only through a Builder. + */ +@Getter +@Builder +public class ImmutableToFooWithBuilder { + private final String name; + private final BigInteger id; + private final List nestedObjectList; + private final List list; + private final FromSubFoo nestedObject; + + public ImmutableToFooWithBuilder(final String name, final BigInteger id, final List nestedObjectList, + final List list, final FromSubFoo nestedObject) { + this.name = name; + this.id = id; + this.nestedObjectList = nestedObjectList; + this.list = list; + this.nestedObject = nestedObject; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java new file mode 100644 index 000000000..e55119f6e --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.util.List; +import java.util.Map; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object. + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableToSubFoo { + private final String name; + private final int[] phoneNumbers; + private final Map sampleMap; + private final Map> complexMap; + private final Map> veryComplexMap; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java new file mode 100644 index 000000000..b4f281c76 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.util.List; +import java.util.Map; + +import javax.validation.constraints.NotNull; + +import com.hotels.beans.annotation.ConstructorArg; + +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object. + */ +@Getter +@ToString +public class ImmutableToSubFooCustomAnnotation { + @NotNull + private final String name; + private final int[] phoneNumbers; + private final Map sampleMap; + private final Map> complexMap; + private final Map> veryComplexMap; + + /** + * Constructor. + * @param name name + */ + public ImmutableToSubFooCustomAnnotation(@ConstructorArg("name") final String name, @ConstructorArg("phoneNumbers") final int[] phoneNumbers, + @ConstructorArg("sampleMap") final Map sampleMap, @ConstructorArg("complexMap") final Map> complexMap, + @ConstructorArg("veryComplexMap") final Map> veryComplexMap) { + this.name = name; + this.phoneNumbers = phoneNumbers; + this.sampleMap = sampleMap; + this.complexMap = complexMap; + this.veryComplexMap = veryComplexMap; + } +} + + diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/package-info.java b/bull-core/src/test/java/com/hotels/beans/sample/immutable/package-info.java new file mode 100644 index 000000000..64a546785 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/immutable/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Immutable Bean package. + */ + +package com.hotels.beans.sample.immutable; diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java new file mode 100644 index 000000000..837d853a8 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mixed; + +import java.math.BigInteger; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import com.hotels.beans.sample.immutable.ImmutableToSubFoo; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mixed object. + */ +@AllArgsConstructor +@Getter +@Setter +public class MixedToFoo { + @NotNull + public BigInteger id; + private final String name; + private final List list; + private final List nestedObjectList; + private ImmutableToSubFoo nestedObject; + + @Override + public String toString() { + return "MixedToFoo"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java new file mode 100644 index 000000000..49f6d4479 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mixed; + +import java.math.BigInteger; +import java.util.List; + +import com.hotels.beans.annotation.ConstructorArg; +import com.hotels.beans.sample.immutable.ImmutableToSubFoo; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * Sample mixed object with different column names. + */ +@Getter +@Setter +@ToString +public class MixedToFooDiffFields { + private String name; + private final BigInteger identifier; + private final List list; + private final List nestedObjectList; + private ImmutableToSubFoo nestedObject; + + public MixedToFooDiffFields(@ConstructorArg("name") final String name, + @ConstructorArg("identifier") final BigInteger identifier, + @ConstructorArg("list") final List list, @ConstructorArg("nestedObjectList") final List nestedObjectList, + @ConstructorArg("nestedObject") final ImmutableToSubFoo nestedObject) { + this.name = name; + this.identifier = identifier; + this.list = list; + this.nestedObjectList = nestedObjectList; + this.nestedObject = nestedObject; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java new file mode 100644 index 000000000..79954b25e --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mixed; + +import java.math.BigInteger; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import com.hotels.beans.sample.immutable.ImmutableToSubFoo; + +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mixed object with a constructor containing the final fields only. + */ +@Getter +@Setter +public class MixedToFooMissingAllArgsConstructor { + @NotNull + public BigInteger id; + private final String name; + private final List list; + private final List nestedObjectList; + private ImmutableToSubFoo nestedObject; + + /** + * Constructor for final fields only. + */ + public MixedToFooMissingAllArgsConstructor(final String name, final List list, final List nestedObjectList) { + this.name = name; + this.list = list; + this.nestedObjectList = nestedObjectList; + } + + @Override + public String toString() { + return "MixedToFooMissingAllArgsConstructor"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java new file mode 100644 index 000000000..a359699e1 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mixed; + +import java.math.BigInteger; + +import javax.validation.constraints.NotNull; + +import lombok.Getter; +import lombok.ToString; + +/** + * Sample mixed object with missing default constructor. + */ +@Getter +@ToString +public class MixedToFooMissingConstructor { + @NotNull + public BigInteger id; + private final String name; + + public MixedToFooMissingConstructor(final String name) { + this.name = name; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java new file mode 100644 index 000000000..3140d2453 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mixed; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample mixed object with different column names. + */ +@Getter +@AllArgsConstructor +@ToString +public class MixedToFooMissingField { + private final String name; + private final BigInteger id; + private final String fooField; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java new file mode 100644 index 000000000..65d398d68 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mixed; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mixed object that contains a field not existing in the source object. + */ +@AllArgsConstructor +@Getter +@Setter +public class MixedToFooNotExistingFields { + private final String name; + private final BigInteger id; + private int age; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java new file mode 100644 index 000000000..35a90647f --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mixed; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * Mixed bean class containing a static fields. + */ +@Getter +@Setter +@ToString +public class MixedToFooStaticField { + private static final int STATIC_FIELD = 0; + private String normalField; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java new file mode 100644 index 000000000..3b5f0d025 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mixed; + +import java.math.BigInteger; +import java.util.List; + +import com.hotels.beans.sample.immutable.ImmutableToSubFoo; + +import lombok.Builder; +import lombok.Getter; + +/** + * Mixed bean instantiable only through a Builder. + */ +@Getter +@Builder +public class MixedToFooWithBuilder { + private final String name; + private BigInteger id; + private final List nestedObjectList; + private final List list; + private final ImmutableToSubFoo nestedObject; + + public MixedToFooWithBuilder(final String name, final BigInteger id, final List nestedObjectList, + final List list, final ImmutableToSubFoo nestedObject) { + this.name = name; + this.id = id; + this.nestedObjectList = nestedObjectList; + this.list = list; + this.nestedObject = nestedObject; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/package-info.java b/bull-core/src/test/java/com/hotels/beans/sample/mixed/package-info.java new file mode 100644 index 000000000..c743ab584 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mixed/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Mixed Bean package. + */ + +package com.hotels.beans.sample.mixed; diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java new file mode 100644 index 000000000..a73ee9e57 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.math.BigInteger; +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mutable object. + */ +@Getter +@Setter +public class MutableToFoo { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + @Override + public String toString() { + return "MutableToFoo"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java new file mode 100644 index 000000000..1a90e991c --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.util.Locale; +import java.util.Optional; + +import com.hotels.beans.constant.ClassType; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * Sample mutable object containing special fields. + */ +@Getter +@Setter +@ToString +public class MutableToFooAdvFields { + private Optional name; + private Optional age; + private String indexNumber; + private ClassType classType; + private Locale locale; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java new file mode 100644 index 000000000..bcdaede18 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.math.BigInteger; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mutable object. + */ +@Getter +@Setter +@AllArgsConstructor +public class MutableToFooInvalid { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + @Override + public String toString() { + return "MutableToFooInvalid"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java new file mode 100644 index 000000000..ea337939d --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.math.BigInteger; + +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mutable object that contains a field not existing in the source object. + */ +@Getter +@Setter +public class MutableToFooNotExistingFields { + private String name; + private BigInteger id; + private int age; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java new file mode 100644 index 000000000..8e33a8a56 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.math.BigInteger; + +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mutable object. + */ +@Getter +@Setter +public class MutableToFooSimple { + private String name; + private BigInteger id; + + @Override + public String toString() { + return "MutableToFooSimple"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java new file mode 100644 index 000000000..39830a2e6 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.math.BigInteger; + +import lombok.Getter; + +/** + * Sample mutable object without setter methods. + */ +@Getter +public class MutableToFooSimpleNoSetters { + private String name; + private BigInteger id; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java new file mode 100644 index 000000000..1e4e81c21 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.math.BigDecimal; + +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mutable object extending a class. + */ +@Getter +@Setter +public class MutableToFooSubClass extends MutableToFoo { + private String surname; + private int phone; + private boolean check; + private BigDecimal amount; + + @Override + public String toString() { + return "MutableToFooSubClass"; + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java new file mode 100644 index 000000000..ada9bc7b0 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.math.BigInteger; +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +/** + * Mutable object instantiable only through a Builder. + */ +@Getter +@Setter +public final class MutableToFooWithBuilder { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + private MutableToFooWithBuilder() { + } + + public static class Builder { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + public Builder withName(final String name) { + this.name = name; + return this; + } + + public Builder withId(final BigInteger id) { + this.id = id; + return this; + } + + public MutableToFooWithBuilder build() { + MutableToFooWithBuilder mutableToFooWithBuilder = new MutableToFooWithBuilder(); + mutableToFooWithBuilder.id = this.id; + mutableToFooWithBuilder.name = this.name; + mutableToFooWithBuilder.list = this.list; + mutableToFooWithBuilder.nestedObjectList = this.nestedObjectList; + mutableToFooWithBuilder.nestedObject = this.nestedObject; + return mutableToFooWithBuilder; + } + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java new file mode 100644 index 000000000..98423f770 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.math.BigInteger; +import java.util.List; + +import lombok.Getter; + +/** + * Mutable object instantiable only through a Builder. + * The Builder class contains multiple constructors. + */ +@Getter +public final class MutableToFooWithBuilderMultipleConstructor { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + /** + * Private constructor. + */ + private MutableToFooWithBuilderMultipleConstructor() { + } + + static class Builder { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + Builder(final String name) { + this.name = name; + } + + Builder() { + } + + public Builder withName(final String name) { + this.name = name; + return this; + } + + public Builder withId(final BigInteger id) { + this.id = id; + return this; + } + + public MutableToFooWithBuilderMultipleConstructor build() { + MutableToFooWithBuilderMultipleConstructor builderToFoo = new MutableToFooWithBuilderMultipleConstructor(); + builderToFoo.id = this.id; + builderToFoo.name = this.name; + builderToFoo.list = this.list; + builderToFoo.nestedObjectList = this.nestedObjectList; + builderToFoo.nestedObject = this.nestedObject; + return builderToFoo; + } + } +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java new file mode 100644 index 000000000..ba52ad7c3 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.util.List; +import java.util.Map; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * Sample mutable object. + */ +@Getter +@Setter +@ToString +public class MutableToSubFoo { + private String name; + private int[] phoneNumbers; + private Map sampleMap; + private Map> complexMap; + private Map> veryComplexMap; +} diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/package-info.java b/bull-core/src/test/java/com/hotels/beans/sample/mutable/package-info.java new file mode 100644 index 000000000..c4f792139 --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/mutable/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Mutable Bean package. + */ + +package com.hotels.beans.sample.mutable; diff --git a/bull-core/src/test/java/com/hotels/beans/sample/package-info.java b/bull-core/src/test/java/com/hotels/beans/sample/package-info.java new file mode 100644 index 000000000..1cfa2332f --- /dev/null +++ b/bull-core/src/test/java/com/hotels/beans/sample/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Sample Bean object for test purpose. + */ + +package com.hotels.beans.sample; diff --git a/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bull-core/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java similarity index 100% rename from src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java rename to bull-core/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java diff --git a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-core/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java similarity index 99% rename from src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java rename to bull-core/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index bf7ce369e..1e46089df 100644 --- a/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-core/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -16,8 +16,8 @@ package com.hotels.beans.transformer; -import static org.mockito.MockitoAnnotations.initMocks; import static org.junit.Assert.assertThat; +import static org.mockito.MockitoAnnotations.initMocks; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; @@ -26,11 +26,10 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.mutable.MutableToFooWithBuilderMultipleConstructor; -import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; -import com.hotels.beans.sample.mixed.MixedToFooWithBuilder; import com.hotels.beans.sample.immutable.ImmutableToFooWithBuilder; - +import com.hotels.beans.sample.mixed.MixedToFooWithBuilder; +import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; +import com.hotels.beans.sample.mutable.MutableToFooWithBuilderMultipleConstructor; /** * Unit test for all {@link Transformer} functions related to Object based on Builder Pattern. diff --git a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-core/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java similarity index 99% rename from src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java rename to bull-core/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 39e1a51cb..15db8ce35 100644 --- a/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-core/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -330,7 +330,7 @@ private Object[][] dataAdvancedFieldsCopyTesting() throws CloneNotSupportedExcep /** * Test that immutable bean containing a constructor with some field not annotated with - * {@link com.hotels.beans.annotation.ConstructorArg} is correctly copied. + * {@link ConstructorArg} is correctly copied. */ @Test public void testImmutableBeanWithMissingConstructorArgIsCorrectlyCopied() { diff --git a/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-core/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java similarity index 100% rename from src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java rename to bull-core/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java diff --git a/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-core/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java similarity index 100% rename from src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java rename to bull-core/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java diff --git a/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bull-core/src/test/java/com/hotels/beans/transformer/TransformerTest.java similarity index 100% rename from src/test/java/com/hotels/beans/transformer/TransformerTest.java rename to bull-core/src/test/java/com/hotels/beans/transformer/TransformerTest.java diff --git a/src/test/java/com/hotels/beans/transformer/package-info.java b/bull-core/src/test/java/com/hotels/beans/transformer/package-info.java similarity index 100% rename from src/test/java/com/hotels/beans/transformer/package-info.java rename to bull-core/src/test/java/com/hotels/beans/transformer/package-info.java diff --git a/bull-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/bull-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/pom.xml b/pom.xml index c70d0c0df..eb8caabb6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ bean-utils-library https://github.com/HotelsDotCom/bull 1.4.2-SNAPSHOT - jar + pom 2019 This BeanUtils library is a Java Bean to Java Bean transformer that recursively copies data from one object to @@ -14,13 +14,18 @@ incredibly fast. It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. - com.hotels hotels-oss-parent 4.0.1 + + bull-common + bull-converter + bull-core + + UTF-8 UTF-8 @@ -148,7 +153,7 @@ false true - false + true true false @@ -212,7 +217,8 @@ - + + org.apache.maven.plugins maven-compiler-plugin @@ -446,6 +452,21 @@ + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + generate-javadoc + + aggregate-jar + + + + + @@ -455,6 +476,14 @@ public + + + aggregate + + aggregate + + + From f3120c9897c07d3a78c961642c698a6346adcae1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 May 2019 18:27:08 +0200 Subject: [PATCH 0556/1786] - Updated maven javadoc library - Modified dependency structure --- {bull-core => bean-utils-library}/pom.xml | 15 +- .../main/java/com/hotels/beans/BeanUtils.java | 0 .../com/hotels/beans/model/FieldMapping.java | 0 .../hotels/beans/model/FieldTransformer.java | 0 .../com/hotels/beans/model/package-info.java | 0 .../java/com/hotels/beans/package-info.java | 0 .../beans/populator/ArrayPopulator.java | 0 .../beans/populator/CollectionPopulator.java | 0 .../beans/populator/ICollectionPopulator.java | 0 .../hotels/beans/populator/MapPopulator.java | 0 .../beans/populator/OptionalPopulator.java | 0 .../com/hotels/beans/populator/Populator.java | 0 .../beans/populator/PopulatorFactory.java | 0 .../hotels/beans/populator/package-info.java | 0 .../transformer/AbstractTransformer.java | 0 .../hotels/beans/transformer/Transformer.java | 0 .../beans/transformer/TransformerImpl.java | 0 .../transformer/TransformerSettings.java | 0 .../beans/transformer/package-info.java | 0 .../src/main/resources/banner.txt | 0 .../main/resources/config/application-dev.yml | 0 .../src/main/resources/config/application.yml | 0 .../config/logging/logback-appenders.xml | 0 .../config/logging/logback-properties.xml | 0 .../src/main/resources/logback-test.xml | 0 .../src/main/resources/logback.xml | 0 .../java/com/hotels/beans/BeanUtilsTest.java | 0 .../java/com/hotels/beans/package-info.java | 0 .../beans/performance/PerformanceTest.java | 0 .../beans/performance/package-info.java | 0 .../beans/populator/ArrayPopulatorTest.java | 0 .../beans/populator/PopulatorFactoryTest.java | 0 .../hotels/beans/populator/package-info.java | 0 .../hotels/beans/sample/AbstractClass.java | 0 .../java/com/hotels/beans/sample/FromFoo.java | 0 .../hotels/beans/sample/FromFooAdvFields.java | 0 .../com/hotels/beans/sample/FromFooMap.java | 0 .../hotels/beans/sample/FromFooSimple.java | 0 .../beans/sample/FromFooSimpleNoGetters.java | 0 .../hotels/beans/sample/FromFooSubClass.java | 0 .../sample/FromFooWithPrimitiveFields.java | 0 .../com/hotels/beans/sample/FromSubFoo.java | 0 .../sample/immutable/ImmutableFlatToFoo.java | 0 .../sample/immutable/ImmutableToFoo.java | 0 .../immutable/ImmutableToFooAdvFields.java | 0 .../ImmutableToFooCustomAnnotation.java | 0 .../immutable/ImmutableToFooDiffFields.java | 0 .../immutable/ImmutableToFooInvalid.java | 0 .../sample/immutable/ImmutableToFooMap.java | 0 ...ImmutableToFooMissingCustomAnnotation.java | 0 .../ImmutableToFooNoConstructors.java | 0 .../ImmutableToFooNotExistingFields.java | 0 .../immutable/ImmutableToFooSimple.java | 0 .../ImmutableToFooSimpleWrongTypes.java | 0 .../immutable/ImmutableToFooSubClass.java | 0 .../immutable/ImmutableToFooWithBuilder.java | 0 .../sample/immutable/ImmutableToSubFoo.java | 0 .../ImmutableToSubFooCustomAnnotation.java | 0 .../beans/sample/immutable/package-info.java | 0 .../hotels/beans/sample/mixed/MixedToFoo.java | 0 .../sample/mixed/MixedToFooDiffFields.java | 0 .../MixedToFooMissingAllArgsConstructor.java | 0 .../mixed/MixedToFooMissingConstructor.java | 0 .../sample/mixed/MixedToFooMissingField.java | 0 .../mixed/MixedToFooNotExistingFields.java | 0 .../sample/mixed/MixedToFooStaticField.java | 0 .../sample/mixed/MixedToFooWithBuilder.java | 0 .../beans/sample/mixed/package-info.java | 0 .../beans/sample/mutable/MutableToFoo.java | 0 .../sample/mutable/MutableToFooAdvFields.java | 0 .../sample/mutable/MutableToFooInvalid.java | 0 .../MutableToFooNotExistingFields.java | 0 .../sample/mutable/MutableToFooSimple.java | 0 .../mutable/MutableToFooSimpleNoSetters.java | 0 .../sample/mutable/MutableToFooSubClass.java | 0 .../mutable/MutableToFooWithBuilder.java | 0 ...leToFooWithBuilderMultipleConstructor.java | 0 .../beans/sample/mutable/MutableToSubFoo.java | 0 .../beans/sample/mutable/package-info.java | 0 .../com/hotels/beans/sample/package-info.java | 0 .../transformer/AbstractTransformerTest.java | 0 .../BuilderObjectTransformationTest.java | 0 .../ImmutableObjectTransformationTest.java | 0 .../MixedObjectTransformationTest.java | 0 .../MutableObjectTransformationTest.java | 0 .../beans/transformer/TransformerTest.java | 0 .../beans/transformer/package-info.java | 0 .../org.mockito.plugins.MockMaker | 0 bull-common/pom.xml | 29 +++- bull-converter/pom.xml | 2 +- pom.xml | 129 +++++++++++------- 91 files changed, 116 insertions(+), 59 deletions(-) rename {bull-core => bean-utils-library}/pom.xml (74%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/BeanUtils.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/model/FieldMapping.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/model/FieldTransformer.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/model/package-info.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/package-info.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/populator/ArrayPopulator.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/populator/CollectionPopulator.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/populator/MapPopulator.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/populator/OptionalPopulator.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/populator/Populator.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/populator/PopulatorFactory.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/populator/package-info.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/transformer/Transformer.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/transformer/TransformerImpl.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/transformer/TransformerSettings.java (100%) rename {bull-core => bean-utils-library}/src/main/java/com/hotels/beans/transformer/package-info.java (100%) rename {bull-core => bean-utils-library}/src/main/resources/banner.txt (100%) rename {bull-core => bean-utils-library}/src/main/resources/config/application-dev.yml (100%) rename {bull-core => bean-utils-library}/src/main/resources/config/application.yml (100%) rename {bull-core => bean-utils-library}/src/main/resources/config/logging/logback-appenders.xml (100%) rename {bull-core => bean-utils-library}/src/main/resources/config/logging/logback-properties.xml (100%) rename {bull-core => bean-utils-library}/src/main/resources/logback-test.xml (100%) rename {bull-core => bean-utils-library}/src/main/resources/logback.xml (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/BeanUtilsTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/package-info.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/performance/PerformanceTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/performance/package-info.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/populator/package-info.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/AbstractClass.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/FromFoo.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/FromFooMap.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/FromFooSimple.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/FromFooSubClass.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/FromSubFoo.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/immutable/package-info.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mixed/package-info.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/mutable/package-info.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/sample/package-info.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/transformer/TransformerTest.java (100%) rename {bull-core => bean-utils-library}/src/test/java/com/hotels/beans/transformer/package-info.java (100%) rename {bull-core => bean-utils-library}/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker (100%) diff --git a/bull-core/pom.xml b/bean-utils-library/pom.xml similarity index 74% rename from bull-core/pom.xml rename to bean-utils-library/pom.xml index ab4548517..151c1b060 100644 --- a/bull-core/pom.xml +++ b/bean-utils-library/pom.xml @@ -3,12 +3,12 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - bull-core + bean-utils-library jar com.hotels.beans - bean-utils-library + bean-utils-library-parent 1.4.2-SNAPSHOT @@ -23,10 +23,11 @@ bull-converter ${project.version} + + + com.shazam + shazamcrest + test + - - - - ${parent.artifactId}-${project.version} - \ No newline at end of file diff --git a/bull-core/src/main/java/com/hotels/beans/BeanUtils.java b/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/BeanUtils.java rename to bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java diff --git a/bull-core/src/main/java/com/hotels/beans/model/FieldMapping.java b/bean-utils-library/src/main/java/com/hotels/beans/model/FieldMapping.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/model/FieldMapping.java rename to bean-utils-library/src/main/java/com/hotels/beans/model/FieldMapping.java diff --git a/bull-core/src/main/java/com/hotels/beans/model/FieldTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/model/FieldTransformer.java rename to bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java diff --git a/bull-core/src/main/java/com/hotels/beans/model/package-info.java b/bean-utils-library/src/main/java/com/hotels/beans/model/package-info.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/model/package-info.java rename to bean-utils-library/src/main/java/com/hotels/beans/model/package-info.java diff --git a/bull-core/src/main/java/com/hotels/beans/package-info.java b/bean-utils-library/src/main/java/com/hotels/beans/package-info.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/package-info.java rename to bean-utils-library/src/main/java/com/hotels/beans/package-info.java diff --git a/bull-core/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/populator/ArrayPopulator.java rename to bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java diff --git a/bull-core/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/CollectionPopulator.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/populator/CollectionPopulator.java rename to bean-utils-library/src/main/java/com/hotels/beans/populator/CollectionPopulator.java diff --git a/bull-core/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java rename to bean-utils-library/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java diff --git a/bull-core/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/populator/MapPopulator.java rename to bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java diff --git a/bull-core/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/OptionalPopulator.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/populator/OptionalPopulator.java rename to bean-utils-library/src/main/java/com/hotels/beans/populator/OptionalPopulator.java diff --git a/bull-core/src/main/java/com/hotels/beans/populator/Populator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/populator/Populator.java rename to bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java diff --git a/bull-core/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/PopulatorFactory.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/populator/PopulatorFactory.java rename to bean-utils-library/src/main/java/com/hotels/beans/populator/PopulatorFactory.java diff --git a/bull-core/src/main/java/com/hotels/beans/populator/package-info.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/package-info.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/populator/package-info.java rename to bean-utils-library/src/main/java/com/hotels/beans/populator/package-info.java diff --git a/bull-core/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java rename to bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java diff --git a/bull-core/src/main/java/com/hotels/beans/transformer/Transformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/transformer/Transformer.java rename to bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java diff --git a/bull-core/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/transformer/TransformerImpl.java rename to bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java diff --git a/bull-core/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/transformer/TransformerSettings.java rename to bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java diff --git a/bull-core/src/main/java/com/hotels/beans/transformer/package-info.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/package-info.java similarity index 100% rename from bull-core/src/main/java/com/hotels/beans/transformer/package-info.java rename to bean-utils-library/src/main/java/com/hotels/beans/transformer/package-info.java diff --git a/bull-core/src/main/resources/banner.txt b/bean-utils-library/src/main/resources/banner.txt similarity index 100% rename from bull-core/src/main/resources/banner.txt rename to bean-utils-library/src/main/resources/banner.txt diff --git a/bull-core/src/main/resources/config/application-dev.yml b/bean-utils-library/src/main/resources/config/application-dev.yml similarity index 100% rename from bull-core/src/main/resources/config/application-dev.yml rename to bean-utils-library/src/main/resources/config/application-dev.yml diff --git a/bull-core/src/main/resources/config/application.yml b/bean-utils-library/src/main/resources/config/application.yml similarity index 100% rename from bull-core/src/main/resources/config/application.yml rename to bean-utils-library/src/main/resources/config/application.yml diff --git a/bull-core/src/main/resources/config/logging/logback-appenders.xml b/bean-utils-library/src/main/resources/config/logging/logback-appenders.xml similarity index 100% rename from bull-core/src/main/resources/config/logging/logback-appenders.xml rename to bean-utils-library/src/main/resources/config/logging/logback-appenders.xml diff --git a/bull-core/src/main/resources/config/logging/logback-properties.xml b/bean-utils-library/src/main/resources/config/logging/logback-properties.xml similarity index 100% rename from bull-core/src/main/resources/config/logging/logback-properties.xml rename to bean-utils-library/src/main/resources/config/logging/logback-properties.xml diff --git a/bull-core/src/main/resources/logback-test.xml b/bean-utils-library/src/main/resources/logback-test.xml similarity index 100% rename from bull-core/src/main/resources/logback-test.xml rename to bean-utils-library/src/main/resources/logback-test.xml diff --git a/bull-core/src/main/resources/logback.xml b/bean-utils-library/src/main/resources/logback.xml similarity index 100% rename from bull-core/src/main/resources/logback.xml rename to bean-utils-library/src/main/resources/logback.xml diff --git a/bull-core/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/BeanUtilsTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/package-info.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/package-info.java rename to bean-utils-library/src/test/java/com/hotels/beans/package-info.java diff --git a/bull-core/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/performance/PerformanceTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/performance/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/performance/package-info.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/performance/package-info.java rename to bean-utils-library/src/test/java/com/hotels/beans/performance/package-info.java diff --git a/bull-core/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bean-utils-library/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/populator/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/populator/package-info.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/populator/package-info.java rename to bean-utils-library/src/test/java/com/hotels/beans/populator/package-info.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/AbstractClass.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/AbstractClass.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/AbstractClass.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/AbstractClass.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFoo.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/FromFoo.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/FromFoo.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooMap.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooMap.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/FromFooMap.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooMap.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooSimple.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimple.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/FromFooSimple.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimple.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooSubClass.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSubClass.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/FromFooSubClass.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSubClass.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/FromSubFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromSubFoo.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/FromSubFoo.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/FromSubFoo.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/immutable/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/package-info.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/immutable/package-info.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/package-info.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mixed/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/package-info.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mixed/package-info.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/package-info.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/mutable/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/package-info.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/mutable/package-info.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/package-info.java diff --git a/bull-core/src/test/java/com/hotels/beans/sample/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/package-info.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/sample/package-info.java rename to bean-utils-library/src/test/java/com/hotels/beans/sample/package-info.java diff --git a/bull-core/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/transformer/TransformerTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java diff --git a/bull-core/src/test/java/com/hotels/beans/transformer/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/package-info.java similarity index 100% rename from bull-core/src/test/java/com/hotels/beans/transformer/package-info.java rename to bean-utils-library/src/test/java/com/hotels/beans/transformer/package-info.java diff --git a/bull-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bean-utils-library/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker similarity index 100% rename from bull-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker rename to bean-utils-library/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 41124ec74..6d4d495aa 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -8,9 +8,36 @@ Contains all classes required from more than one module - bean-utils-library com.hotels.beans + bean-utils-library-parent 1.4.2-SNAPSHOT + + + org.apache.commons + commons-lang3 + + + + javax.validation + validation-api + ${validation-api.version} + + + javax.el + javax.el-api + ${javax.el-api.version} + + + org.glassfish.web + javax.el + ${glassfish.javax.el.version} + + + org.hibernate.validator + hibernate-validator + ${hibernate-validator.version} + + \ No newline at end of file diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 2f3ce4d3c..6b625be47 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans - bean-utils-library + bean-utils-library-parent 1.4.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index eb8caabb6..b206d9161 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 BULL - Bean Utils Light Library com.hotels.beans - bean-utils-library + bean-utils-library-parent https://github.com/HotelsDotCom/bull 1.4.2-SNAPSHOT pom @@ -23,7 +23,7 @@ bull-common bull-converter - bull-core + bean-utils-library @@ -33,6 +33,7 @@ ${jdk.version} ${jdk.version} 3.12.0 + 3.1.0 2.1.5.RELEASE 1.18.8 3.9 @@ -77,68 +78,95 @@ + + + + com.hotels.beans + bull-common + ${project.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + org.apache.commons + commons-lang3 + ${apache.commons-lang3.version} + + + + javax.validation + validation-api + ${validation-api.version} + + + javax.el + javax.el-api + ${javax.el-api.version} + + + org.glassfish.web + javax.el + ${glassfish.javax.el.version} + + + org.hibernate.validator + hibernate-validator + ${hibernate-validator.version} + + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + + + org.slf4j + slf4j-api + ${slf4j-api.version} + test + + + com.shazam + shazamcrest + ${shazamcrest.version} + test + + + com.google.code.gson + gson + ${gson.version} + test + + + org.testng + testng + ${testng.version} + test + + + + + org.projectlombok lombok - ${lombok.version} provided - - org.apache.commons - commons-lang3 - ${apache.commons-lang3.version} - - - - javax.validation - validation-api - ${validation-api.version} - - - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish.web - javax.el - ${glassfish.javax.el.version} - - - org.hibernate.validator - hibernate-validator - ${hibernate-validator.version} - org.springframework.boot spring-boot-starter-test - ${spring-boot.version} - test - - - org.slf4j - slf4j-api - ${slf4j-api.version} - test - - - com.shazam - shazamcrest - ${shazamcrest.version} - test - - - com.google.code.gson - gson - ${gson.version} test org.testng testng - ${testng.version} test @@ -153,7 +181,7 @@ false true - true + false true false @@ -217,6 +245,7 @@ + ${project.artifactId}-${project.version} From b35c710c182737ff42910537bad997c5f2f7ed9d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 May 2019 18:30:27 +0200 Subject: [PATCH 0557/1786] Added module name definition --- bean-utils-library/pom.xml | 1 + bull-common/pom.xml | 1 + bull-converter/pom.xml | 1 + pom.xml | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 151c1b060..2752c1f36 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -3,6 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + BULL - Bean Utils Light Library bean-utils-library jar diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 6d4d495aa..8c646d0ef 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -3,6 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + BULL - Common bull-common jar Contains all classes required from more than one module diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 6b625be47..fdf339b79 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -3,6 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + BULL - Converter bull-converter jar Provides the conversion related classes diff --git a/pom.xml b/pom.xml index b206d9161..ff89afc4a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - BULL - Bean Utils Light Library + BULL - Parent module com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull From d50ce964e0206b3e5433b10a4bc036ba6de6bcea Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 May 2019 22:27:53 +0200 Subject: [PATCH 0558/1786] Modified module configuration in order to have testing sample classes in a single module --- bean-utils-library/pom.xml | 7 ++ .../hotels/beans/sample/AbstractClass.java | 32 -------- .../java/com/hotels/beans/sample/FromFoo.java | 47 ----------- .../hotels/beans/sample/FromFooAdvFields.java | 46 ----------- .../com/hotels/beans/sample/FromFooMap.java | 37 --------- .../hotels/beans/sample/FromFooSimple.java | 41 ---------- .../beans/sample/FromFooSimpleNoGetters.java | 34 -------- .../hotels/beans/sample/FromFooSubClass.java | 42 ---------- .../sample/FromFooWithPrimitiveFields.java | 38 --------- .../com/hotels/beans/sample/FromSubFoo.java | 38 --------- .../sample/immutable/ImmutableFlatToFoo.java | 39 ---------- .../sample/immutable/ImmutableToFoo.java | 47 ----------- .../immutable/ImmutableToFooAdvFields.java | 48 ------------ .../ImmutableToFooCustomAnnotation.java | 77 ------------------- .../immutable/ImmutableToFooDiffFields.java | 49 ------------ .../immutable/ImmutableToFooInvalid.java | 58 -------------- .../sample/immutable/ImmutableToFooMap.java | 37 --------- ...ImmutableToFooMissingCustomAnnotation.java | 46 ----------- .../ImmutableToFooNoConstructors.java | 27 ------- .../ImmutableToFooNotExistingFields.java | 33 -------- .../immutable/ImmutableToFooSimple.java | 37 --------- .../ImmutableToFooSimpleWrongTypes.java | 32 -------- .../immutable/ImmutableToFooSubClass.java | 58 -------------- .../immutable/ImmutableToFooWithBuilder.java | 47 ----------- .../sample/immutable/ImmutableToSubFoo.java | 38 --------- .../ImmutableToSubFooCustomAnnotation.java | 57 -------------- .../beans/sample/immutable/package-info.java | 20 ----- .../hotels/beans/sample/mixed/MixedToFoo.java | 48 ------------ .../sample/mixed/MixedToFooDiffFields.java | 52 ------------- .../MixedToFooMissingAllArgsConstructor.java | 55 ------------- .../mixed/MixedToFooMissingConstructor.java | 39 ---------- .../sample/mixed/MixedToFooMissingField.java | 35 --------- .../mixed/MixedToFooNotExistingFields.java | 35 --------- .../sample/mixed/MixedToFooStaticField.java | 32 -------- .../sample/mixed/MixedToFooWithBuilder.java | 47 ----------- .../beans/sample/mixed/package-info.java | 20 ----- .../beans/sample/mutable/MutableToFoo.java | 41 ---------- .../sample/mutable/MutableToFooAdvFields.java | 40 ---------- .../sample/mutable/MutableToFooInvalid.java | 43 ----------- .../MutableToFooNotExistingFields.java | 33 -------- .../sample/mutable/MutableToFooSimple.java | 37 --------- .../mutable/MutableToFooSimpleNoSetters.java | 30 -------- .../sample/mutable/MutableToFooSubClass.java | 39 ---------- .../mutable/MutableToFooWithBuilder.java | 67 ---------------- ...leToFooWithBuilderMultipleConstructor.java | 76 ------------------ .../beans/sample/mutable/MutableToSubFoo.java | 38 --------- .../beans/sample/mutable/package-info.java | 20 ----- .../com/hotels/beans/sample/package-info.java | 20 ----- bull-common/pom.xml | 15 ++++ pom.xml | 63 ++++++++++----- 50 files changed, 67 insertions(+), 1970 deletions(-) delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/AbstractClass.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/FromFoo.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooMap.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimple.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSubClass.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/FromSubFoo.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java delete mode 100755 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/package-info.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/package-info.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/package-info.java delete mode 100644 bean-utils-library/src/test/java/com/hotels/beans/sample/package-info.java diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 2752c1f36..0d6495e13 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -25,6 +25,13 @@ ${project.version} + + com.hotels.beans + bull-common + ${project.version} + test-jar + test + com.shazam shazamcrest diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/AbstractClass.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/AbstractClass.java deleted file mode 100644 index adba701d9..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/AbstractClass.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.math.BigInteger; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * Abstract class for testing purpose. - */ -@AllArgsConstructor -@Getter -public abstract class AbstractClass { - private final String name; - private final BigInteger id; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFoo.java deleted file mode 100644 index d9662e008..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFoo.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.math.BigInteger; -import java.util.List; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; - -/** - * Sample immutable object. - */ -@AllArgsConstructor -@Getter -@Setter -public class FromFoo implements Cloneable { - private final String name; - private BigInteger id; - private final List nestedObjectList; - private final List list; - private final FromSubFoo nestedObject; - - public FromFoo clone() throws CloneNotSupportedException { - return (FromFoo) super.clone(); - } - - @Override - public String toString() { - return "FromFoo"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java deleted file mode 100644 index 1c197b967..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.util.Optional; - -import com.hotels.beans.constant.ClassType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * Sample object containing java advanced fields. - */ -@AllArgsConstructor -@Getter -@Setter -@ToString -public class FromFooAdvFields implements Cloneable { - private Optional name; - private final Optional age; - private final String indexNumber; - private final ClassType classType; - private final String locale; - private final float price; - - public FromFooAdvFields clone() throws CloneNotSupportedException { - return (FromFooAdvFields) super.clone(); - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooMap.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooMap.java deleted file mode 100644 index cc7721358..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooMap.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.util.List; -import java.util.Map; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object containing extremely complex map. - */ -@AllArgsConstructor -@Getter -@ToString -public class FromFooMap { - private final Map sampleMap; - private final Map> complexMap; - private final Map> veryComplexMap; - private final Map> extremeComplexMap; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimple.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimple.java deleted file mode 100644 index 944a7d5bd..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimple.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.math.BigInteger; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -/** - * Sample immutable object. - */ -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -public class FromFooSimple { - public String name; - public BigInteger id; - - @Override - public String toString() { - return "FromFooSimple"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java deleted file mode 100644 index e5b34d849..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.math.BigInteger; - -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.Setter; - -/** - * Sample object without getter methods. - */ -@NoArgsConstructor -@AllArgsConstructor -@Setter -public class FromFooSimpleNoGetters { - public String name; - public BigInteger id; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSubClass.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSubClass.java deleted file mode 100644 index 73171eaae..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooSubClass.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.List; - -import lombok.Getter; -import lombok.ToString; - -@Getter -@ToString -public class FromFooSubClass extends FromFoo { - private final String surname; - private final int phone; - private final boolean check; - private final BigDecimal amount; - - public FromFooSubClass(final String name, final BigInteger id, final List nestedObjectList, final List list, final FromSubFoo nestedObject, - final String surname, final int phone, final boolean check, final BigDecimal amount) { - super(name, id, nestedObjectList, list, nestedObject); - this.surname = surname; - this.phone = phone; - this.check = check; - this.amount = amount; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java deleted file mode 100644 index 35ebf6aab..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.util.List; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object. - */ -@AllArgsConstructor -@Getter -@ToString -public class FromFooWithPrimitiveFields { - private final String name; - private final int id; - private final int age; - private final List nestedObjectList; - private final List list; - private final FromSubFoo nestedObject; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromSubFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/FromSubFoo.java deleted file mode 100644 index fdddae4b8..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/FromSubFoo.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import java.util.List; -import java.util.Map; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object. - */ -@AllArgsConstructor -@Getter -@ToString -public class FromSubFoo { - private final String name; - private final int[] phoneNumbers; - private final Map sampleMap; - private final Map> complexMap; - private final Map> veryComplexMap; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java deleted file mode 100644 index 4e70caf49..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigInteger; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object containing properties available in the source object inside other objects. - *

      - * e.g. phoneNumbers field is available inside FromFoo.nestedObject.phoneNumbers - *

      - */ -@AllArgsConstructor -@Getter -@ToString -public class ImmutableFlatToFoo { - private final String name; - private final BigInteger id; - private final int[] phoneNumbers; - -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java deleted file mode 100644 index 0b68fa7ea..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigInteger; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * Sample immutable object. - */ -@AllArgsConstructor -@Getter -public class ImmutableToFoo { - private final String name; - @NotNull - private final BigInteger id; - @NotNull - private final List list; - @NotNull - private final List nestedObjectList; - @NotNull - private final ImmutableToSubFoo nestedObject; - - @Override - public String toString() { - return "ImmutableToFoo"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java deleted file mode 100644 index 919e3fea7..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.util.Locale; -import java.util.Optional; - -import com.hotels.beans.constant.ClassType; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object. - */ -@AllArgsConstructor -@Getter -@ToString -public class ImmutableToFooAdvFields { - private final Optional name; - private final Integer age; - private final String indexNumber; - private final ClassType classType; - private final Locale locale; - private final Price price; -} - -@AllArgsConstructor -@Getter -class Price { - private final float netPrice; - private final float grossPrice; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java deleted file mode 100644 index a37c75802..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigInteger; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import com.hotels.beans.annotation.ConstructorArg; - -import lombok.ToString; - -/** - * Sample immutable object. - */ -@ToString -public class ImmutableToFooCustomAnnotation { - @NotNull - private final String name; - @NotNull - private final BigInteger id; - @NotNull - private final List list; - @NotNull - private final List nestedObjectList; - @NotNull - private final ImmutableToSubFooCustomAnnotation nestedObject; - - public ImmutableToFooCustomAnnotation(@ConstructorArg("name") final String name, - @ConstructorArg("id") final BigInteger id, - @ConstructorArg("list") final List list, - @ConstructorArg("nestedObjectList") final List nestedObjectList, - @ConstructorArg("nestedObject") final ImmutableToSubFooCustomAnnotation nestedObject) { - this.name = name; - this.id = id; - this.list = list; - this.nestedObjectList = nestedObjectList; - this.nestedObject = nestedObject; - } - - public String getName() { - return name; - } - - public BigInteger getId() { - return id; - } - - public List getList() { - return list; - } - - public List getNestedObjectList() { - return nestedObjectList; - } - - public ImmutableToSubFooCustomAnnotation getNestedObject() { - return nestedObject; - } -} - - diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java deleted file mode 100644 index 6fdf751c3..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigInteger; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object with different fields than source object. - */ -@AllArgsConstructor -@Getter -@ToString -public class ImmutableToFooDiffFields { - @NotNull - private final String name; - - @NotNull - private final BigInteger identifier; - - @NotNull - private final List list; - - @NotNull - private final List nestedObjectList; - - @NotNull - private final ImmutableToSubFoo nestedObject; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java deleted file mode 100644 index 014863100..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigInteger; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import lombok.Getter; - -/** - * Sample immutable object with constructor containing parameter in a different order than expected. - */ -@Getter -public class ImmutableToFooInvalid { - @NotNull - private final String name; - @NotNull - private final BigInteger id; - - private final List list; - @NotNull - private final List nestedObjectList; - @NotNull - private final ImmutableToSubFoo nestedObject; - - /** - * Constructor. - */ - public ImmutableToFooInvalid(@NotNull final String name, @NotNull final BigInteger id, @NotNull final List nestedObjectList, - @NotNull final ImmutableToSubFoo nestedObject) { - this.name = name; - this.id = id; - this.list = null; - this.nestedObjectList = nestedObjectList; - this.nestedObject = nestedObject; - } - - @Override - public String toString() { - return "ImmutableToFooInvalid"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java deleted file mode 100644 index 190e0ed96..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.util.List; -import java.util.Map; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object containing extremely complex map. - */ -@AllArgsConstructor -@Getter -@ToString -public class ImmutableToFooMap { - private final Map sampleMap; - private final Map> complexMap; - private final Map> veryComplexMap; - private final Map> extremeComplexMap; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java deleted file mode 100644 index 75d4d7d7a..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import javax.validation.constraints.NotNull; - -import com.hotels.beans.annotation.ConstructorArg; - -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object without all constructor's parameter annotated with {@link ConstructorArg}. - */ -@Getter -@ToString -public class ImmutableToFooMissingCustomAnnotation { - @NotNull - private final String name; - - private final int id; - - /** - * Constructor. - */ - public ImmutableToFooMissingCustomAnnotation(@ConstructorArg("name") final String name, final int id) { - this.name = name; - this.id = id; - } -} - - diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java deleted file mode 100644 index 4515faab2..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -/** - * Immutable object without constructor. - */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class ImmutableToFooNoConstructors { -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java deleted file mode 100644 index d5af1278b..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigInteger; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * Sample immutable object that contains a field not existing in the source object. - */ -@AllArgsConstructor -@Getter -public class ImmutableToFooNotExistingFields { - private final String name; - private final BigInteger id; - private final int age; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java deleted file mode 100644 index c93c28c6c..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigInteger; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * Sample immutable object. - */ -@AllArgsConstructor -@Getter -public class ImmutableToFooSimple { - private final String name; - private final BigInteger id; - - @Override - public String toString() { - return "ImmutableToFooSimple"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java deleted file mode 100755 index 1a15f9947..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object with different field than the source object. - */ -@AllArgsConstructor -@Getter -@ToString -public class ImmutableToFooSimpleWrongTypes { - private final Integer id; - private final String name; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java deleted file mode 100644 index 75829bfa5..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import lombok.Getter; - -/** - * Sample immutable object extending a class. - */ -@Getter -public class ImmutableToFooSubClass extends ImmutableToFoo { - @NotNull - private final String surname; - @NotNull - private final int phone; - @NotNull - private final boolean check; - @NotNull - private final BigDecimal amount; - - /** - * Constructor. - */ - public ImmutableToFooSubClass(final String name, final BigInteger id, final List list, - final List nestedObjectList, final ImmutableToSubFoo nestedObject, final String surname, - final int phone, final boolean check, final BigDecimal amount) { - super(name, id, list, nestedObjectList, nestedObject); - this.surname = surname; - this.phone = phone; - this.check = check; - this.amount = amount; - } - - @Override - public String toString() { - return "ImmutableToFooSubClass"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java deleted file mode 100644 index 5dbc13cd9..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigInteger; -import java.util.List; - -import com.hotels.beans.sample.FromSubFoo; - -import lombok.Builder; -import lombok.Getter; - -/** - * Immutable bean instantiable only through a Builder. - */ -@Getter -@Builder -public class ImmutableToFooWithBuilder { - private final String name; - private final BigInteger id; - private final List nestedObjectList; - private final List list; - private final FromSubFoo nestedObject; - - public ImmutableToFooWithBuilder(final String name, final BigInteger id, final List nestedObjectList, - final List list, final FromSubFoo nestedObject) { - this.name = name; - this.id = id; - this.nestedObjectList = nestedObjectList; - this.list = list; - this.nestedObject = nestedObject; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java deleted file mode 100644 index e55119f6e..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.util.List; -import java.util.Map; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object. - */ -@AllArgsConstructor -@Getter -@ToString -public class ImmutableToSubFoo { - private final String name; - private final int[] phoneNumbers; - private final Map sampleMap; - private final Map> complexMap; - private final Map> veryComplexMap; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java deleted file mode 100644 index b4f281c76..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.util.List; -import java.util.Map; - -import javax.validation.constraints.NotNull; - -import com.hotels.beans.annotation.ConstructorArg; - -import lombok.Getter; -import lombok.ToString; - -/** - * Sample immutable object. - */ -@Getter -@ToString -public class ImmutableToSubFooCustomAnnotation { - @NotNull - private final String name; - private final int[] phoneNumbers; - private final Map sampleMap; - private final Map> complexMap; - private final Map> veryComplexMap; - - /** - * Constructor. - * @param name name - */ - public ImmutableToSubFooCustomAnnotation(@ConstructorArg("name") final String name, @ConstructorArg("phoneNumbers") final int[] phoneNumbers, - @ConstructorArg("sampleMap") final Map sampleMap, @ConstructorArg("complexMap") final Map> complexMap, - @ConstructorArg("veryComplexMap") final Map> veryComplexMap) { - this.name = name; - this.phoneNumbers = phoneNumbers; - this.sampleMap = sampleMap; - this.complexMap = complexMap; - this.veryComplexMap = veryComplexMap; - } -} - - diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/package-info.java deleted file mode 100644 index 64a546785..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/immutable/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Immutable Bean package. - */ - -package com.hotels.beans.sample.immutable; diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java deleted file mode 100644 index 837d853a8..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mixed; - -import java.math.BigInteger; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import com.hotels.beans.sample.immutable.ImmutableToSubFoo; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; - -/** - * Sample mixed object. - */ -@AllArgsConstructor -@Getter -@Setter -public class MixedToFoo { - @NotNull - public BigInteger id; - private final String name; - private final List list; - private final List nestedObjectList; - private ImmutableToSubFoo nestedObject; - - @Override - public String toString() { - return "MixedToFoo"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java deleted file mode 100644 index 49f6d4479..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mixed; - -import java.math.BigInteger; -import java.util.List; - -import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.sample.immutable.ImmutableToSubFoo; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * Sample mixed object with different column names. - */ -@Getter -@Setter -@ToString -public class MixedToFooDiffFields { - private String name; - private final BigInteger identifier; - private final List list; - private final List nestedObjectList; - private ImmutableToSubFoo nestedObject; - - public MixedToFooDiffFields(@ConstructorArg("name") final String name, - @ConstructorArg("identifier") final BigInteger identifier, - @ConstructorArg("list") final List list, @ConstructorArg("nestedObjectList") final List nestedObjectList, - @ConstructorArg("nestedObject") final ImmutableToSubFoo nestedObject) { - this.name = name; - this.identifier = identifier; - this.list = list; - this.nestedObjectList = nestedObjectList; - this.nestedObject = nestedObject; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java deleted file mode 100644 index 79954b25e..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mixed; - -import java.math.BigInteger; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import com.hotels.beans.sample.immutable.ImmutableToSubFoo; - -import lombok.Getter; -import lombok.Setter; - -/** - * Sample mixed object with a constructor containing the final fields only. - */ -@Getter -@Setter -public class MixedToFooMissingAllArgsConstructor { - @NotNull - public BigInteger id; - private final String name; - private final List list; - private final List nestedObjectList; - private ImmutableToSubFoo nestedObject; - - /** - * Constructor for final fields only. - */ - public MixedToFooMissingAllArgsConstructor(final String name, final List list, final List nestedObjectList) { - this.name = name; - this.list = list; - this.nestedObjectList = nestedObjectList; - } - - @Override - public String toString() { - return "MixedToFooMissingAllArgsConstructor"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java deleted file mode 100644 index a359699e1..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mixed; - -import java.math.BigInteger; - -import javax.validation.constraints.NotNull; - -import lombok.Getter; -import lombok.ToString; - -/** - * Sample mixed object with missing default constructor. - */ -@Getter -@ToString -public class MixedToFooMissingConstructor { - @NotNull - public BigInteger id; - private final String name; - - public MixedToFooMissingConstructor(final String name) { - this.name = name; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java deleted file mode 100644 index 3140d2453..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mixed; - -import java.math.BigInteger; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - -/** - * Sample mixed object with different column names. - */ -@Getter -@AllArgsConstructor -@ToString -public class MixedToFooMissingField { - private final String name; - private final BigInteger id; - private final String fooField; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java deleted file mode 100644 index 65d398d68..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mixed; - -import java.math.BigInteger; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; - -/** - * Sample mixed object that contains a field not existing in the source object. - */ -@AllArgsConstructor -@Getter -@Setter -public class MixedToFooNotExistingFields { - private final String name; - private final BigInteger id; - private int age; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java deleted file mode 100644 index 35a90647f..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mixed; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * Mixed bean class containing a static fields. - */ -@Getter -@Setter -@ToString -public class MixedToFooStaticField { - private static final int STATIC_FIELD = 0; - private String normalField; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java deleted file mode 100644 index 3b5f0d025..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mixed; - -import java.math.BigInteger; -import java.util.List; - -import com.hotels.beans.sample.immutable.ImmutableToSubFoo; - -import lombok.Builder; -import lombok.Getter; - -/** - * Mixed bean instantiable only through a Builder. - */ -@Getter -@Builder -public class MixedToFooWithBuilder { - private final String name; - private BigInteger id; - private final List nestedObjectList; - private final List list; - private final ImmutableToSubFoo nestedObject; - - public MixedToFooWithBuilder(final String name, final BigInteger id, final List nestedObjectList, - final List list, final ImmutableToSubFoo nestedObject) { - this.name = name; - this.id = id; - this.nestedObjectList = nestedObjectList; - this.list = list; - this.nestedObject = nestedObject; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/package-info.java deleted file mode 100644 index c743ab584..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mixed/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Mixed Bean package. - */ - -package com.hotels.beans.sample.mixed; diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java deleted file mode 100644 index a73ee9e57..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.math.BigInteger; -import java.util.List; - -import lombok.Getter; -import lombok.Setter; - -/** - * Sample mutable object. - */ -@Getter -@Setter -public class MutableToFoo { - private String name; - private BigInteger id; - private List list; - private List nestedObjectList; - private MutableToSubFoo nestedObject; - - @Override - public String toString() { - return "MutableToFoo"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java deleted file mode 100644 index 1a90e991c..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.util.Locale; -import java.util.Optional; - -import com.hotels.beans.constant.ClassType; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * Sample mutable object containing special fields. - */ -@Getter -@Setter -@ToString -public class MutableToFooAdvFields { - private Optional name; - private Optional age; - private String indexNumber; - private ClassType classType; - private Locale locale; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java deleted file mode 100644 index bcdaede18..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.math.BigInteger; -import java.util.List; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; - -/** - * Sample mutable object. - */ -@Getter -@Setter -@AllArgsConstructor -public class MutableToFooInvalid { - private String name; - private BigInteger id; - private List list; - private List nestedObjectList; - private MutableToSubFoo nestedObject; - - @Override - public String toString() { - return "MutableToFooInvalid"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java deleted file mode 100644 index ea337939d..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.math.BigInteger; - -import lombok.Getter; -import lombok.Setter; - -/** - * Sample mutable object that contains a field not existing in the source object. - */ -@Getter -@Setter -public class MutableToFooNotExistingFields { - private String name; - private BigInteger id; - private int age; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java deleted file mode 100644 index 8e33a8a56..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.math.BigInteger; - -import lombok.Getter; -import lombok.Setter; - -/** - * Sample mutable object. - */ -@Getter -@Setter -public class MutableToFooSimple { - private String name; - private BigInteger id; - - @Override - public String toString() { - return "MutableToFooSimple"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java deleted file mode 100644 index 39830a2e6..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.math.BigInteger; - -import lombok.Getter; - -/** - * Sample mutable object without setter methods. - */ -@Getter -public class MutableToFooSimpleNoSetters { - private String name; - private BigInteger id; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java deleted file mode 100644 index 1e4e81c21..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.math.BigDecimal; - -import lombok.Getter; -import lombok.Setter; - -/** - * Sample mutable object extending a class. - */ -@Getter -@Setter -public class MutableToFooSubClass extends MutableToFoo { - private String surname; - private int phone; - private boolean check; - private BigDecimal amount; - - @Override - public String toString() { - return "MutableToFooSubClass"; - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java deleted file mode 100644 index ada9bc7b0..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.math.BigInteger; -import java.util.List; - -import lombok.Getter; -import lombok.Setter; - -/** - * Mutable object instantiable only through a Builder. - */ -@Getter -@Setter -public final class MutableToFooWithBuilder { - private String name; - private BigInteger id; - private List list; - private List nestedObjectList; - private MutableToSubFoo nestedObject; - - private MutableToFooWithBuilder() { - } - - public static class Builder { - private String name; - private BigInteger id; - private List list; - private List nestedObjectList; - private MutableToSubFoo nestedObject; - - public Builder withName(final String name) { - this.name = name; - return this; - } - - public Builder withId(final BigInteger id) { - this.id = id; - return this; - } - - public MutableToFooWithBuilder build() { - MutableToFooWithBuilder mutableToFooWithBuilder = new MutableToFooWithBuilder(); - mutableToFooWithBuilder.id = this.id; - mutableToFooWithBuilder.name = this.name; - mutableToFooWithBuilder.list = this.list; - mutableToFooWithBuilder.nestedObjectList = this.nestedObjectList; - mutableToFooWithBuilder.nestedObject = this.nestedObject; - return mutableToFooWithBuilder; - } - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java deleted file mode 100644 index 98423f770..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.math.BigInteger; -import java.util.List; - -import lombok.Getter; - -/** - * Mutable object instantiable only through a Builder. - * The Builder class contains multiple constructors. - */ -@Getter -public final class MutableToFooWithBuilderMultipleConstructor { - private String name; - private BigInteger id; - private List list; - private List nestedObjectList; - private MutableToSubFoo nestedObject; - - /** - * Private constructor. - */ - private MutableToFooWithBuilderMultipleConstructor() { - } - - static class Builder { - private String name; - private BigInteger id; - private List list; - private List nestedObjectList; - private MutableToSubFoo nestedObject; - - Builder(final String name) { - this.name = name; - } - - Builder() { - } - - public Builder withName(final String name) { - this.name = name; - return this; - } - - public Builder withId(final BigInteger id) { - this.id = id; - return this; - } - - public MutableToFooWithBuilderMultipleConstructor build() { - MutableToFooWithBuilderMultipleConstructor builderToFoo = new MutableToFooWithBuilderMultipleConstructor(); - builderToFoo.id = this.id; - builderToFoo.name = this.name; - builderToFoo.list = this.list; - builderToFoo.nestedObjectList = this.nestedObjectList; - builderToFoo.nestedObject = this.nestedObject; - return builderToFoo; - } - } -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java deleted file mode 100644 index ba52ad7c3..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.mutable; - -import java.util.List; -import java.util.Map; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -/** - * Sample mutable object. - */ -@Getter -@Setter -@ToString -public class MutableToSubFoo { - private String name; - private int[] phoneNumbers; - private Map sampleMap; - private Map> complexMap; - private Map> veryComplexMap; -} diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/package-info.java deleted file mode 100644 index c4f792139..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/mutable/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Mutable Bean package. - */ - -package com.hotels.beans.sample.mutable; diff --git a/bean-utils-library/src/test/java/com/hotels/beans/sample/package-info.java b/bean-utils-library/src/test/java/com/hotels/beans/sample/package-info.java deleted file mode 100644 index 1cfa2332f..000000000 --- a/bean-utils-library/src/test/java/com/hotels/beans/sample/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Sample Bean object for test purpose. - */ - -package com.hotels.beans.sample; diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 8c646d0ef..357bbff64 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -41,4 +41,19 @@ ${hibernate-validator.version}
      + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + +
      \ No newline at end of file diff --git a/pom.xml b/pom.xml index ff89afc4a..f0349f4b6 100644 --- a/pom.xml +++ b/pom.xml @@ -245,26 +245,25 @@ - ${project.artifactId}-${project.version} - - org.apache.maven.plugins - maven-compiler-plugin - ${maven.compiler.plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - true - true - - - - org.apache.maven.plugins - maven-jar-plugin - ${maven.jar.plugin.version} - - + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + true + true + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + **/config/** **/logback*.xml **/banner.txt @@ -483,6 +482,18 @@ + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + org.apache.maven.plugins maven-javadoc-plugin @@ -495,6 +506,22 @@ + + org.apache.maven.plugins + maven-site-plugin + + + com.github.github + site-maven-plugin + + + + site + + site + + + From 715759e85aaf9d1351fafaebe95e87696985eac5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 May 2019 22:45:46 +0200 Subject: [PATCH 0559/1786] Changed build order --- pom.xml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index f0349f4b6..7936546e0 100644 --- a/pom.xml +++ b/pom.xml @@ -21,9 +21,9 @@ + bean-utils-library bull-common bull-converter - bean-utils-library @@ -80,11 +80,6 @@ - - com.hotels.beans - bull-common - ${project.version} - org.projectlombok lombok From e0a4473bc33877b40fe72c2f9dd37096bd1256d5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 May 2019 23:57:59 +0200 Subject: [PATCH 0560/1786] Fixed problem with javadoc aggregation --- .travis.yml | 2 +- bean-utils-library/pom.xml | 2 +- bull-converter/pom.xml | 1 - pom.xml | 14 +------------- 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index dd94c34db..a6f2f24d4 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true -B + - travis_retry mvn install sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true javadoc:aggregate -B deploy: provider: pages local-dir: target/site diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 0d6495e13..80f24e428 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - BULL - Bean Utils Light Library + BULL - Core bean-utils-library jar diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index fdf339b79..dbcdcd347 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -21,5 +21,4 @@ ${project.version} - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7936546e0..91d40f2ec 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - BULL - Parent module + BULL - Bean Utils Light Library com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull @@ -489,18 +489,6 @@
      - - org.apache.maven.plugins - maven-javadoc-plugin - - - generate-javadoc - - aggregate-jar - - - - org.apache.maven.plugins maven-site-plugin From 5d0b376d4c9e48592f3806e3eaad8cb513a6ee2e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 May 2019 10:22:36 +0200 Subject: [PATCH 0561/1786] Adding test cases --- .../hotels/beans/cache/CacheManagerTest.java | 26 +- .../beans/utils/ReflectionUtilsTest.java | 60 ++- .../hotels/beans/validator/ValidatorTest.java | 56 +++ pom.xml | 438 +++++++++--------- 4 files changed, 357 insertions(+), 223 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index 02fe64664..d2797df26 100644 --- a/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -31,7 +31,8 @@ * Unit test for {@link CacheManager}. */ public class CacheManagerTest { - private static final String CACHED_VALUE = "cachedValue"; + private static final String VALUE = "value"; + private static final String DEFAULT_VALUE = "defaultValue"; private static final String CACHE_KEY = "cacheKey"; private static final Class CACHED_OBJECT_CLASS = String.class; /** @@ -53,7 +54,7 @@ public void beforeClass() { @Test public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { // GIVEN - underTest.cacheObject(CACHE_KEY, CACHED_VALUE); + underTest.cacheObject(CACHE_KEY, VALUE); // WHEN Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); @@ -61,7 +62,24 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { // THEN assertTrue(actual.isPresent()); assertEquals(CACHED_OBJECT_CLASS, actual.get().getClass()); - assertSame(CACHED_VALUE, actual.get()); + assertSame(VALUE, actual.get()); + } + + /** + * Tests that the method {@code cacheObject} caches the default value if the object is null. + */ + @Test + public void testCacheObjectStoresTheDefaultValueIfTheGivenObjectIsNull() { + // GIVEN + underTest.cacheObject(CACHE_KEY, null, DEFAULT_VALUE); + + // WHEN + Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); + + // THEN + assertTrue(actual.isPresent()); + assertEquals(CACHED_OBJECT_CLASS, actual.get().getClass()); + assertSame(DEFAULT_VALUE, actual.get()); } /** @@ -70,7 +88,7 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { @Test public void testRemoveFromCacheRemovesTheObject() { // GIVEN - underTest.cacheObject(CACHE_KEY, CACHED_VALUE); + underTest.cacheObject(CACHE_KEY, VALUE); // WHEN underTest.removeFromCache(CACHE_KEY); diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index 3498eff8c..a89f9690a 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -52,6 +52,7 @@ import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.mutable.MutableToFoo; +import com.hotels.beans.sample.mutable.MutableToFooSimple; /** * Unit tests fro class: {@link ReflectionUtils}. @@ -216,7 +217,7 @@ private Object[][] dataGetGetterMethodPrefixTesting() throws Exception { public void testGetFieldAnnotationWorksProperly(final String testCaseDescription, final Class annotationToGet, final boolean expectNull) throws NoSuchFieldException { // GIVEN - Field nameField = ImmutableToFoo.class.getDeclaredField(ID_FIELD_NAME); + Field nameField = underTest.getDeclaredField(ID_FIELD_NAME, ImmutableToFoo.class); // WHEN final Annotation actual = underTest.getFieldAnnotation(nameField, annotationToGet); @@ -329,6 +330,63 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong getMethod(INVOKE_METHOD_NAME).invoke(underTest, idSetterMethod, mutableToFoo, new Object[] {ONE}); } + /** + * Tests that the method {@code invokeMethod} works properly. + */ + @Test + public void testGetDeclaredFieldWorksProperly() { + // GIVEN + + // WHEN + Field actual = underTest.getDeclaredField(ID_FIELD_NAME, FromFooSubClass.class); + + // THEN + assertNotNull(actual); + } + + /** + * Tests that the method {@code invokeMethod} throws a {@link MissingFieldException} if the field does not exists. + */ + @Test(expectedExceptions = MissingFieldException.class) + public void testGetDeclaredFieldRaisesAnExceptionIfTheFieldDoesNotExists() { + // GIVEN + + // WHEN + Field actual = underTest.getDeclaredField(NOT_EXISTING_FIELD_NAME, FromFooSubClass.class); + + // THEN + assertNotNull(actual); + } + + /** + * Tests that the method {@code setFieldValue} works properly. + */ + @Test + public void testSetFieldValueWorksProperly() { + // GIVEN + MutableToFooSimple mutableToFoo = new MutableToFooSimple(); + Field idField = underTest.getDeclaredField(ID_FIELD_NAME, mutableToFoo.getClass()); + + // WHEN + underTest.setFieldValue(mutableToFoo, idField, ONE); + + // THEN + assertEquals(ONE, mutableToFoo.getId()); + } + + /** + * Tests that the method {@code setFieldValue} throws an {@link IllegalArgumentException} if the field value is not valid. + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testSetFieldValueRaiseAnExceptionIfTheValueToSetIsNotValid() { + // GIVEN + MutableToFooSimple mutableToFoo = new MutableToFooSimple(); + Field idField = underTest.getDeclaredField(ID_FIELD_NAME, mutableToFoo.getClass()); + + // WHEN + underTest.setFieldValue(mutableToFoo, idField, Boolean.TRUE); + } + /** * Retrieves a method. * @param methodName the method to retrieve diff --git a/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java b/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java index 85e15ef0e..aaa18a373 100644 --- a/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java +++ b/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java @@ -20,10 +20,17 @@ import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigInteger; +import java.util.Collections; + +import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.sample.mixed.MixedToFoo; + /** * Unit test for {@link Validator}. */ @@ -33,11 +40,27 @@ public class ValidatorTest { */ private static final String EXCEPTION_MESSAGE = "exception message"; + /** + * A sample ID. + */ + private static final BigInteger ID = new BigInteger("1234"); + + /** + * A sample name. + */ + private static final String NAME = "Goofy"; + /** * A sample value. */ private static final String VALUE = "val"; + /** + * The class to be tested. + */ + @InjectMocks + private ValidatorImpl underTest; + /** * Initialized mocks. */ @@ -106,4 +129,37 @@ private Object[][] dataNoExceptionAreRaisedTesting() { {"Tests that the method does not raise an exception if the given parameter is not null and a description message is not defined", VALUE, null} }; } + + /** + * Test that an {@link InvalidBeanException} is thrown if the bean is not valid. + */ + @Test(expectedExceptions = InvalidBeanException.class) + public void testValidateThrowsExceptionWhenTheBeanIsInvalid() { + //GIVEN + MixedToFoo validBean = createTestBean(null); + + //WHEN + underTest.validate(validBean); + } + + /** + * Test that no exceptions are thrown if the bean is valid. + */ + @Test + public void testValidateDoesNotThrowsExceptionWhenTheBeanIsValid() { + //GIVEN + MixedToFoo validBean = createTestBean(ID); + + //WHEN + underTest.validate(validBean); + } + + /** + * Creates a test bean. + * @param id the id to use + * @return a populated {@link MixedToFoo} + */ + private MixedToFoo createTestBean(final BigInteger id) { + return new MixedToFoo(id, NAME, Collections.emptyList(), null, null); + } } diff --git a/pom.xml b/pom.xml index 91d40f2ec..07ee49c32 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 BULL - Bean Utils Light Library com.hotels.beans @@ -23,7 +24,7 @@ bean-utils-library bull-common - bull-converter + @@ -259,222 +260,223 @@ ${maven.jar.plugin.version} - **/config/** - **/logback*.xml - **/banner.txt - **/*.yml - **/stats/** - - - - - org.apache.maven.plugins - maven-source-plugin - ${maven.source.plugin.version} - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven.javadoc.plugin.version} - - ${javadoc.skip} - - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${maven.checkstyle.plugin.version} - - - validate - validate - - config/checkstyle/rules.xml - config/checkstyle/suppression.xml - UTF-8 - true - true - ${checkstyle.check.skip} - ${checkstyle.includeTestSourceDirectory} - - - - check - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.surefire.plugin.version} - - false - - - - org.jacoco - jacoco-maven-plugin - ${jacoco.version} - - - - prepare-agent - - - - report - prepare-package - - report - - - - jacoco-check - - check - - - ${jacoco.check.skip} - - com/hotels/beans/** - - - **/Test*.* - **/*Test.* - **/*Application.* - com/hotels/beans/model/** - com/hotels/beans/error/** - com/hotels/beans/annotation/** - - - - PACKAGE - - - COMPLEXITY - COVEREDRATIO - ${jacoco.complexityRatio} - - - CLASS - COVEREDRATIO - ${jacoco.classRatio} - - - METHOD - COVEREDRATIO - ${jacoco.methodRatio} - - - BRANCH - COVEREDRATIO - ${jacoco.branchRatio} - - - LINE - COVEREDRATIO - ${jacoco.lineRatio} - - - INSTRUCTION - COVEREDRATIO - ${jacoco.instructionRatio} - - - - - - - - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura.maven.plugin.version} - - false - true - - - - none - - - - - - org.apache.maven.plugins - maven-pmd-plugin - ${maven.pmd.plugin.version} - - ${jdk.version} - true - false - false - false - java - ${pmd.check.skip} - - - - process-sources - - check - - - - - - - org.apache.maven.plugins - maven-site-plugin - ${maven.site.plugin.version} - - ${project.basedir}/docs/site - true - - - - org.apache.maven.wagon - wagon-ssh - ${wagon-ssh.version} - - - - - com.github.github - site-maven-plugin - ${github.site.maven.plugin.version} - - Creating site for ${project.artifactId} ${project.version} - - - - - site - - site - - - -
      + **/config/** + **/logback*.xml + **/banner.txt + **/*.yml + **/stats/** + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven.source.plugin.version} + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + ${javadoc.skip} + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven.checkstyle.plugin.version} + + + validate + validate + + config/checkstyle/rules.xml + config/checkstyle/suppression.xml + UTF-8 + true + true + ${checkstyle.check.skip} + ${checkstyle.includeTestSourceDirectory} + + + + check + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.plugin.version} + + false + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + + prepare-agent + + + + report + prepare-package + + report + + + + jacoco-check + + check + + + ${jacoco.check.skip} + + com/hotels/beans/** + + + **/Test*.* + **/*Test.* + **/*Application.* + com/hotels/beans/model/** + com/hotels/beans/constant/** + com/hotels/beans/error/** + com/hotels/beans/annotation/** + + + + PACKAGE + + + COMPLEXITY + COVEREDRATIO + ${jacoco.complexityRatio} + + + CLASS + COVEREDRATIO + ${jacoco.classRatio} + + + METHOD + COVEREDRATIO + ${jacoco.methodRatio} + + + BRANCH + COVEREDRATIO + ${jacoco.branchRatio} + + + LINE + COVEREDRATIO + ${jacoco.lineRatio} + + + INSTRUCTION + COVEREDRATIO + ${jacoco.instructionRatio} + + + + + + + + + + org.codehaus.mojo + cobertura-maven-plugin + ${cobertura.maven.plugin.version} + + false + true + + + + none + + + + + + org.apache.maven.plugins + maven-pmd-plugin + ${maven.pmd.plugin.version} + + ${jdk.version} + true + false + false + false + java + ${pmd.check.skip} + + + + process-sources + + check + + + + + + + org.apache.maven.plugins + maven-site-plugin + ${maven.site.plugin.version} + + ${project.basedir}/docs/site + true + + + + org.apache.maven.wagon + wagon-ssh + ${wagon-ssh.version} + + + + + com.github.github + site-maven-plugin + ${github.site.maven.plugin.version} + + Creating site for ${project.artifactId} ${project.version} + + + + + site + + site + + + +
      From 3cd9e34fc2193e9b6cc6e70a44f7748eb7d28943 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 May 2019 12:52:06 +0200 Subject: [PATCH 0562/1786] Modified travis config --- .travis.yml | 3 +- bean-utils-library/pom.xml | 10 ++--- .../com/hotels/beans/base/DefaultsTest.java | 41 ++++--------------- 3 files changed, 16 insertions(+), 38 deletions(-) diff --git a/.travis.yml b/.travis.yml index a6f2f24d4..766d6c46e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true javadoc:aggregate -B + - travis_retry mvn install sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true -B deploy: provider: pages local-dir: target/site @@ -41,6 +41,7 @@ jobs: before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate deploy: - provider: script script: config/travis/deploy.sh diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 80f24e428..7e3ea4ccb 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -19,11 +19,11 @@ bull-common ${project.version} - - com.hotels.beans - bull-converter - ${project.version} - + + + + + com.hotels.beans diff --git a/bull-common/src/test/java/com/hotels/beans/base/DefaultsTest.java b/bull-common/src/test/java/com/hotels/beans/base/DefaultsTest.java index 7531634e4..e4baddf4a 100644 --- a/bull-common/src/test/java/com/hotels/beans/base/DefaultsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/base/DefaultsTest.java @@ -17,34 +17,19 @@ package com.hotels.beans.base; import static java.lang.Boolean.FALSE; -import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; -import java.util.Collection; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; import org.mockito.InjectMocks; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; import com.hotels.beans.sample.FromFoo; /** * Unit test for {@link Defaults}. */ -@RunWith(value = Parameterized.class) public class DefaultsTest { - /** - * The class type. - */ - private final Class type; - - /** - * The expected result. - */ - private final Object expectedResult; - /** * The class to be tested. */ @@ -52,20 +37,12 @@ public class DefaultsTest { private Defaults underTest; /** - * All args constructor. + * Tests that the method: {@code defaultValue} returns the expected result for the given type. * @param type the class type. * @param expectedResult the expected result. */ - public DefaultsTest(final Class type, final Object expectedResult) { - this.type = type; - this.expectedResult = expectedResult; - } - - /** - * Tests that the method: {@code defaultValue} returns the expected result for the given type. - */ - @Test - public void testDefaultValueShouldReturnTheExpectedResult() { + @Test(dataProvider = "dataProvider") + public void testDefaultValueShouldReturnTheExpectedResult(final Class type, final Object expectedResult) { // GIVEN // WHEN @@ -79,9 +56,9 @@ public void testDefaultValueShouldReturnTheExpectedResult() { * Data provider for the required test cases. * @return the test cases. */ - @Parameterized.Parameters(name = "{index}. Type: {0}.") - public static Collection dataProvider() { - return asList(new Object[][]{ + @DataProvider + private Object[][] dataProvider() { + return new Object[][] { {boolean.class, FALSE}, {Boolean.class, FALSE}, {Character.class, '\u0000'}, @@ -99,6 +76,6 @@ public static Collection dataProvider() { {Double.class, 0.0D}, {double.class, 0.0D}, {FromFoo.class, null} - }); + }; } } From 19f1030b07fffb869204bd2477fb7e2203dbde84 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 May 2019 17:18:33 +0200 Subject: [PATCH 0563/1786] Completed unit test for class ClassUtils --- README.md | 40 ++++++- .../com/hotels/beans/validator/Validator.java | 26 ++++- .../hotels/beans/validator/ValidatorImpl.java | 26 ++++- .../hotels/beans/utils/ClassUtilsTest.java | 105 +++++++++++++++++- .../hotels/beans/validator/ValidatorTest.java | 41 ++++++- docs/site/markdown/validator/samples.md | 40 ++++++- 6 files changed, 266 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index b2b595a64..c3e082b79 100644 --- a/README.md +++ b/README.md @@ -556,7 +556,11 @@ Following the obtained results: ## Validation samples -Validate a java bean has never been so simple. Given the following bean: +Validate a java bean has never been so simple. The library offers different API related to this, following some examples: + +### Validate a Java Bean: + +Given the following bean: ~~~Java public class SampleBean { @@ -583,6 +587,40 @@ beanUtils.getValidator().validate(sampleBean); this will throw an `InvalidBeanException` as the `id` field is null. +### Retrieve the violated constraints: + +Given the following bean: + +~~~Java +public class SampleBean { + @NotNull + private BigInteger id; + private String name; + + // constructor + // getters and setters... +} +~~~ + +an instance of the above object: + +~~~Java +SampleBean sampleBean = new SampleBean(); +~~~ + +And one line code as: + +~~~Java +List violatedConstraints = beanUtils.getValidator().getConstraintViolationsMessages(sampleBean); +~~~ + +this will returns a list containing a constraint validation message for the `id` field as it's null and the constraint: `@NotNull` is not met. + +in case it's needed to have the `ConstraintViolation` object: +~~~Java +Set> violatedConstraints = beanUtils.getValidator().getConstraintViolations(sampleBean); +~~~ + ## Constraints: * the class's fields that have to be copied must not be static diff --git a/bull-common/src/main/java/com/hotels/beans/validator/Validator.java b/bull-common/src/main/java/com/hotels/beans/validator/Validator.java index ce8ae83d2..60e7bfe8f 100644 --- a/bull-common/src/main/java/com/hotels/beans/validator/Validator.java +++ b/bull-common/src/main/java/com/hotels/beans/validator/Validator.java @@ -18,18 +18,40 @@ import static java.util.Objects.isNull; +import java.util.List; +import java.util.Set; + +import javax.validation.ConstraintViolation; + /** * Java Bean validation class. * It offers the possibility to validate a given Java Bean against a set of defined constraints. */ public interface Validator { /** - * Checks if an object is valid. + * Checks if an object is valid and returns the list of the constraints not met. + * @param the object class + * @param k the object to check + * @return the list of violated constraints. + */ + Set> getConstraintViolations(K k); + + /** + * Checks if an object is valid and returns the list of the constraints messages not met. + * @param the object class * @param k the object to check + * @return the list of violated constraints messages. + */ + List getConstraintViolationsMessages(K k); + + /** + * Checks if an object is valid. * @param the object class + * @param k the object to check * @throws com.hotels.beans.error.InvalidBeanException {@link com.hotels.beans.error.InvalidBeanException} if the validation fails + * @return */ - void validate(final K k); + void validate(K k); /** * Validate that the specified argument is not {@code null}; diff --git a/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java index a8502b385..a2246e618 100644 --- a/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java @@ -17,6 +17,7 @@ package com.hotels.beans.validator; import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; import static javax.validation.Validation.buildDefaultValidatorFactory; @@ -26,6 +27,7 @@ import static com.hotels.beans.constant.Punctuation.DOT; import static com.hotels.beans.constant.Punctuation.SEMICOLON; +import java.util.List; import java.util.Set; import javax.validation.ConstraintViolation; @@ -50,12 +52,34 @@ public ValidatorImpl() { this.cacheManager = getCacheManager("validatorImpl"); } + /** + * {@inheritDoc} + */ + @Override + public final Set> getConstraintViolations(final K k) { + return getValidator().validate(k); + } + + /** + * {@inheritDoc} + */ + @Override + public final List getConstraintViolationsMessages(final K k) { + return getConstraintViolations(k).stream() + .map(cv -> cv.getRootBeanClass().getName() + + DOT.getSymbol() + + cv.getPropertyPath() + + SPACE + + cv.getMessage()) + .collect(toList()); + } + /** * {@inheritDoc} */ @Override public final void validate(final K k) { - final Set> constraintViolations = getValidator().validate(k); + final Set> constraintViolations = getConstraintViolations(k); if (!constraintViolations.isEmpty()) { final String errors = constraintViolations.stream() .map(cv -> cv.getRootBeanClass().getName() diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index cb0769f8e..f4beef3a0 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -23,6 +23,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import java.lang.annotation.Annotation; @@ -35,10 +37,12 @@ import java.util.List; import java.util.Locale; import java.util.function.Predicate; +import java.util.function.Supplier; import javax.validation.constraints.NotNull; import org.mockito.InjectMocks; +import org.springframework.test.util.ReflectionTestUtils; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -57,17 +61,19 @@ import com.hotels.beans.sample.mixed.MixedToFooStaticField; import com.hotels.beans.sample.mixed.MixedToFooWithBuilder; import com.hotels.beans.sample.mutable.MutableToFoo; +import com.hotels.beans.sample.mutable.MutableToFooSubClass; import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; /** * Unit test for {@link ClassUtils}. */ public class ClassUtilsTest { - private static final Class CLASS_WITHOUT_PRIVATE_FINAL_FIELDS = MutableToFoo.class; + private static final Class CLASS_WITHOUT_PRIVATE_FINAL_FIELDS = MutableToFooSubClass.class; private static final Class CLASS_WITH_PRIVATE_FINAL_FIELDS = ImmutableToFoo.class; private static final int EXPECTED_PRIVATE_FINAL_FIELDS = 5; private static final int EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS = 4; private static final Class CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS = MixedToFoo.class; + private static final int EXPECTED_MIXED_CLASS_TOTAL_NOT_FINAL_FIELDS = 2; private static final int EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_NOT_FINAL_FIELDS = 1; private static final Class CLASS_WITH_STATIC_FIELDS = MixedToFooStaticField.class; private static final Class CLASS_WITHOUT_CONSTRUCTOR = MixedToFooMissingConstructor.class; @@ -259,7 +265,39 @@ public void testGetPrivateFinalFieldsWorksAsExpected(final String testCaseDescri private Object[][] dataGetPrivateFinalFieldsTesting() { return new Object[][] { {"Tests that the method returns 0 if the given class has no private final fields", CLASS_WITHOUT_PRIVATE_FINAL_FIELDS, ZERO}, - {"Tests that the method returns the expected value if the class has private final fields", CLASS_WITH_PRIVATE_FINAL_FIELDS, EXPECTED_PRIVATE_FINAL_FIELDS} + {"Tests that the method returns the expected value if the class has private final fields", CLASS_WITH_PRIVATE_FINAL_FIELDS, EXPECTED_PRIVATE_FINAL_FIELDS}, + {"Tests that the method returns the expected value if the class has private final fields and extends another class", + CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS, EXPECTED_SUB_CLASS_PRIVATE_FIELDS} + }; + } + + /** + * Tests that the method {@code getNotFinalFields} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataGetNotFinalFieldsTesting") + public void testGetNotFinalFieldsWorksAsExpected(final String testCaseDescription, final Class testClass, final int expectedResult) { + // GIVEN + + // WHEN + List actual = underTest.getNotFinalFields(testClass, true); + + // THEN + assertEquals(expectedResult, actual.size()); + } + + /** + * Creates the parameters to be used for testing the method {@code getNotFinalFields}. + * @return parameters to be used for testing the the method {@code getNotFinalFields}. + */ + @DataProvider + private Object[][] dataGetNotFinalFieldsTesting() { + return new Object[][] { + {"Tests that the method returns 0 if the given class has only private fields", CLASS_WITH_PRIVATE_FINAL_FIELDS, ZERO}, + {"Tests that the method returns the expected value if the class has private final fields", + CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, EXPECTED_MIXED_CLASS_TOTAL_NOT_FINAL_FIELDS} }; } @@ -364,7 +402,9 @@ private Object[][] dataGetDeclaredFieldsTesting() { {"Tests that the method returns the expected total number of fields when the skipStatic param is true", CLASS_WITH_STATIC_FIELDS, true, EXPECTED_NOT_STATIC_FIELDS}, {"Tests that the method returns the expected value if the class has private final fields only", CLASS_WITH_STATIC_FIELDS, false, - CLASS_WITH_STATIC_FIELDS.getDeclaredFields().length} + CLASS_WITH_STATIC_FIELDS.getDeclaredFields().length}, + {"Tests that the method returns the expected total number of fields when the skipStatic param is true and the class extends another class", + CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS, true, EXPECTED_SUB_CLASS_PRIVATE_FIELDS} }; } @@ -413,6 +453,65 @@ public void testGetAllArgsConstructorWorksAsExpected() { assertNotNull(actual); } + /** + * Tests that the method {@code getNoArgsConstructor} works as expected. + */ + @Test + public void testGetNoArgsConstructorWorksAsExpected() { + // GIVEN + + // WHEN + Supplier actual = underTest.getNoArgsConstructor(CLASS_WITHOUT_PRIVATE_FINAL_FIELDS); + + // THEN + assertNotNull(actual); + } + + /** + * Tests that the method {@code areParameterNamesAvailable} works as expected. + * @param testCaseDescription the test case description + * @param constructor the test constructor to check + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataAreParameterNamesAvailableTesting") + public void testAreParameterNamesAvailableWorksAsExpected(final String testCaseDescription, final Constructor constructor, final boolean expectedResult) { + // GIVEN + + // WHEN + boolean actual = underTest.areParameterNamesAvailable(constructor); + + // THEN + assertEquals(expectedResult, actual); + + } + + /** + * Creates the parameters to be used for testing the method {@code areParameterNamesAvailable}. + * @return parameters to be used for testing the the method {@code areParameterNamesAvailable}. + */ + @DataProvider + private Object[][] dataAreParameterNamesAvailableTesting() { + return new Object[][] { + {"Tests that the method returns false if the constructor parameter names are not available", createMockedConstructor(false), false}, + {"Tests that the method returns false if the constructor parameter names are available", underTest.getAllArgsConstructor(MixedToFoo.class), true} + }; + } + + /** + * Creates a mocked constructor for testing method {@code areParameterNamesAvailable}. + * @param isNamePresent the value it should return when invoking the {@code isNamePresent} method + * @return a mocked {@link Constructor} instance + */ + private Constructor createMockedConstructor(final boolean isNamePresent) { + Parameter parameter = mock(Parameter.class); + ReflectionTestUtils.setField(parameter, "name", "paramName"); + when(parameter.isNamePresent()).thenReturn(isNamePresent); + Constructor constructor = mock(Constructor.class); + when(constructor.getDeclaringClass()).thenReturn(ImmutableToFoo.class); + when(constructor.getParameters()).thenReturn(new Parameter[] {parameter}); + return constructor; + } + /** * Tests that the method {@code getNoArgsConstructor} throws exception if the class has no all args constructor. */ diff --git a/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java b/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java index aaa18a373..1ab148447 100644 --- a/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java +++ b/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java @@ -16,12 +16,16 @@ package com.hotels.beans.validator; +import static java.math.BigInteger.ONE; +import static java.math.BigInteger.ZERO; import static java.util.Objects.nonNull; import static org.mockito.MockitoAnnotations.initMocks; +import static org.testng.Assert.assertEquals; import java.math.BigInteger; import java.util.Collections; +import java.util.List; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; @@ -88,8 +92,8 @@ public void testNotNullRaisesAnExceptionWhenTheGivenObjectIsNull(final String te } /** - * Creates the parameters to be used for testing tat the method {@code notNull} raises an {@link IllegalArgumentException}. - * @return parameters to be used for testing tat the method {@code notNull} raises an {@link IllegalArgumentException}. + * Creates the parameters to be used for testing that the method {@code notNull} raises an {@link IllegalArgumentException}. + * @return parameters to be used for testing that the method {@code notNull} raises an {@link IllegalArgumentException}. */ @DataProvider private Object[][] dataIllegalArgumentExceptionTesting() { @@ -119,8 +123,8 @@ public void testThatNoExceptionAreThrownWhenTheGivenObjectIsNotNullEvenWithoutAC } /** - * Creates the parameters to be used for testing tat the method {@code notNull} raises an {@link IllegalArgumentException}. - * @return parameters to be used for testing tat the method {@code notNull} raises an {@link IllegalArgumentException}. + * Creates the parameters to be used for testing that the method {@code notNull} raises an {@link IllegalArgumentException}. + * @return parameters to be used for testing that the method {@code notNull} raises an {@link IllegalArgumentException}. */ @DataProvider private Object[][] dataNoExceptionAreRaisedTesting() { @@ -154,6 +158,35 @@ public void testValidateDoesNotThrowsExceptionWhenTheBeanIsValid() { underTest.validate(validBean); } + /** + * Test that the method {@code getConstraintViolationsAsString} returns the exact number of violations. + * @param testCaseDescription the test case description + * @param elemToCheck the class to validate + * @param totalExpectedViolation the exception message + */ + @Test(dataProvider = "dataValidationConstraintsList") + public void testGetConstraintViolationsWorksAsExpected(final String testCaseDescription, final Object elemToCheck, final int totalExpectedViolation) { + //GIVEN + + //WHEN + List actual = underTest.getConstraintViolationsMessages(elemToCheck); + + // THEN + assertEquals(totalExpectedViolation, actual.size()); + } + + /** + * Creates the parameters to be used for testing that the method {@code getConstraintViolationsAsString} returns the exact number of violations. + * @return parameters to be used for testing that the method {@code getConstraintViolationsAsString} returns the exact number of violations. + */ + @DataProvider + private Object[][] dataValidationConstraintsList() { + return new Object[][] { + {"Tests that no constraints violation are returned if the object is valid.", createTestBean(ID), ZERO.intValue()}, + {"Tests that one constraints violation is returned if the object id is null.", createTestBean(null), ONE.intValue()} + }; + } + /** * Creates a test bean. * @param id the id to use diff --git a/docs/site/markdown/validator/samples.md b/docs/site/markdown/validator/samples.md index 050c20d62..9763dd89f 100644 --- a/docs/site/markdown/validator/samples.md +++ b/docs/site/markdown/validator/samples.md @@ -4,7 +4,11 @@ # Validation samples -Validate a java bean has never been so simple. Given the following bean: +Validate a java bean has never been so simple. The library offers different API related to this, following some examples: + +### Validate a Java Bean: + +Given the following bean: ~~~Java public class SampleBean { @@ -30,3 +34,37 @@ beanUtils.getValidator().validate(sampleBean); ~~~ this will throw an `InvalidBeanException` as the `id` field is null. + +### Retrieve the violated constraints: + +Given the following bean: + +~~~Java +public class SampleBean { + @NotNull + private BigInteger id; + private String name; + + // constructor + // getters and setters... +} +~~~ + +an instance of the above object: + +~~~Java +SampleBean sampleBean = new SampleBean(); +~~~ + +And one line code as: + +~~~Java +List violatedConstraints = beanUtils.getValidator().getConstraintViolationsMessages(sampleBean); +~~~ + +this will returns a list containing a constraint validation message for the `id` field as it's null and the constraint: `@NotNull` is not met. + +in case it's needed to have the `ConstraintViolation` object: +~~~Java +Set> violatedConstraints = beanUtils.getValidator().getConstraintViolations(sampleBean); +~~~ From e539ac50981d2ed653f903af96fc4f6c2cce37f0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 May 2019 18:28:38 +0200 Subject: [PATCH 0564/1786] Added test cases for ReflectionUtils class --- .../beans/utils/ReflectionUtilsTest.java | 73 ++++++++++++++++++- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index a89f9690a..68d658583 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -49,8 +49,12 @@ import com.hotels.beans.error.MissingFieldException; import com.hotels.beans.error.MissingMethodException; +import com.hotels.beans.model.ItemType; +import com.hotels.beans.model.MapElemType; +import com.hotels.beans.model.MapType; import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.immutable.ImmutableToFoo; +import com.hotels.beans.sample.immutable.ImmutableToSubFoo; import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooSimple; @@ -66,6 +70,7 @@ public class ReflectionUtilsTest { private static final String EXPECTED_SETTER_METHOD_NAME = "setId"; private static final String DECLARING_CLASS_NAME = "declaringClassName"; private static final String INVOKE_METHOD_NAME = "invokeMethod"; + private static final String VERY_COMPLEX_MAP_FIELD_NAME = "veryComplexMap"; /** * The class to be tested. @@ -300,7 +305,7 @@ public void testGetParameterAnnotationReturnsNullIfTheAnnotationDoesNotExists() } /** - * Tests that the method {@code invokeMethod} works properly. + * Tests that the method {@code getSetterMethodForField} works properly. * @throws Exception if something goes wrong. */ @Test @@ -317,7 +322,7 @@ public void testInvokeMethodWorksProperly() throws Exception { } /** - * Tests that the method {@code invokeMethod} raises an {@link InvocationTargetException} if the argument is wrong. + * Tests that the method {@code getSetterMethodForField} raises an {@link InvocationTargetException} if the argument is wrong. * @throws Exception if something goes wrong. */ @Test(expectedExceptions = InvocationTargetException.class) @@ -331,7 +336,7 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong } /** - * Tests that the method {@code invokeMethod} works properly. + * Tests that the method {@code getDeclaredField} works properly. */ @Test public void testGetDeclaredFieldWorksProperly() { @@ -345,7 +350,7 @@ public void testGetDeclaredFieldWorksProperly() { } /** - * Tests that the method {@code invokeMethod} throws a {@link MissingFieldException} if the field does not exists. + * Tests that the method {@code getDeclaredField} throws a {@link MissingFieldException} if the field does not exists. */ @Test(expectedExceptions = MissingFieldException.class) public void testGetDeclaredFieldRaisesAnExceptionIfTheFieldDoesNotExists() { @@ -358,6 +363,66 @@ public void testGetDeclaredFieldRaisesAnExceptionIfTheFieldDoesNotExists() { assertNotNull(actual); } + /** + * Tests that the method {@code getDeclaredFieldType} works properly. + */ + @Test + public void testGetDeclaredFieldTypeWorksProperly() { + // GIVEN + + // WHEN + Class actual = underTest.getDeclaredFieldType(ID_FIELD_NAME, FromFooSubClass.class); + + // THEN + assertNotNull(actual); + } + + /** + * Tests that the method {@code getGenericFieldType} works properly. + */ + @Test + public void testGetGenericFieldTypeWorksProperly() { + // GIVEN + Field field = underTest.getDeclaredField(LIST_FIELD_NAME, ImmutableToFoo.class); + + // WHEN + Class actual = underTest.getGenericFieldType(field); + + // THEN + assertEquals(String.class, actual); + } + + /** + * Tests that the method {@code getGenericFieldType} works properly. + */ + @Test + public void testMapGenericFieldTypeWorksProperly() { + // GIVEN + MapElemType keyType = ItemType.builder() + .objectClass(String.class) + .build(); + final MapType expectedElemType = new MapType(keyType, keyType); + final MapType expectedMapType = new MapType(keyType, expectedElemType); + Field field = underTest.getDeclaredField(VERY_COMPLEX_MAP_FIELD_NAME, ImmutableToSubFoo.class); + + // WHEN + MapType actual = underTest.getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); + ItemType expectedMapKeyType = (ItemType) expectedMapType.getKeyType(); + ItemType actualMapKeyType = (ItemType) actual.getKeyType(); + ItemType expectedNestedMapKeyType = (ItemType) ((MapType) expectedMapType.getElemType()).getKeyType(); + ItemType actualNestedMapKeyType = (ItemType) ((MapType) actual.getElemType()).getKeyType(); + ItemType expectedNestedMapElemType = (ItemType) ((MapType) expectedMapType.getElemType()).getElemType(); + ItemType actualNestedMapElemType = (ItemType) ((MapType) actual.getElemType()).getElemType(); + + // THEN + assertEquals(expectedMapKeyType.getObjectClass(), actualMapKeyType.getObjectClass()); + assertEquals(expectedMapKeyType.getGenericClass(), actualMapKeyType.getGenericClass()); + assertEquals(expectedNestedMapKeyType.getObjectClass(), actualNestedMapKeyType.getObjectClass()); + assertEquals(expectedNestedMapKeyType.getGenericClass(), actualNestedMapKeyType.getGenericClass()); + assertEquals(expectedNestedMapElemType.getObjectClass(), actualNestedMapElemType.getObjectClass()); + assertEquals(expectedNestedMapElemType.getGenericClass(), actualNestedMapElemType.getGenericClass()); + } + /** * Tests that the method {@code setFieldValue} works properly. */ From 3a70cebc65caeb4d983f5ddf4db813769f70d341 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 May 2019 18:42:32 +0200 Subject: [PATCH 0565/1786] Completed tests for utils package --- .../beans/utils/ReflectionUtilsTest.java | 56 +++++++++++++++++-- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index 68d658583..d5e3dd994 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -53,6 +53,7 @@ import com.hotels.beans.model.MapElemType; import com.hotels.beans.model.MapType; import com.hotels.beans.sample.FromFooSubClass; +import com.hotels.beans.sample.FromSubFoo; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToSubFoo; import com.hotels.beans.sample.mutable.MutableToFoo; @@ -65,9 +66,11 @@ public class ReflectionUtilsTest { private static final String ID_FIELD_NAME = "id"; private static final String NOT_EXISTING_FIELD_NAME = "notExistingField"; private static final String LIST_FIELD_NAME = "list"; + private static final String PHONE_NUMBERS_FIELD_NAME = "phoneNumbers"; private static final String GETTER_METHOD_PREFIX_METHOD_NAME = "getGetterMethodPrefix"; - private static final String CHECK_FIELD_NAME = "check"; private static final String EXPECTED_SETTER_METHOD_NAME = "setId"; + private static final String GET_FIELD_VALUE_DIRECT_ACCESS_METHOD_NAME = "getFieldValueDirectAccess"; + private static final String CHECK_FIELD_NAME = "check"; private static final String DECLARING_CLASS_NAME = "declaringClassName"; private static final String INVOKE_METHOD_NAME = "invokeMethod"; private static final String VERY_COMPLEX_MAP_FIELD_NAME = "veryComplexMap"; @@ -87,7 +90,7 @@ public void beforeClass() { } /** - * Tests that the method {@code getFieldValueDirectAccess} returns the expected value. + * Tests that the method {@code getFieldValue} returns the expected value. */ @Test public void testGetFieldValueWorksAsExpected() { @@ -103,21 +106,51 @@ public void testGetFieldValueWorksAsExpected() { } /** - * Tests that the method {@code getFieldValueDirectAccess} throws Exception if the field does not exists. + * Tests that the method {@code getFieldValue} throws Exception if the field does not exists. */ @Test(expectedExceptions = MissingFieldException.class) public void testGetFieldValueThrowsExceptionIfTheFieldDoesNotExists() { // GIVEN MutableToFoo mutableToFoo = new MutableToFoo(); + + // WHEN + underTest.getFieldValue(mutableToFoo, NOT_EXISTING_FIELD_NAME); + } + + /** + * Tests that the method {@code getFieldValueDirectAccess} returns the expected value. + * @throws Exception if an error occurs + */ + @Test + public void testGetFieldValueDirectAccessWorksAsExpected() throws Exception { + // GIVEN + MutableToFoo mutableToFoo = new MutableToFoo(); mutableToFoo.setId(ZERO); + Method getFieldValueDirectAccessMethod = ReflectionUtils.class.getDeclaredMethod(GET_FIELD_VALUE_DIRECT_ACCESS_METHOD_NAME, Object.class, String.class); + getFieldValueDirectAccessMethod.setAccessible(true); // WHEN - Object actual = underTest.getFieldValue(mutableToFoo, NOT_EXISTING_FIELD_NAME); + Object actual = getFieldValueDirectAccessMethod.invoke(underTest, mutableToFoo, ID_FIELD_NAME); // THEN assertEquals(ZERO, actual); } + /** + * Tests that the method {@code getFieldValueDirectAccess} throws Exception if the field does not exists. + * @throws Exception if an error occurs + */ + @Test(expectedExceptions = java.lang.reflect.InvocationTargetException.class) + public void testGetFieldValueDirectAccessThrowsExceptionIfTheFieldDoesNotExists() throws Exception { + // GIVEN + MutableToFoo mutableToFoo = new MutableToFoo(); + Method getFieldValueDirectAccessMethod = ReflectionUtils.class.getDeclaredMethod(GET_FIELD_VALUE_DIRECT_ACCESS_METHOD_NAME, Object.class, String.class); + getFieldValueDirectAccessMethod.setAccessible(true); + + // WHEN + getFieldValueDirectAccessMethod.invoke(underTest, mutableToFoo, NOT_EXISTING_FIELD_NAME); + } + /** * Tests that the method {@code handleReflectionException} raises the expected exception. */ @@ -392,6 +425,21 @@ public void testGetGenericFieldTypeWorksProperly() { assertEquals(String.class, actual); } + /** + * Tests that the method {@code getArrayType} works properly. + */ + @Test + public void testGetArrayTypeWorksProperly() { + // GIVEN + Field phoneNumbersField = underTest.getDeclaredField(PHONE_NUMBERS_FIELD_NAME, FromSubFoo.class); + + // WHEN + Class actual = underTest.getArrayType(phoneNumbersField); + + // THEN + assertEquals(int.class, actual); + } + /** * Tests that the method {@code getGenericFieldType} works properly. */ From 9c1e76c002a15e55c10f4a31d5cfdcd7026450ec Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 23 May 2019 10:30:48 +0200 Subject: [PATCH 0566/1786] Added test cases --- .../beans/utils/ReflectionUtilsTest.java | 100 +++++++++++++++--- 1 file changed, 84 insertions(+), 16 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index d5e3dd994..ca05a56d3 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -52,6 +52,7 @@ import com.hotels.beans.model.ItemType; import com.hotels.beans.model.MapElemType; import com.hotels.beans.model.MapType; +import com.hotels.beans.sample.FromFooSimpleNoGetters; import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.FromSubFoo; import com.hotels.beans.sample.immutable.ImmutableToFoo; @@ -65,6 +66,7 @@ public class ReflectionUtilsTest { private static final String ID_FIELD_NAME = "id"; private static final String NOT_EXISTING_FIELD_NAME = "notExistingField"; + private static final String NESTED_OBJECT_FIELD_NAME = "nestedObject.name"; private static final String LIST_FIELD_NAME = "list"; private static final String PHONE_NUMBERS_FIELD_NAME = "phoneNumbers"; private static final String GETTER_METHOD_PREFIX_METHOD_NAME = "getGetterMethodPrefix"; @@ -91,18 +93,34 @@ public void beforeClass() { /** * Tests that the method {@code getFieldValue} returns the expected value. + * @param testCaseDescription the test case description + * @param beanObject the java bean from which the value has to be retrieved + * @param fieldName the name of the field to retrieve + * @param expectedResult the expected result */ - @Test - public void testGetFieldValueWorksAsExpected() { + @Test(dataProvider = "dataGetFieldValueTesting") + public void testGetFieldValueWorksAsExpected(final String testCaseDescription, final Object beanObject, final String fieldName, final Object expectedResult) { // GIVEN - MutableToFoo mutableToFoo = new MutableToFoo(); - mutableToFoo.setId(ZERO); // WHEN - Object actual = underTest.getFieldValue(mutableToFoo, ID_FIELD_NAME); + Object actual = underTest.getFieldValue(beanObject, fieldName); // THEN - assertEquals(ZERO, actual); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code getFieldValue}. + * @return parameters to be used for testing the the method {@code getFieldValue}. + */ + @DataProvider + private Object[][] dataGetFieldValueTesting() { + MutableToFoo mutableToFoo = createMutableToFoo(ZERO); + return new Object[][] { + {"Tests that the method returns the field value", mutableToFoo, ID_FIELD_NAME, ZERO}, + {"Tests that the method returns null if the required field is inside a null object", mutableToFoo, NESTED_OBJECT_FIELD_NAME, null}, + {"Tests that the method returns the field value even if there is no getter method defined", createFromFooSimpleNoGetters(), ID_FIELD_NAME, ZERO} + }; } /** @@ -111,7 +129,7 @@ public void testGetFieldValueWorksAsExpected() { @Test(expectedExceptions = MissingFieldException.class) public void testGetFieldValueThrowsExceptionIfTheFieldDoesNotExists() { // GIVEN - MutableToFoo mutableToFoo = new MutableToFoo(); + MutableToFoo mutableToFoo = createMutableToFoo(null); // WHEN underTest.getFieldValue(mutableToFoo, NOT_EXISTING_FIELD_NAME); @@ -124,8 +142,7 @@ public void testGetFieldValueThrowsExceptionIfTheFieldDoesNotExists() { @Test public void testGetFieldValueDirectAccessWorksAsExpected() throws Exception { // GIVEN - MutableToFoo mutableToFoo = new MutableToFoo(); - mutableToFoo.setId(ZERO); + MutableToFoo mutableToFoo = createMutableToFoo(ZERO); Method getFieldValueDirectAccessMethod = ReflectionUtils.class.getDeclaredMethod(GET_FIELD_VALUE_DIRECT_ACCESS_METHOD_NAME, Object.class, String.class); getFieldValueDirectAccessMethod.setAccessible(true); @@ -137,18 +154,34 @@ public void testGetFieldValueDirectAccessWorksAsExpected() throws Exception { } /** - * Tests that the method {@code getFieldValueDirectAccess} throws Exception if the field does not exists. + * Tests that the method {@code getFieldValueDirectAccess} throws Exception in specific cases. + * @param testCaseDescription the test case description + * @param beanObject the java bean from which the value has to be retrieved + * @param fieldName the name of the field to retrieve * @throws Exception if an error occurs */ - @Test(expectedExceptions = java.lang.reflect.InvocationTargetException.class) - public void testGetFieldValueDirectAccessThrowsExceptionIfTheFieldDoesNotExists() throws Exception { + @Test(dataProvider = "dataGetFieldValueDirectAccessTesting", expectedExceptions = java.lang.reflect.InvocationTargetException.class) + public void testGetFieldValueDirectAccessThrowsExceptionIfTheFieldDoesNotExists(final String testCaseDescription, + final Object beanObject, final String fieldName) throws Exception { // GIVEN - MutableToFoo mutableToFoo = new MutableToFoo(); Method getFieldValueDirectAccessMethod = ReflectionUtils.class.getDeclaredMethod(GET_FIELD_VALUE_DIRECT_ACCESS_METHOD_NAME, Object.class, String.class); getFieldValueDirectAccessMethod.setAccessible(true); // WHEN - getFieldValueDirectAccessMethod.invoke(underTest, mutableToFoo, NOT_EXISTING_FIELD_NAME); + getFieldValueDirectAccessMethod.invoke(underTest, beanObject, fieldName); + } + + /** + * Creates the parameters to be used for testing the method {@code getFieldValueDirectAccess}. + * @return parameters to be used for testing the the method {@code getFieldValueDirectAccess}. + */ + @DataProvider + private Object[][] dataGetFieldValueDirectAccessTesting() { + MutableToFoo mutableToFoo = createMutableToFoo(null); + return new Object[][] { + {"Tests that the method throws Exception if the field does not exists", mutableToFoo, NOT_EXISTING_FIELD_NAME}, + {"Tests that the method throws Exception if the bean is null", null, NESTED_OBJECT_FIELD_NAME} + }; } /** @@ -215,6 +248,7 @@ public void testGetMapGenericTypeThrowsIllegalArgumentExceptionWhenTheGivenTypeI * @param testCaseDescription the test case description * @param testClass the class to test * @param expectedResult the expected result + * @throws Exception if something goes wrong */ @Test(dataProvider = "dataGetGetterMethodPrefixTesting") public void testGetGetterMethodPrefixWorksAsExpected(final String testCaseDescription, final Class testClass, final String expectedResult) throws Exception { @@ -344,7 +378,7 @@ public void testGetParameterAnnotationReturnsNullIfTheAnnotationDoesNotExists() @Test public void testInvokeMethodWorksProperly() throws Exception { // GIVEN - MutableToFoo mutableToFoo = new MutableToFoo(); + MutableToFoo mutableToFoo = createMutableToFoo(null); Method idSetterMethod = underTest.getSetterMethodForField(MutableToFoo.class, ID_FIELD_NAME, BigInteger.class); // WHEN @@ -361,7 +395,7 @@ public void testInvokeMethodWorksProperly() throws Exception { @Test(expectedExceptions = InvocationTargetException.class) public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong() throws Exception { // GIVEN - MutableToFoo mutableToFoo = new MutableToFoo(); + MutableToFoo mutableToFoo = createMutableToFoo(null); Method idSetterMethod = underTest.getSetterMethodForField(MutableToFoo.class, LIST_FIELD_NAME, List.class); // WHEN @@ -487,6 +521,19 @@ public void testSetFieldValueWorksProperly() { assertEquals(ONE, mutableToFoo.getId()); } + /** + * Tests that the method {@code setFieldValue} tries to inject the value through the setter method if the direct access fails. + */ + @Test(expectedExceptions = NullPointerException.class) + public void testSetFieldValueTriesToInjectThroughSetterMethodInCaseOfErrors() { + // GIVEN + MutableToFooSimple mutableToFoo = new MutableToFooSimple(); + Field idField = underTest.getDeclaredField(ID_FIELD_NAME, mutableToFoo.getClass()); + + // WHEN + underTest.setFieldValue(null, idField, ONE); + } + /** * Tests that the method {@code setFieldValue} throws an {@link IllegalArgumentException} if the field value is not valid. */ @@ -511,4 +558,25 @@ private Method getMethod(final String methodName) throws NoSuchMethodException { invokeMethod.setAccessible(true); return invokeMethod; } + + /** + * Creates an instance of of {@link FromFooSimpleNoGetters}. + * @return an instance of {@link FromFooSimpleNoGetters} + */ + private FromFooSimpleNoGetters createFromFooSimpleNoGetters() { + FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(); + fromFooSimpleNoGetters.setId(ZERO); + return fromFooSimpleNoGetters; + } + + /** + * Creates an instance of of {@link MutableToFoo} with the given id. + * @param id the id to assign + * @return an instance of {@link MutableToFoo} + */ + private MutableToFoo createMutableToFoo(final BigInteger id) { + MutableToFoo mutableToFoo = new MutableToFoo(); + mutableToFoo.setId(id); + return mutableToFoo; + } } From 340250977d10eb065ef9492a1338fbd762d079e0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 23 May 2019 18:45:58 +0200 Subject: [PATCH 0567/1786] Updated changelog --- CHANGELOG-JDK8.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 581a430d8..1c33f1b36 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.1.19] 2019.05.23 +#### Changes +* Made the project multi module + ### [1.1.18] 2019.05.18 #### Changes * Removed deprecated method: `setValidationDisabled` From b10a117ae9a8933be0a57f7a478e14b55f9f5aaf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 08:00:27 +0200 Subject: [PATCH 0568/1786] - Removed converter module - Added skip of submodule release --- bean-utils-library/pom.xml | 5 - bull-common/pom.xml | 7 + bull-converter/pom.xml | 24 --- .../beans/conversion/ConversionAnalyzer.java | 123 --------------- .../beans/conversion/ConversionProcessor.java | 126 --------------- .../ConversionProcessorFactory.java | 73 --------- .../conversion/StringConversionProcessor.java | 144 ------------------ .../hotels/beans/conversion/package-info.java | 20 --- .../org.mockito.plugins.MockMaker | 1 - pom.xml | 14 +- 10 files changed, 20 insertions(+), 517 deletions(-) delete mode 100644 bull-converter/pom.xml delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java delete mode 100644 bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 7e3ea4ccb..46958cd80 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -19,11 +19,6 @@ bull-common ${project.version} - - - - - com.hotels.beans diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 357bbff64..6276ba4fd 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -54,6 +54,13 @@ + + org.apache.maven.plugins + maven-deploy-plugin + + true + +
      \ No newline at end of file diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml deleted file mode 100644 index dbcdcd347..000000000 --- a/bull-converter/pom.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - 4.0.0 - BULL - Converter - bull-converter - jar - Provides the conversion related classes - - - com.hotels.beans - bean-utils-library-parent - 1.4.2-SNAPSHOT - - - - - com.hotels.beans - bull-common - ${project.version} - - - \ No newline at end of file diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java deleted file mode 100644 index a2da54a56..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion; - -import static java.util.Optional.empty; -import static java.util.Optional.of; - -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.conversion.ConversionProcessorFactory.getConversionProcessor; - -import java.util.Optional; -import java.util.function.Function; - -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.utils.ClassUtils; - -/** - * This class analyzes the two classes received in input, and returns the conversion processor to be used. - */ -public final class ConversionAnalyzer { - /** - * CacheManager instance {@link CacheManager}. - */ - private static final CacheManager CACHE_MANAGER = getCacheManager("conversionAnalyzer"); - - /** - * Class utils instance {@link ClassUtils}. - */ - private final ClassUtils classUtils; - - /** - * Default constructor. - */ - public ConversionAnalyzer() { - this.classUtils = new ClassUtils(); - } - - /** - * Analyzes Fields given as input and returns the conversion processor. - * @param sourceFieldType source field class - * @param destinationFieldType the destination field class - * @return an {@link Optional} containing the conversion function (if exists) - */ - @SuppressWarnings("unchecked") - public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { - final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional> conversionFunction = empty(); - if (destinationFieldType != sourceFieldType && classUtils.isPrimitiveType(sourceFieldType) && classUtils.isPrimitiveType(destinationFieldType)) { - conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); - } - CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); - return conversionFunction; - }); - } - - /** - * Returns the type transformer function for the given type. - * @param conversionProcessor the {@link ConversionProcessor} for the given type - * @param sourceFieldType the source field class - * @return the conversion function - */ - @SuppressWarnings("unchecked") - private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { - final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional> conversionFunction; - if (sourceFieldType == String.class) { - conversionFunction = of(conversionProcessor.convertString()); - } else if (sourceFieldType == Byte.class) { - conversionFunction = of(conversionProcessor.convertByte()); - } else if (sourceFieldType == byte.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveByte()); - } else if (sourceFieldType == Short.class) { - conversionFunction = of(conversionProcessor.convertShort()); - } else if (sourceFieldType == short.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveShort()); - } else if (sourceFieldType == Integer.class) { - conversionFunction = of(conversionProcessor.convertInteger()); - } else if (sourceFieldType == int.class) { - conversionFunction = of(conversionProcessor.convertInt()); - } else if (sourceFieldType == Long.class) { - conversionFunction = of(conversionProcessor.convertLong()); - } else if (sourceFieldType == long.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveLong()); - } else if (sourceFieldType == Float.class) { - conversionFunction = of(conversionProcessor.convertFloat()); - } else if (sourceFieldType == float.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveFloat()); - } else if (sourceFieldType == Double.class) { - conversionFunction = of(conversionProcessor.convertDouble()); - } else if (sourceFieldType == double.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveDouble()); - } else if (sourceFieldType == Character.class) { - conversionFunction = of(conversionProcessor.convertCharacter()); - } else if (sourceFieldType == char.class) { - conversionFunction = of(conversionProcessor.convertChar()); - } else if (sourceFieldType == Boolean.class) { - conversionFunction = of(conversionProcessor.convertBoolean()); - } else if (sourceFieldType == boolean.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveBoolean()); - } else { - conversionFunction = empty(); - } - CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); - return conversionFunction; - }); - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java deleted file mode 100644 index 26c270015..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion; - -import java.util.function.Function; - -/** - * Conversion methods for all primitive types. - */ -public interface ConversionProcessor { - /** - * Converts a byte type. - * @return the converted value - */ - Function convertPrimitiveByte(); - - /** - * Converts a {@link Byte} type. - * @return the converted value - */ - Function convertByte(); - - /** - * Converts a short type. - * @return the converted value - */ - Function convertPrimitiveShort(); - - /** - * Converts a {@link Short} type. - * @return the converted value - */ - Function convertShort(); - - /** - * Converts an int type. - * @return the converted value - */ - Function convertInt(); - - /** - * Converts an {@link Integer} type. - * @return the converted value - */ - Function convertInteger(); - - /** - * Converts a long type. - * @return the converted value - */ - Function convertPrimitiveLong(); - - /** - * Converts a {@link Long} type. - * @return the converted value - */ - Function convertLong(); - - /** - * Converts a float type. - * @return the converted value - */ - Function convertPrimitiveFloat(); - - /** - * Converts an {@link Float} type. - * @return the converted value - */ - Function convertFloat(); - - /** - * Converts a double type. - * @return the converted value - */ - Function convertPrimitiveDouble(); - - /** - * Converts a {@link Double} type. - * @return the converted value - */ - Function convertDouble(); - - /** - * Converts a char type. - * @return the converted value - */ - Function convertChar(); - - /** - * Converts a {@link Character} type. - * @return the converted value - */ - Function convertCharacter(); - - /** - * Converts a boolean type. - * @return the converted value - */ - Function convertPrimitiveBoolean(); - - /** - * Converts a {@link Boolean} type. - * @return the converted value - */ - Function convertBoolean(); - - /** - * Converts a {@link String} type. - * @return the converted value - */ - Function convertString(); -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java deleted file mode 100644 index 9affbb8b5..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion; - -import static lombok.AccessLevel.PRIVATE; - -import lombok.NoArgsConstructor; - -/** - * Creates a {@link ConversionProcessor} instance for the given class. - */ -@NoArgsConstructor(access = PRIVATE) -public final class ConversionProcessorFactory { - /** - * Returns a conversion processor for the given type. - * @param clazz the class for which the conversion processor has to be retrieved. - * @return a conversion processor for the given type - */ - public static ConversionProcessor getConversionProcessor(final Class clazz) { - ConversionProcessor conversionProcessor = null; - if (clazz == String.class) { - conversionProcessor = new StringConversionProcessor(); - } -// else if (clazz == Byte.class) { -// conversionProcessor = new ByteConversionProcessor(); -// } else if (clazz == byte.class) { -// conversionProcessor = new PrimitiveByteConversionProcessor(); -// } else if (clazz == Short.class) { -// conversionProcessor = new ShortConversionProcessor(); -// } else if (clazz == short.class) { -// conversionProcessor = new PrimitiveShortConversionProcessor(); -// } else if (clazz == Integer.class) { -// conversionProcessor = new IntegerConversionProcessor(); -// } else if (clazz == int.class) { -// conversionProcessor = new IntConversionProcessor(); -// } else if (clazz == Long.class) { -// conversionProcessor = new LongConversionProcessor(); -// } else if (clazz == long.class) { -// conversionProcessor = new PrimitiveLongConversionProcessor(); -// } else if (clazz == Float.class) { -// conversionProcessor = new FloatConversionProcessor(); -// } else if (clazz == float.class) { -// conversionProcessor = new PrimitiveFloatConversionProcessor(); -// } else if (clazz == Double.class) { -// conversionProcessor = new DoubleConversionProcessor(); -// } else if (clazz == double.class) { -// conversionProcessor = new PrimitiveDoubleConversionProcessor(); -// } else if (clazz == Character.class) { -// conversionProcessor = new CharacterConversionProcessor(); -// } else if (clazz == char.class) { -// conversionProcessor = new CharConversionProcessor(); -// } else if (clazz == Boolean.class) { -// conversionProcessor = new BooleanConversionProcessor(); -// } else if (clazz == boolean.class) { -// conversionProcessor = new PrimitiveBooleanConversionProcessor(); -// } - return conversionProcessor; - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java deleted file mode 100644 index 1f0711f06..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion; - -import java.util.function.Function; - -/** - * Provides all method for converting any primitive type to a String. - */ -public class StringConversionProcessor implements ConversionProcessor { - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveByte() { - return val -> Byte.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertByte() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveShort() { - return val -> Short.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertShort() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertInt() { - return val -> Integer.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertInteger() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveLong() { - return val -> Long.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertLong() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveFloat() { - return val -> Float.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertFloat() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveDouble() { - return val -> Double.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertDouble() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertChar() { - return val -> Character.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertCharacter() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveBoolean() { - return val -> Boolean.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertBoolean() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertString() { - return val -> val; - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java deleted file mode 100644 index eb89044b2..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Type conversion processor package. - */ - -package com.hotels.beans.conversion; diff --git a/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea..000000000 --- a/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/pom.xml b/pom.xml index 07ee49c32..f04908ad3 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,6 @@ bean-utils-library bull-common - @@ -35,6 +34,7 @@ ${jdk.version} 3.12.0 3.1.0 + 2.8.2 2.1.5.RELEASE 1.18.8 3.9 @@ -329,6 +329,11 @@ false + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy.plugin.version} + org.jacoco jacoco-maven-plugin @@ -507,6 +512,13 @@ + + org.apache.maven.plugins + maven-deploy-plugin + + true + + From 4b0a2479dfd2dab68461f8ed9b7fa5c9669498e4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 08:07:47 +0200 Subject: [PATCH 0569/1786] fixed minor in javadoc --- .../src/main/java/com/hotels/beans/validator/Validator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bull-common/src/main/java/com/hotels/beans/validator/Validator.java b/bull-common/src/main/java/com/hotels/beans/validator/Validator.java index 60e7bfe8f..0726b162a 100644 --- a/bull-common/src/main/java/com/hotels/beans/validator/Validator.java +++ b/bull-common/src/main/java/com/hotels/beans/validator/Validator.java @@ -49,7 +49,6 @@ public interface Validator { * @param the object class * @param k the object to check * @throws com.hotels.beans.error.InvalidBeanException {@link com.hotels.beans.error.InvalidBeanException} if the validation fails - * @return */ void validate(K k); From 5ecc57900b4da753995665ad873a22f89d380afc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 08:14:10 +0200 Subject: [PATCH 0570/1786] Prepared version for being released --- .travis.yml | 5 +++-- CHANGELOG.md | 4 ++++ bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 766d6c46e..bb8436abc 100755 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,8 @@ jobs: tags: true notifications: slack: + rooms: + - bull-crew:hTuN6VsJod6aUOU6FWIFiQca on_failure: change on_success: change - on_pull_requests: true - secure: GXhjJv7xyR+ooIUiFLESGZ9x4WsQzCpT3Be6sy5YVyzk2JpGRh+uCJ1cjG3D2/AkUJ70xBEi5Rnpr2uAKKEIaK291hHyQCZYIWisU/eUtEU0S65hiSUIjgE8m8B1FVqL5RE7/o6xOmIIYYMTPklcdS8v3PMDPyvzF1T40wC1BWZaO5fxuZScPj5+od8UB0HoLENczGHzqmaTFKEJrlVKGefnOZLAX/Z84mwSitSUDipuJ0M+LdF1GLr5b6gk3hwwy1FZ6CUiQEMt25xT1qBX4Z86TZ3r0NbOkpWNUoEhhbS2CIKQ1q4qWZSoNrju+lbg9SjtlglTumWaTFVYoTVc4I6LrveMHIBUy/sOLuEuoVpThEcK7fAB9NJ3MLR8LAcN6h9EbmWWVj/ufOXM1AMC5ZxESlX9odynZ3b5zqTPerB/Px3eOjqCSLxDH39jueXrBrGNuFW6TaMSuyra6z+yx9ut3JrQwKnfHytUc5Fyu+5wqFJ6R0DWzy1+dzWXw7o0IKaqZ/knxrR1c9clkFXp+3XACupdnha1pI4YDChGWYEIiU4IUL3uB2c9wHcvUlOei/JrBAsDazBJBNxpsA0UxoXIqsZYvi4xEW28GbrUNjUFd049isBPnUiKOIs8hemjZjHmpqbO6X5Qn2cHMzZQoysqxuKnOudcsDIonqldtf0= + on_pull_requests: true \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 60af5a922..d7ed9ba70 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.4.1.1] 2019.05.24 +#### Changes +* Made the project multi module + ### [1.4.1] 2019.05.18 #### Changes * Removed deprecated method: `setValidationDisabled` diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 46958cd80..452d86e9e 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -10,7 +10,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2-SNAPSHOT + 1.4.1.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 6276ba4fd..9b64be211 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -11,7 +11,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2-SNAPSHOT + 1.4.1.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index f04908ad3..ca9e123d1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.2-SNAPSHOT + 1.4.1.1-SNAPSHOT pom 2019 From 6d83600494244bd0f427ec0601614a55d2fc9316 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 08:17:40 +0200 Subject: [PATCH 0571/1786] [maven-release-plugin] prepare release 1.4.1.1 --- bean-utils-library/pom.xml | 6 ++---- bull-common/pom.xml | 6 ++---- pom.xml | 7 +++---- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 452d86e9e..59c491e41 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 BULL - Core bean-utils-library @@ -10,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.1.1-SNAPSHOT + 1.4.1.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 9b64be211..b0691e5e3 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 BULL - Common bull-common @@ -11,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.1.1-SNAPSHOT + 1.4.1.1 diff --git a/pom.xml b/pom.xml index ca9e123d1..775f694f3 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 BULL - Bean Utils Light Library com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.1.1-SNAPSHOT + 1.4.1.1 pom 2019 @@ -66,7 +65,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.1.1 From d26bfcc0564efb4c64baa56da0b0d00fc6965b8a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 08:17:47 +0200 Subject: [PATCH 0572/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 59c491e41..d8786b1e2 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.1.1 + 1.4.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index b0691e5e3..e5ed9a7ca 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.1.1 + 1.4.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 775f694f3..f6290511c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.1.1 + 1.4.2-SNAPSHOT pom 2019 @@ -65,7 +65,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.1.1 + HEAD From 2f66ccd91dc6fb94a51e11a0c7789320a294ef96 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 08:26:56 +0200 Subject: [PATCH 0573/1786] Added converter module --- .travis.yml | 2 +- bean-utils-library/pom.xml | 5 + bull-converter/pom.xml | 36 +++++ .../beans/conversion/ConversionAnalyzer.java | 123 +++++++++++++++ .../beans/conversion/ConversionProcessor.java | 126 +++++++++++++++ .../ConversionProcessorFactory.java | 73 +++++++++ .../conversion/StringConversionProcessor.java | 144 ++++++++++++++++++ .../hotels/beans/conversion/package-info.java | 20 +++ .../org.mockito.plugins.MockMaker | 1 + pom.xml | 1 + 10 files changed, 530 insertions(+), 1 deletion(-) create mode 100644 bull-converter/pom.xml create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java create mode 100644 bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/.travis.yml b/.travis.yml index bb8436abc..78a3e9aaf 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - install: travis_retry mvn clean install + install: travis_retry mvn clean install -DskipTests -Dmaven.test.skip=true - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index d8786b1e2..5dc87a5eb 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -17,6 +17,11 @@ bull-common ${project.version} + + com.hotels.beans + bull-converter + ${project.version} + com.hotels.beans diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml new file mode 100644 index 000000000..0b7c77038 --- /dev/null +++ b/bull-converter/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + BULL - Converter + bull-converter + jar + Provides the conversion related classes + + + com.hotels.beans + bean-utils-library-parent + 1.4.2-SNAPSHOT + + + + + com.hotels.beans + bull-common + ${project.version} + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + \ No newline at end of file diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java new file mode 100644 index 000000000..a2da54a56 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java @@ -0,0 +1,123 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import static java.util.Optional.empty; +import static java.util.Optional.of; + +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.conversion.ConversionProcessorFactory.getConversionProcessor; + +import java.util.Optional; +import java.util.function.Function; + +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.utils.ClassUtils; + +/** + * This class analyzes the two classes received in input, and returns the conversion processor to be used. + */ +public final class ConversionAnalyzer { + /** + * CacheManager instance {@link CacheManager}. + */ + private static final CacheManager CACHE_MANAGER = getCacheManager("conversionAnalyzer"); + + /** + * Class utils instance {@link ClassUtils}. + */ + private final ClassUtils classUtils; + + /** + * Default constructor. + */ + public ConversionAnalyzer() { + this.classUtils = new ClassUtils(); + } + + /** + * Analyzes Fields given as input and returns the conversion processor. + * @param sourceFieldType source field class + * @param destinationFieldType the destination field class + * @return an {@link Optional} containing the conversion function (if exists) + */ + @SuppressWarnings("unchecked") + public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { + final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { + Optional> conversionFunction = empty(); + if (destinationFieldType != sourceFieldType && classUtils.isPrimitiveType(sourceFieldType) && classUtils.isPrimitiveType(destinationFieldType)) { + conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); + } + CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); + return conversionFunction; + }); + } + + /** + * Returns the type transformer function for the given type. + * @param conversionProcessor the {@link ConversionProcessor} for the given type + * @param sourceFieldType the source field class + * @return the conversion function + */ + @SuppressWarnings("unchecked") + private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { + Optional> conversionFunction; + if (sourceFieldType == String.class) { + conversionFunction = of(conversionProcessor.convertString()); + } else if (sourceFieldType == Byte.class) { + conversionFunction = of(conversionProcessor.convertByte()); + } else if (sourceFieldType == byte.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveByte()); + } else if (sourceFieldType == Short.class) { + conversionFunction = of(conversionProcessor.convertShort()); + } else if (sourceFieldType == short.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveShort()); + } else if (sourceFieldType == Integer.class) { + conversionFunction = of(conversionProcessor.convertInteger()); + } else if (sourceFieldType == int.class) { + conversionFunction = of(conversionProcessor.convertInt()); + } else if (sourceFieldType == Long.class) { + conversionFunction = of(conversionProcessor.convertLong()); + } else if (sourceFieldType == long.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveLong()); + } else if (sourceFieldType == Float.class) { + conversionFunction = of(conversionProcessor.convertFloat()); + } else if (sourceFieldType == float.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveFloat()); + } else if (sourceFieldType == Double.class) { + conversionFunction = of(conversionProcessor.convertDouble()); + } else if (sourceFieldType == double.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveDouble()); + } else if (sourceFieldType == Character.class) { + conversionFunction = of(conversionProcessor.convertCharacter()); + } else if (sourceFieldType == char.class) { + conversionFunction = of(conversionProcessor.convertChar()); + } else if (sourceFieldType == Boolean.class) { + conversionFunction = of(conversionProcessor.convertBoolean()); + } else if (sourceFieldType == boolean.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveBoolean()); + } else { + conversionFunction = empty(); + } + CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); + return conversionFunction; + }); + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java new file mode 100644 index 000000000..26c270015 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java @@ -0,0 +1,126 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import java.util.function.Function; + +/** + * Conversion methods for all primitive types. + */ +public interface ConversionProcessor { + /** + * Converts a byte type. + * @return the converted value + */ + Function convertPrimitiveByte(); + + /** + * Converts a {@link Byte} type. + * @return the converted value + */ + Function convertByte(); + + /** + * Converts a short type. + * @return the converted value + */ + Function convertPrimitiveShort(); + + /** + * Converts a {@link Short} type. + * @return the converted value + */ + Function convertShort(); + + /** + * Converts an int type. + * @return the converted value + */ + Function convertInt(); + + /** + * Converts an {@link Integer} type. + * @return the converted value + */ + Function convertInteger(); + + /** + * Converts a long type. + * @return the converted value + */ + Function convertPrimitiveLong(); + + /** + * Converts a {@link Long} type. + * @return the converted value + */ + Function convertLong(); + + /** + * Converts a float type. + * @return the converted value + */ + Function convertPrimitiveFloat(); + + /** + * Converts an {@link Float} type. + * @return the converted value + */ + Function convertFloat(); + + /** + * Converts a double type. + * @return the converted value + */ + Function convertPrimitiveDouble(); + + /** + * Converts a {@link Double} type. + * @return the converted value + */ + Function convertDouble(); + + /** + * Converts a char type. + * @return the converted value + */ + Function convertChar(); + + /** + * Converts a {@link Character} type. + * @return the converted value + */ + Function convertCharacter(); + + /** + * Converts a boolean type. + * @return the converted value + */ + Function convertPrimitiveBoolean(); + + /** + * Converts a {@link Boolean} type. + * @return the converted value + */ + Function convertBoolean(); + + /** + * Converts a {@link String} type. + * @return the converted value + */ + Function convertString(); +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java new file mode 100644 index 000000000..9affbb8b5 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import static lombok.AccessLevel.PRIVATE; + +import lombok.NoArgsConstructor; + +/** + * Creates a {@link ConversionProcessor} instance for the given class. + */ +@NoArgsConstructor(access = PRIVATE) +public final class ConversionProcessorFactory { + /** + * Returns a conversion processor for the given type. + * @param clazz the class for which the conversion processor has to be retrieved. + * @return a conversion processor for the given type + */ + public static ConversionProcessor getConversionProcessor(final Class clazz) { + ConversionProcessor conversionProcessor = null; + if (clazz == String.class) { + conversionProcessor = new StringConversionProcessor(); + } +// else if (clazz == Byte.class) { +// conversionProcessor = new ByteConversionProcessor(); +// } else if (clazz == byte.class) { +// conversionProcessor = new PrimitiveByteConversionProcessor(); +// } else if (clazz == Short.class) { +// conversionProcessor = new ShortConversionProcessor(); +// } else if (clazz == short.class) { +// conversionProcessor = new PrimitiveShortConversionProcessor(); +// } else if (clazz == Integer.class) { +// conversionProcessor = new IntegerConversionProcessor(); +// } else if (clazz == int.class) { +// conversionProcessor = new IntConversionProcessor(); +// } else if (clazz == Long.class) { +// conversionProcessor = new LongConversionProcessor(); +// } else if (clazz == long.class) { +// conversionProcessor = new PrimitiveLongConversionProcessor(); +// } else if (clazz == Float.class) { +// conversionProcessor = new FloatConversionProcessor(); +// } else if (clazz == float.class) { +// conversionProcessor = new PrimitiveFloatConversionProcessor(); +// } else if (clazz == Double.class) { +// conversionProcessor = new DoubleConversionProcessor(); +// } else if (clazz == double.class) { +// conversionProcessor = new PrimitiveDoubleConversionProcessor(); +// } else if (clazz == Character.class) { +// conversionProcessor = new CharacterConversionProcessor(); +// } else if (clazz == char.class) { +// conversionProcessor = new CharConversionProcessor(); +// } else if (clazz == Boolean.class) { +// conversionProcessor = new BooleanConversionProcessor(); +// } else if (clazz == boolean.class) { +// conversionProcessor = new PrimitiveBooleanConversionProcessor(); +// } + return conversionProcessor; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java new file mode 100644 index 000000000..1f0711f06 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java @@ -0,0 +1,144 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import java.util.function.Function; + +/** + * Provides all method for converting any primitive type to a String. + */ +public class StringConversionProcessor implements ConversionProcessor { + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveByte() { + return val -> Byte.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertByte() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveShort() { + return val -> Short.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertShort() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertInt() { + return val -> Integer.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertInteger() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveLong() { + return val -> Long.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertLong() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveFloat() { + return val -> Float.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertFloat() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveDouble() { + return val -> Double.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertDouble() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertChar() { + return val -> Character.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertCharacter() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveBoolean() { + return val -> Boolean.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertBoolean() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertString() { + return val -> val; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java new file mode 100644 index 000000000..eb89044b2 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Type conversion processor package. + */ + +package com.hotels.beans.conversion; diff --git a/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/pom.xml b/pom.xml index f6290511c..153b35ef3 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,7 @@ bean-utils-library bull-common + bull-converter From 00df180b326f9a273dbf34e4f53ca266efb2ad13 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 13:59:00 +0200 Subject: [PATCH 0574/1786] Implemented logic that allows to apply a supplier transformation function --- .../hotels/beans/model/FieldTransformer.java | 41 +++++++++++++++++-- .../transformer/AbstractTransformer.java | 6 +-- .../beans/transformer/TransformerImpl.java | 9 ++-- .../transformer/TransformerSettings.java | 14 ++++++- .../ImmutableObjectTransformationTest.java | 2 +- 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java index 4ed6f4383..98f2c6c93 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java @@ -16,9 +16,11 @@ package com.hotels.beans.model; +import static java.util.Objects.nonNull; + import java.util.function.Function; +import java.util.function.Supplier; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; @@ -28,7 +30,6 @@ * @param input field type. * @param field value on with apply the function. */ -@AllArgsConstructor @Getter @ToString public class FieldTransformer { @@ -40,5 +41,39 @@ public class FieldTransformer { /** * The field transformer function. */ - private final Function transformerFunction; + private Function transformerFunction; + + /** + * The field transformer supplier + */ + private Supplier transformerSupplier; + + /** + * Creates a field transformer with a lambda function to be applied on the field. + * @param destFieldName the field name in the destination object. + * @param transformerFunction the transformer function to apply on field + */ + public FieldTransformer(final String destFieldName, final Function transformerFunction) { + this.destFieldName = destFieldName; + this.transformerFunction = transformerFunction; + } + + /** + * Creates a field transformer with a field supplier function to be applied on the field. + * @param destFieldName the field name in the destination object. + * @param transformerSupplier the transformer supplier to apply on field + */ + public FieldTransformer(final String destFieldName, final Supplier transformerSupplier) { + this.destFieldName = destFieldName; + this.transformerSupplier = transformerSupplier; + } + + /** + * Returns a transformed object by applying the defined transformed function or the supplier. + * @param objectToTransform the object to transform + * @return the transformed object + */ + public K getTransformedObject(final T objectToTransform) { + return nonNull(transformerFunction) ? transformerFunction.apply(objectToTransform) : transformerSupplier.get(); + } } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 91041d87c..5a2284283 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -22,7 +22,6 @@ import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import java.util.Map; -import java.util.function.Function; import com.hotels.beans.cache.CacheManager; import com.hotels.beans.model.FieldMapping; @@ -106,11 +105,10 @@ public final void resetFieldsMapping() { * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") public final Transformer withFieldTransformer(final FieldTransformer... fieldTransformer) { - Map> fieldsTransformers = settings.getFieldsTransformers(); + Map fieldsTransformers = settings.getFieldsTransformers(); for (FieldTransformer transformer : fieldTransformer) { - fieldsTransformers.put(transformer.getDestFieldName(), transformer.getTransformerFunction()); + fieldsTransformers.put(transformer.getDestFieldName(), transformer); } return this; } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index ce15a8fd0..87f473287 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -39,12 +39,12 @@ import java.lang.reflect.Parameter; import java.util.List; import java.util.Optional; -import java.util.function.Function; import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.constant.ClassType; import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.error.MissingFieldException; +import com.hotels.beans.model.FieldTransformer; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. @@ -305,6 +305,7 @@ private Object getFieldValue(final T sourceObj, final Class targetClas * @return the field value * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ + @SuppressWarnings("unchecked") private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); Class fieldType = field.getType(); @@ -312,7 +313,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN return defaultValue(fieldType); } boolean primitiveType = classUtils.isPrimitiveType(fieldType); - Function transformerFunction = getTransformerFunction(field, fieldBreadcrumb); + FieldTransformer transformerFunction = getTransformerFunction(field, fieldBreadcrumb); boolean isTransformerFunctionDefined = nonNull(transformerFunction); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, isTransformerFunctionDefined); if (nonNull(fieldValue)) { @@ -327,7 +328,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN fieldValue = defaultValue(fieldType); // assign the default value } if (isTransformerFunctionDefined) { - fieldValue = transformerFunction.apply(fieldValue); + fieldValue = transformerFunction.getTransformedObject(fieldValue); } return fieldValue; } @@ -375,7 +376,7 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie * @param breadcrumb The full field path on which the transformation should be applied. * @return the transformer function. */ - private Function getTransformerFunction(final Field field, final String breadcrumb) { + private FieldTransformer getTransformerFunction(final Field field, final String breadcrumb) { return settings.getFieldsTransformers().get(settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 8fd336884..bbb2af039 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -21,7 +21,9 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +import java.util.function.Supplier; +import com.hotels.beans.model.FieldTransformer; import lombok.Getter; import lombok.Setter; @@ -47,7 +49,17 @@ final class TransformerSettings { * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); * } */ - private final Map> fieldsTransformers = new ConcurrentHashMap<>(); + private final Map fieldsTransformers = new ConcurrentHashMap<>(); + +// /** +// * Contains the supplier functions to be applied on a given fields. +// * This features allows to apply transformation on the destination object value. +// * e.g. The following instructions allows to negate the destination value of the identifier field. +// * {@code +// * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::ZERO); +// * } +// */ +// private final Map> fieldsSuppliers = new ConcurrentHashMap<>(); /** * Contains the list of fields that don't need to be transformed. diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 15db8ce35..640b9d6b1 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -457,7 +457,7 @@ public void testTransformationReturnsAMeaningfulException() { public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { //GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); - FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); + FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, () -> AGE); //WHEN underTest.withFieldTransformer(ageFieldTransformer); From 1688ff96a8cd9726f86f3b9495ebe8dadbbf174e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 14:11:49 +0200 Subject: [PATCH 0575/1786] fixed checkstyle issues --- CHANGELOG-JDK8.md | 4 ++++ CHANGELOG.md | 4 ++++ README.md | 2 +- .../com/hotels/beans/model/FieldTransformer.java | 4 ++-- .../beans/transformer/TransformerSettings.java | 13 +------------ docs/site/markdown/transformer/samples.md | 2 +- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 1c33f1b36..9dd80903c 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.1.20] TBD +#### Added +* Added possibility to define transformer function without arguments if not needed (see: [Issue X](https://github.com/HotelsDotCom/bull/issues/X)). + ### [1.1.19] 2019.05.23 #### Changes * Made the project multi module diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ed9ba70..23a031d9c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.4.2] TBD +#### Added +* Added possibility to define transformer function without arguments if not needed (see: [Issue X](https://github.com/HotelsDotCom/bull/issues/X)). + ### [1.4.1.1] 2019.05.24 #### Changes * Made the project multi module diff --git a/README.md b/README.md index c3e082b79..f78919619 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,7 @@ public class FromBean { public class ToBean ~~~ And one line code as: ~~~Java -FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); +FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", () -> "sampleVal"); ToBean toBean = beanUtils.getTransformer() .withFieldTransformer(notExistingFieldTransformer) .transform(fromBean, ToBean.class); diff --git a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java index 98f2c6c93..bf3a6e397 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java @@ -44,7 +44,7 @@ public class FieldTransformer { private Function transformerFunction; /** - * The field transformer supplier + * The field transformer supplier. */ private Supplier transformerSupplier; @@ -73,7 +73,7 @@ public FieldTransformer(final String destFieldName, final Supplier transforme * @param objectToTransform the object to transform * @return the transformed object */ - public K getTransformedObject(final T objectToTransform) { + public final K getTransformedObject(final T objectToTransform) { return nonNull(transformerFunction) ? transformerFunction.apply(objectToTransform) : transformerSupplier.get(); } } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index bbb2af039..31ba4b9ff 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -20,10 +20,9 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.function.Supplier; import com.hotels.beans.model.FieldTransformer; + import lombok.Getter; import lombok.Setter; @@ -51,16 +50,6 @@ final class TransformerSettings { */ private final Map fieldsTransformers = new ConcurrentHashMap<>(); -// /** -// * Contains the supplier functions to be applied on a given fields. -// * This features allows to apply transformation on the destination object value. -// * e.g. The following instructions allows to negate the destination value of the identifier field. -// * {@code -// * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::ZERO); -// * } -// */ -// private final Map> fieldsSuppliers = new ConcurrentHashMap<>(); - /** * Contains the list of fields that don't need to be transformed. */ diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index a632d92f0..7def1ba76 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -196,7 +196,7 @@ public class FromBean { public class ToBean ~~~ And one line code as: ~~~Java -FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", val -> "sampleVal"); +FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", () -> "sampleVal"); ToBean toBean = beanUtils.getTransformer() .withFieldTransformer(notExistingFieldTransformer) .transform(fromBean, ToBean.class); From fd4cce78595c73812ae7835b200d8879bb348b43 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 14:45:06 +0200 Subject: [PATCH 0576/1786] Fixed checkstyle issues --- bean-utils-library/pom.xml | 2 +- .../hotels/beans/model/FieldTransformer.java | 26 ++++++++++--------- pom.xml | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index d8786b1e2..95b4642c6 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - BULL - Core + BULL - Bean Utils Light Library bean-utils-library jar diff --git a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java index bf3a6e397..07f6a43bd 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java @@ -18,9 +18,12 @@ import static java.util.Objects.nonNull; +import static lombok.AccessLevel.PRIVATE; + import java.util.function.Function; import java.util.function.Supplier; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; @@ -30,6 +33,7 @@ * @param input field type. * @param field value on with apply the function. */ +@AllArgsConstructor(access = PRIVATE) @Getter @ToString public class FieldTransformer { @@ -41,31 +45,29 @@ public class FieldTransformer { /** * The field transformer function. */ - private Function transformerFunction; + private final Function transformerFunction; /** * The field transformer supplier. */ - private Supplier transformerSupplier; + private final Supplier transformerSupplier; /** * Creates a field transformer with a lambda function to be applied on the field. - * @param destFieldName the field name in the destination object. - * @param transformerFunction the transformer function to apply on field + * @param destinationFieldName the field name in the destination object. + * @param fieldTransformerFunction the transformer function to apply on field */ - public FieldTransformer(final String destFieldName, final Function transformerFunction) { - this.destFieldName = destFieldName; - this.transformerFunction = transformerFunction; + public FieldTransformer(final String destinationFieldName, final Function fieldTransformerFunction) { + this(destinationFieldName, fieldTransformerFunction, null); } /** * Creates a field transformer with a field supplier function to be applied on the field. - * @param destFieldName the field name in the destination object. - * @param transformerSupplier the transformer supplier to apply on field + * @param destinationFieldName the field name in the destination object. + * @param fieldTransformerSupplier the transformer supplier to apply on field */ - public FieldTransformer(final String destFieldName, final Supplier transformerSupplier) { - this.destFieldName = destFieldName; - this.transformerSupplier = transformerSupplier; + public FieldTransformer(final String destinationFieldName, final Supplier fieldTransformerSupplier) { + this(destinationFieldName, null, fieldTransformerSupplier); } /** diff --git a/pom.xml b/pom.xml index f6290511c..4db74acde 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - BULL - Bean Utils Light Library + BULL - Bean Utils Light Library Parent com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull From 6f95f73a33a2d1975cf98d6cd705b72dcf670b83 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 14:59:01 +0200 Subject: [PATCH 0577/1786] linked issue --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- .../beans/transformer/MutableObjectTransformationTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 9dd80903c..a9be75a44 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.1.20] TBD #### Added -* Added possibility to define transformer function without arguments if not needed (see: [Issue X](https://github.com/HotelsDotCom/bull/issues/X)). +* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/HotelsDotCom/bull/issues/62)). ### [1.1.19] 2019.05.23 #### Changes diff --git a/CHANGELOG.md b/CHANGELOG.md index 23a031d9c..56f963322 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.4.2] TBD #### Added -* Added possibility to define transformer function without arguments if not needed (see: [Issue X](https://github.com/HotelsDotCom/bull/issues/X)). +* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/HotelsDotCom/bull/issues/62)). ### [1.4.1.1] 2019.05.24 #### Changes diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index cfb40cfc6..1c7fd854c 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -180,7 +180,7 @@ public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { //GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); - FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); + FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, () -> AGE); //WHEN underTest.withFieldTransformer(ageFieldTransformer); From efd2e89bef10d6db68507ce3c5da1979153abf65 Mon Sep 17 00:00:00 2001 From: Matteo Moci <11626+mox601@users.noreply.github.com> Date: Fri, 24 May 2019 16:37:09 +0200 Subject: [PATCH 0578/1786] changed logic to pass original values to FieldTransformer, added test close #64 --- .../beans/transformer/TransformerImpl.java | 9 +++-- .../java/com/hotels/beans/BeanUtilsTest.java | 35 ++++++++++++++++- .../sample/FromFooSimpleBooleanField.java | 38 +++++++++++++++++++ .../ImmutableToFooSimpleBoolean.java | 33 ++++++++++++++++ 4 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index ce15a8fd0..e779fcef5 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -315,21 +315,22 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN Function transformerFunction = getTransformerFunction(field, fieldBreadcrumb); boolean isTransformerFunctionDefined = nonNull(transformerFunction); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, isTransformerFunctionDefined); + Object outputValue = fieldValue; if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function // defined it recursively evaluate the value boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(fieldType); if (!isTransformerFunctionDefined && (notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass()))) { - fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); + outputValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); } } else if (primitiveType) { - fieldValue = defaultValue(fieldType); // assign the default value + outputValue = defaultValue(fieldType); // assign the default value } if (isTransformerFunctionDefined) { - fieldValue = transformerFunction.apply(fieldValue); + outputValue = transformerFunction.apply(fieldValue); } - return fieldValue; + return outputValue; } /** diff --git a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java index 39f2636ed..cf1c02580 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -16,12 +16,12 @@ package com.hotels.beans; +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; - import java.math.BigInteger; import java.util.Arrays; import java.util.List; @@ -35,10 +35,13 @@ import org.testng.annotations.Test; import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.FromFooSimpleBooleanField; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooSimple; +import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; import com.hotels.beans.transformer.Transformer; /** @@ -109,6 +112,26 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip .forEach(i -> assertThat(actual.get(i), sameBeanAs(fromFooSimpleList.get(i)))); } + /** + * Test that the transformer function is applied earlier than the default value + */ + @Test + public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { + //GIVEN + BeanUtils beanUtils = new BeanUtils(); + FromFooSimpleBooleanField fromFooSimpleNullFields = createFromFooSimpleNullFields(); + FieldTransformer nullToTrue = + new FieldTransformer<>("work", aBoolean -> aBoolean == null || aBoolean); + + //WHEN + ImmutableToFooSimpleBoolean transformed = beanUtils.getTransformer() + .withFieldTransformer(nullToTrue) + .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); + + //THEN + assertTrue(transformed.getWork()); + } + /** * Creates the parameters to be used for testing the default transformation operations. * @return parameters to be used for testing the default transformation operations. @@ -157,4 +180,12 @@ public void testValidateThrowsExceptionIfTheGivenBeanIsInvalid() { private FromFooSimple createFromFooSimple() { return new FromFooSimple(NAME, ID); } + + /** + * Creates a {@link FromFooSimpleBooleanField} instance with null field. + * @return the {@link FromFooSimpleBooleanField} instance. + */ + private FromFooSimpleBooleanField createFromFooSimpleNullFields() { + return new FromFooSimpleBooleanField(); + } } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java new file mode 100644 index 000000000..c86991211 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Sample immutable object with a {@link Boolean} field. + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class FromFooSimpleBooleanField { + public Boolean work; + + @Override + public String toString() { + return "FromFooSimpleBooleanField"; + } +} diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java new file mode 100644 index 000000000..20a2417f9 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.hotels.beans.sample.immutable; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Sample immutable object. + */ +@AllArgsConstructor +@Getter +public class ImmutableToFooSimpleBoolean { + private final Boolean work; + + @Override + public String toString() { + return "ImmutableToFooSimpleBoolean"; + } +} From b0fe599af58ca236aac6ff47ff3886479b624da2 Mon Sep 17 00:00:00 2001 From: Matteo Moci <11626+mox601@users.noreply.github.com> Date: Fri, 24 May 2019 16:54:06 +0200 Subject: [PATCH 0579/1786] code style --- .../src/test/java/com/hotels/beans/BeanUtilsTest.java | 3 ++- .../beans/sample/immutable/ImmutableToFooSimpleBoolean.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java index cf1c02580..4b44f6694 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -16,12 +16,13 @@ package com.hotels.beans; -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + import java.math.BigInteger; import java.util.Arrays; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java index 20a2417f9..29790df99 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.sample.immutable; import lombok.AllArgsConstructor; From 3699bcc34e5efad2437b3fbcd6c9e77bc9fb195c Mon Sep 17 00:00:00 2001 From: Matteo Moci <11626+mox601@users.noreply.github.com> Date: Fri, 24 May 2019 16:58:08 +0200 Subject: [PATCH 0580/1786] updated CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ed9ba70..9ec8ccfe4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.4.1.2] 2019.05.24 +#### Changes +* Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). + ### [1.4.1.1] 2019.05.24 #### Changes * Made the project multi module From 0da799bcb7f3bcbf190621dfb2e556724567b7b1 Mon Sep 17 00:00:00 2001 From: Matteo Moci <11626+mox601@users.noreply.github.com> Date: Fri, 24 May 2019 17:09:16 +0200 Subject: [PATCH 0581/1786] changed version to major --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ec8ccfe4..73ab70a79 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.4.1.2] 2019.05.24 +### [1.4.2] 2019.05.24 #### Changes * Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). From b3ef83955d306bbd3f14863f0ef143e12612f653 Mon Sep 17 00:00:00 2001 From: Matteo Moci <11626+mox601@users.noreply.github.com> Date: Fri, 24 May 2019 17:09:16 +0200 Subject: [PATCH 0582/1786] changed version to 1.4.2 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ec8ccfe4..73ab70a79 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.4.1.2] 2019.05.24 +### [1.4.2] 2019.05.24 #### Changes * Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). From 1cb60414aa50b6857fd765fbc7c6409dd2c47a11 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 17:10:27 +0200 Subject: [PATCH 0583/1786] Added logback configuration --- .../config/logging/logback-appenders.xml | 30 ++++++++++++++++ .../config/logging/logback-properties.xml | 5 +++ .../src/test/resources/logback-test.xml | 36 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 bull-common/src/test/resources/config/logging/logback-appenders.xml create mode 100644 bull-common/src/test/resources/config/logging/logback-properties.xml create mode 100644 bull-common/src/test/resources/logback-test.xml diff --git a/bull-common/src/test/resources/config/logging/logback-appenders.xml b/bull-common/src/test/resources/config/logging/logback-appenders.xml new file mode 100644 index 000000000..3bfd17005 --- /dev/null +++ b/bull-common/src/test/resources/config/logging/logback-appenders.xml @@ -0,0 +1,30 @@ + + + + + + + + + ${LOG_PATTERN} + + + + + + ${ROOT_LOG_DIR}/bean-utils-library.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip + + 30 + + 5MB + + + + \ No newline at end of file diff --git a/bull-common/src/test/resources/config/logging/logback-properties.xml b/bull-common/src/test/resources/config/logging/logback-properties.xml new file mode 100644 index 000000000..934b4e88b --- /dev/null +++ b/bull-common/src/test/resources/config/logging/logback-properties.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/bull-common/src/test/resources/logback-test.xml b/bull-common/src/test/resources/logback-test.xml new file mode 100644 index 000000000..4da7aad36 --- /dev/null +++ b/bull-common/src/test/resources/logback-test.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From d9a512046e9c65c259bdb39a2133a038fffb13a7 Mon Sep 17 00:00:00 2001 From: Matteo Moci <11626+mox601@users.noreply.github.com> Date: Fri, 24 May 2019 17:33:38 +0200 Subject: [PATCH 0584/1786] moved test --- .../java/com/hotels/beans/BeanUtilsTest.java | 31 ------------------- .../ImmutableObjectTransformationTest.java | 23 ++++++++++++++ 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java index 4b44f6694..f9e5b3e50 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -18,7 +18,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; @@ -36,13 +35,10 @@ import org.testng.annotations.Test; import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSimpleBooleanField; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooSimple; -import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; import com.hotels.beans.transformer.Transformer; /** @@ -113,26 +109,6 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip .forEach(i -> assertThat(actual.get(i), sameBeanAs(fromFooSimpleList.get(i)))); } - /** - * Test that the transformer function is applied earlier than the default value - */ - @Test - public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { - //GIVEN - BeanUtils beanUtils = new BeanUtils(); - FromFooSimpleBooleanField fromFooSimpleNullFields = createFromFooSimpleNullFields(); - FieldTransformer nullToTrue = - new FieldTransformer<>("work", aBoolean -> aBoolean == null || aBoolean); - - //WHEN - ImmutableToFooSimpleBoolean transformed = beanUtils.getTransformer() - .withFieldTransformer(nullToTrue) - .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); - - //THEN - assertTrue(transformed.getWork()); - } - /** * Creates the parameters to be used for testing the default transformation operations. * @return parameters to be used for testing the default transformation operations. @@ -182,11 +158,4 @@ private FromFooSimple createFromFooSimple() { return new FromFooSimple(NAME, ID); } - /** - * Creates a {@link FromFooSimpleBooleanField} instance with null field. - * @return the {@link FromFooSimpleBooleanField} instance. - */ - private FromFooSimpleBooleanField createFromFooSimpleNullFields() { - return new FromFooSimpleBooleanField(); - } } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 15db8ce35..516185b30 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -53,6 +54,7 @@ import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooAdvFields; import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.FromFooSimpleBooleanField; import com.hotels.beans.sample.immutable.ImmutableFlatToFoo; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; @@ -63,6 +65,7 @@ import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; import com.hotels.beans.sample.immutable.ImmutableToFooSimple; +import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; import com.hotels.beans.utils.ReflectionUtils; @@ -485,6 +488,26 @@ public void testFieldTransformationSkipWorksProperly() { underTest.resetFieldsTransformationSkip(); } + /** + * Test that the transformer function is applied earlier than the default value + */ + @Test + public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { + //GIVEN + BeanUtils beanUtils = new BeanUtils(); + FromFooSimpleBooleanField fromFooSimpleNullFields = new FromFooSimpleBooleanField(); + FieldTransformer nullToTrue = + new FieldTransformer<>("work", aBoolean -> aBoolean == null || aBoolean); + + //WHEN + ImmutableToFooSimpleBoolean transformed = beanUtils.getTransformer() + .withFieldTransformer(nullToTrue) + .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); + + //THEN + assertTrue(transformed.getWork()); + } + /** * Initializes the mocks required for testing method: {@code getDestFieldName}. * @param declaringClassName the declaring class name From 577c7a76cf34206dffe50f9b1873d7bd33236bd3 Mon Sep 17 00:00:00 2001 From: Matteo Moci <11626+mox601@users.noreply.github.com> Date: Fri, 24 May 2019 17:39:51 +0200 Subject: [PATCH 0585/1786] taken code from fborriello --- .../hotels/beans/transformer/TransformerImpl.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index e779fcef5..8a613ca92 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -315,22 +315,21 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN Function transformerFunction = getTransformerFunction(field, fieldBreadcrumb); boolean isTransformerFunctionDefined = nonNull(transformerFunction); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, isTransformerFunctionDefined); - Object outputValue = fieldValue; if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function // defined it recursively evaluate the value boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(fieldType); if (!isTransformerFunctionDefined - && (notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass()))) { - outputValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); + && (notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass()))) { + fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); } - } else if (primitiveType) { - outputValue = defaultValue(fieldType); // assign the default value + } else if (!isTransformerFunctionDefined && primitiveType) { + fieldValue = defaultValue(fieldType); // assign the default value } if (isTransformerFunctionDefined) { - outputValue = transformerFunction.apply(fieldValue); + fieldValue = transformerFunction.apply(fieldValue); } - return outputValue; + return fieldValue; } /** From 56bad595c5d637de3160179687a3d9a4a583fe15 Mon Sep 17 00:00:00 2001 From: Matteo Moci <11626+mox601@users.noreply.github.com> Date: Fri, 24 May 2019 17:41:37 +0200 Subject: [PATCH 0586/1786] renamed variable for code style --- .../beans/transformer/ImmutableObjectTransformationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 516185b30..a847e2c69 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -500,12 +500,12 @@ public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { new FieldTransformer<>("work", aBoolean -> aBoolean == null || aBoolean); //WHEN - ImmutableToFooSimpleBoolean transformed = beanUtils.getTransformer() + ImmutableToFooSimpleBoolean actual = beanUtils.getTransformer() .withFieldTransformer(nullToTrue) .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); //THEN - assertTrue(transformed.getWork()); + assertTrue(actual.getWork()); } /** From 93aa44619dcb6dd93f1788840495f2d639bf0d68 Mon Sep 17 00:00:00 2001 From: Matteo Moci <11626+mox601@users.noreply.github.com> Date: Fri, 24 May 2019 17:43:08 +0200 Subject: [PATCH 0587/1786] using common instance and resetting it --- .../beans/transformer/ImmutableObjectTransformationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index a847e2c69..c183909b1 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -494,18 +494,18 @@ public void testFieldTransformationSkipWorksProperly() { @Test public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { //GIVEN - BeanUtils beanUtils = new BeanUtils(); FromFooSimpleBooleanField fromFooSimpleNullFields = new FromFooSimpleBooleanField(); FieldTransformer nullToTrue = new FieldTransformer<>("work", aBoolean -> aBoolean == null || aBoolean); //WHEN - ImmutableToFooSimpleBoolean actual = beanUtils.getTransformer() + ImmutableToFooSimpleBoolean actual = underTest .withFieldTransformer(nullToTrue) .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); //THEN assertTrue(actual.getWork()); + underTest.resetFieldsTransformer(); } /** From b657d081da1f9166e008561a88747c5d84707198 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 18:27:20 +0200 Subject: [PATCH 0588/1786] minor: added missing dot --- .../beans/transformer/ImmutableObjectTransformationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index a5bfbfa94..d0154bacb 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -489,7 +489,7 @@ public void testFieldTransformationSkipWorksProperly() { } /** - * Test that the transformer function is applied earlier than the default value + * Test that the transformer function is applied earlier than the default value. */ @Test public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { From e31b7b73fa5c4281efac685159191b5b74127290 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 18:42:04 +0200 Subject: [PATCH 0589/1786] [maven-release-plugin] prepare release 1.4.2 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 95b4642c6..650ed27e8 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2-SNAPSHOT + 1.4.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e5ed9a7ca..b41f2481c 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2-SNAPSHOT + 1.4.2 diff --git a/pom.xml b/pom.xml index 4db74acde..b33132693 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.2-SNAPSHOT + 1.4.2 pom 2019 @@ -65,7 +65,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.2 From 3c82b87117badb3bcd1b7215bd5b07a095b16ad8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 18:42:18 +0200 Subject: [PATCH 0590/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 650ed27e8..1b83dfaf3 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2 + 1.4.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index b41f2481c..0db3c18e9 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2 + 1.4.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index b33132693..b0d04c470 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.2 + 1.4.3-SNAPSHOT pom 2019 @@ -65,7 +65,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.2 + HEAD From 45c2a13cac9b4c65eee2d12ec87789b2600b563d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 May 2019 18:52:42 +0200 Subject: [PATCH 0591/1786] fixed pom dependency --- bull-converter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 0b7c77038..6107d43bc 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -11,7 +11,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2-SNAPSHOT + 1.4.3-SNAPSHOT From d6ed7a575da113760f24d7feb3a27cfaff6e2c1e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 08:23:57 +0200 Subject: [PATCH 0592/1786] Removed deploy skip plugin --- .travis.yml | 2 +- README.md | 2 +- bull-common/pom.xml | 7 ------- pom.xml | 13 ------------- 4 files changed, 2 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index bb8436abc..bea71022e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ jobs: before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate javadoc:aggregate-jar deploy: - provider: script script: config/travis/deploy.sh diff --git a/README.md b/README.md index f78919619..2e40ddebb 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou ## Start using [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) -[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bean-utils-library.svg)](http://www.javadoc.io/doc/com.hotels.beans/bean-utils-library) +[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bean-utils-library.svg)](https://hotelsdotcom.github.io/bull/apidocs/index.html) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE) diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 0db3c18e9..2da3e9755 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -52,13 +52,6 @@ - - org.apache.maven.plugins - maven-deploy-plugin - - true - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index b0d04c470..28c64d711 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,6 @@ ${jdk.version} 3.12.0 3.1.0 - 2.8.2 2.1.5.RELEASE 1.18.8 3.9 @@ -328,11 +327,6 @@ false - - org.apache.maven.plugins - maven-deploy-plugin - ${maven-deploy.plugin.version} - org.jacoco jacoco-maven-plugin @@ -511,13 +505,6 @@ - - org.apache.maven.plugins - maven-deploy-plugin - - true - - From 12597577bb3c0184038f0c00bf18ca0a08fb8a40 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 19:20:10 +0200 Subject: [PATCH 0593/1786] Modified build configuration in order to aggregate the javadoc of all modules --- .travis.yml | 3 ++- README.md | 2 +- pom.xml | 65 ++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index bea71022e..004c49188 100755 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,8 @@ jobs: before_script: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate javadoc:aggregate-jar + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate + - mvn install -DskipTests -Dmaven.test.skip=true -P prepare-doc deploy: - provider: script script: config/travis/deploy.sh diff --git a/README.md b/README.md index 2e40ddebb..f78919619 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou ## Start using [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) -[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bean-utils-library.svg)](https://hotelsdotcom.github.io/bull/apidocs/index.html) +[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bean-utils-library.svg)](http://www.javadoc.io/doc/com.hotels.beans/bean-utils-library) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE) diff --git a/pom.xml b/pom.xml index 28c64d711..c99c36bb4 100644 --- a/pom.xml +++ b/pom.xml @@ -235,6 +235,38 @@ + + prepare-doc + + true + false + true + true + true + + + + + maven-jar-plugin + + + + javadoc + ${project.parent.basedir}/target/site/apidocs + **/* + ${build.finalName} + + pack-javadoc + package + + jar + + + + + + + @@ -279,22 +311,6 @@ - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven.javadoc.plugin.version} - - ${javadoc.skip} - - - - attach-javadocs - - jar - - - - org.apache.maven.plugins maven-checkstyle-plugin @@ -505,6 +521,23 @@ + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven.javadoc.plugin.version} + + ${javadoc.skip} + + + + attach-javadocs + prepare-package + + jar + + + + From 538d8a0841865f91860a3d0083056ee1c89ecad4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 19:39:52 +0200 Subject: [PATCH 0594/1786] preparing a release for javadoc --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 1b83dfaf3..7e971bd06 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3-SNAPSHOT + 1.4.2.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 2da3e9755..1ff5927e3 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3-SNAPSHOT + 1.4.2.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index c99c36bb4..e2c034f0d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.3-SNAPSHOT + 1.4.2.1-SNAPSHOT pom 2019 From 6a898dc82064b7c9f3b2a134353b7ec9c23bf7be Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 19:41:28 +0200 Subject: [PATCH 0595/1786] [maven-release-plugin] prepare release 1.4.2.1 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 7e971bd06..734fb5b2a 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.1-SNAPSHOT + 1.4.2.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 1ff5927e3..8e9e7a977 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.1-SNAPSHOT + 1.4.2.1 diff --git a/pom.xml b/pom.xml index e2c034f0d..a6dbd3536 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.2.1-SNAPSHOT + 1.4.2.1 pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.2.1 From abfea3ceb1091e230bdcf9a59120ec469923094b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 19:41:35 +0200 Subject: [PATCH 0596/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 734fb5b2a..1b83dfaf3 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.1 + 1.4.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 8e9e7a977..2da3e9755 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.1 + 1.4.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index a6dbd3536..c99c36bb4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.2.1 + 1.4.3-SNAPSHOT pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.2.1 + HEAD From 0d7472b3db59e69f560327c9cf899bce0c806f1f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 20:01:06 +0200 Subject: [PATCH 0597/1786] fixedfixed deploy of javadoc too --- .travis.yml | 3 +-- config/travis/deploy.sh | 4 ++-- pom.xml | 21 +++++++-------------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 004c49188..78a3e9aaf 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - install: travis_retry mvn clean install + install: travis_retry mvn clean install -DskipTests -Dmaven.test.skip=true - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present @@ -42,7 +42,6 @@ jobs: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate - - mvn install -DskipTests -Dmaven.test.skip=true -P prepare-doc deploy: - provider: script script: config/travis/deploy.sh diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index d73d5bc16..437b9c6d4 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true -Dmaven.test.skip=true else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true -Dmaven.test.skip=true fi fi \ No newline at end of file diff --git a/pom.xml b/pom.xml index c99c36bb4..843860498 100644 --- a/pom.xml +++ b/pom.xml @@ -216,6 +216,13 @@ release + + true + false + true + true + true + @@ -232,20 +239,6 @@ - - - - - prepare-doc - - true - false - true - true - true - - - maven-jar-plugin From 6e16e5e077cb1321f95ead29fb9d40e4f5b113ce Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 20:02:32 +0200 Subject: [PATCH 0598/1786] preparing release with javadoc --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 1b83dfaf3..e330c7922 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3-SNAPSHOT + 1.4.2.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 2da3e9755..d2cd9121a 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3-SNAPSHOT + 1.4.2.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 843860498..3b983ccb2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.3-SNAPSHOT + 1.4.2.2-SNAPSHOT pom 2019 From 6cdcd6eda24f60c4948990c02357c2ad4d814240 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 20:03:23 +0200 Subject: [PATCH 0599/1786] [maven-release-plugin] prepare release 1.4.2.2 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index e330c7922..dc7530677 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.2-SNAPSHOT + 1.4.2.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index d2cd9121a..1a78ee54f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.2-SNAPSHOT + 1.4.2.2 diff --git a/pom.xml b/pom.xml index 3b983ccb2..47e417d91 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.2.2-SNAPSHOT + 1.4.2.2 pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.2.2 From a6da593aee30678cc9d1cc1c5f3186cbadc86a5f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 20:03:30 +0200 Subject: [PATCH 0600/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index dc7530677..1b83dfaf3 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.2 + 1.4.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 1a78ee54f..2da3e9755 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.2 + 1.4.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index 47e417d91..843860498 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.2.2 + 1.4.3-SNAPSHOT pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.2.2 + HEAD From d81398edb58459ffbae69ff079f400beeb3c8fdf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 20:10:58 +0200 Subject: [PATCH 0601/1786] fixed travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 78a3e9aaf..bb8436abc 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - install: travis_retry mvn clean install -DskipTests -Dmaven.test.skip=true + install: travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present From b2f6be0541e27edc45a967c856cb1f35ac7d5e6d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 20:13:07 +0200 Subject: [PATCH 0602/1786] preparing release with javadoc --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- config/travis/deploy.sh | 4 ++-- pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 1b83dfaf3..e330c7922 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3-SNAPSHOT + 1.4.2.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 2da3e9755..d2cd9121a 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3-SNAPSHOT + 1.4.2.2-SNAPSHOT diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 437b9c6d4..d73d5bc16 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true -Dmaven.test.skip=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true -Dmaven.test.skip=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true fi fi \ No newline at end of file diff --git a/pom.xml b/pom.xml index 843860498..3b983ccb2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.3-SNAPSHOT + 1.4.2.2-SNAPSHOT pom 2019 From 933ca9a4952e272e383fd33c435bb2795afb0a07 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 20:14:01 +0200 Subject: [PATCH 0603/1786] [maven-release-plugin] prepare release 1.4.2.2 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index e330c7922..dc7530677 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.2-SNAPSHOT + 1.4.2.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index d2cd9121a..1a78ee54f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.2-SNAPSHOT + 1.4.2.2 diff --git a/pom.xml b/pom.xml index 3b983ccb2..47e417d91 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.2.2-SNAPSHOT + 1.4.2.2 pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.2.2 From 2520f9dc86bd660230c951d69b1f69f4f05a6ea2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 20:14:10 +0200 Subject: [PATCH 0604/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index dc7530677..1b83dfaf3 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.2 + 1.4.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 1a78ee54f..2da3e9755 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.2.2 + 1.4.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index 47e417d91..843860498 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.2.2 + 1.4.3-SNAPSHOT pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.2.2 + HEAD From cee1795afbaadfe93d6cce61e32e7f706bdf7c71 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 21:31:50 +0200 Subject: [PATCH 0605/1786] skip tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bb8436abc..26abb04a7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - install: travis_retry mvn clean install + install: travis_retry mvn clean install -DskipTests - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present From 33bb18e39e92880356e6f22885d0612ae316a465 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 26 May 2019 22:50:41 +0200 Subject: [PATCH 0606/1786] created profile for packaging all javadoc modules into a single jar file --- config/travis/deploy.sh | 4 ++-- pom.xml | 40 ++++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index d73d5bc16..37a709ca5 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Pprepare-doc,release -DskipTests=true else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Pprepare-doc,release -DskipTests=true fi fi \ No newline at end of file diff --git a/pom.xml b/pom.xml index 843860498..f17d8a333 100644 --- a/pom.xml +++ b/pom.xml @@ -213,9 +213,9 @@ - + - release + prepare-doc true false @@ -225,20 +225,6 @@ - - org.apache.maven.plugins - maven-gpg-plugin - ${maven.gpg.plugin.version} - - - sign-artifacts - verify - - sign - - - - maven-jar-plugin @@ -260,6 +246,28 @@ + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven.gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + + + + + From d7b00d4f87384ba7e5902875795ecd469d07dd24 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 28 May 2019 09:39:07 +0200 Subject: [PATCH 0607/1786] Modified travis configuration in order to build the site including the javadoc --- .travis.yml | 2 +- bean-utils-library/pom.xml | 2 +- bull-converter/pom.xml | 12 ----------- config/travis/deploy.sh | 4 ++-- pom.xml | 43 ++++++++++++++++---------------------- 5 files changed, 22 insertions(+), 41 deletions(-) diff --git a/.travis.yml b/.travis.yml index 26abb04a7..f3952178c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dmaven.javadoc.skip=true -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true -B + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true javadoc:aggregate -B deploy: provider: pages local-dir: target/site diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index ac0f52981..ad359aec5 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - BULL - Bean Utils Light Library + BULL - Core bean-utils-library jar diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 6107d43bc..22df85407 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -21,16 +21,4 @@ ${project.version} - - - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - \ No newline at end of file diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 37a709ca5..d73d5bc16 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Pprepare-doc,release -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Pprepare-doc,release -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true fi fi \ No newline at end of file diff --git a/pom.xml b/pom.xml index 92be00f7b..3068c3726 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - BULL - Bean Utils Light Library Parent + BULL - Bean Utils Light Library com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull @@ -214,9 +214,9 @@ - + - prepare-doc + release true false @@ -226,6 +226,21 @@ + + org.apache.maven.plugins + maven-gpg-plugin + ${maven.gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + + + maven-jar-plugin @@ -247,28 +262,6 @@ - - - release - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven.gpg.plugin.version} - - - sign-artifacts - verify - - sign - - - - - - - From d96db6b94708964aa0ae3421d4c55140bd73216f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 28 May 2019 11:24:50 +0200 Subject: [PATCH 0608/1786] Improved javadoc --- .../com/hotels/beans/validator/Validator.java | 2 +- bull-converter/pom.xml | 24 --- .../beans/conversion/ConversionAnalyzer.java | 123 --------------- .../beans/conversion/ConversionProcessor.java | 126 --------------- .../ConversionProcessorFactory.java | 73 --------- .../conversion/StringConversionProcessor.java | 144 ------------------ .../hotels/beans/conversion/package-info.java | 20 --- .../org.mockito.plugins.MockMaker | 1 - pom.xml | 1 - 9 files changed, 1 insertion(+), 513 deletions(-) delete mode 100644 bull-converter/pom.xml delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java delete mode 100644 bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bull-common/src/main/java/com/hotels/beans/validator/Validator.java b/bull-common/src/main/java/com/hotels/beans/validator/Validator.java index 0726b162a..af7442ec0 100644 --- a/bull-common/src/main/java/com/hotels/beans/validator/Validator.java +++ b/bull-common/src/main/java/com/hotels/beans/validator/Validator.java @@ -54,7 +54,7 @@ public interface Validator { /** * Validate that the specified argument is not {@code null}; - * otherwise throws an {@link IllegalArgumentException} with the specified message. + * otherwise throws an {@link IllegalArgumentException}. * @param object the object to check * @param the object type * @throws IllegalArgumentException if the object is {@code null} diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml deleted file mode 100644 index 22df85407..000000000 --- a/bull-converter/pom.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - 4.0.0 - BULL - Converter - bull-converter - jar - Provides the conversion related classes - - - com.hotels.beans - bean-utils-library-parent - 1.4.3-SNAPSHOT - - - - - com.hotels.beans - bull-common - ${project.version} - - - \ No newline at end of file diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java deleted file mode 100644 index a2da54a56..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion; - -import static java.util.Optional.empty; -import static java.util.Optional.of; - -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.conversion.ConversionProcessorFactory.getConversionProcessor; - -import java.util.Optional; -import java.util.function.Function; - -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.utils.ClassUtils; - -/** - * This class analyzes the two classes received in input, and returns the conversion processor to be used. - */ -public final class ConversionAnalyzer { - /** - * CacheManager instance {@link CacheManager}. - */ - private static final CacheManager CACHE_MANAGER = getCacheManager("conversionAnalyzer"); - - /** - * Class utils instance {@link ClassUtils}. - */ - private final ClassUtils classUtils; - - /** - * Default constructor. - */ - public ConversionAnalyzer() { - this.classUtils = new ClassUtils(); - } - - /** - * Analyzes Fields given as input and returns the conversion processor. - * @param sourceFieldType source field class - * @param destinationFieldType the destination field class - * @return an {@link Optional} containing the conversion function (if exists) - */ - @SuppressWarnings("unchecked") - public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { - final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional> conversionFunction = empty(); - if (destinationFieldType != sourceFieldType && classUtils.isPrimitiveType(sourceFieldType) && classUtils.isPrimitiveType(destinationFieldType)) { - conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); - } - CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); - return conversionFunction; - }); - } - - /** - * Returns the type transformer function for the given type. - * @param conversionProcessor the {@link ConversionProcessor} for the given type - * @param sourceFieldType the source field class - * @return the conversion function - */ - @SuppressWarnings("unchecked") - private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { - final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional> conversionFunction; - if (sourceFieldType == String.class) { - conversionFunction = of(conversionProcessor.convertString()); - } else if (sourceFieldType == Byte.class) { - conversionFunction = of(conversionProcessor.convertByte()); - } else if (sourceFieldType == byte.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveByte()); - } else if (sourceFieldType == Short.class) { - conversionFunction = of(conversionProcessor.convertShort()); - } else if (sourceFieldType == short.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveShort()); - } else if (sourceFieldType == Integer.class) { - conversionFunction = of(conversionProcessor.convertInteger()); - } else if (sourceFieldType == int.class) { - conversionFunction = of(conversionProcessor.convertInt()); - } else if (sourceFieldType == Long.class) { - conversionFunction = of(conversionProcessor.convertLong()); - } else if (sourceFieldType == long.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveLong()); - } else if (sourceFieldType == Float.class) { - conversionFunction = of(conversionProcessor.convertFloat()); - } else if (sourceFieldType == float.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveFloat()); - } else if (sourceFieldType == Double.class) { - conversionFunction = of(conversionProcessor.convertDouble()); - } else if (sourceFieldType == double.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveDouble()); - } else if (sourceFieldType == Character.class) { - conversionFunction = of(conversionProcessor.convertCharacter()); - } else if (sourceFieldType == char.class) { - conversionFunction = of(conversionProcessor.convertChar()); - } else if (sourceFieldType == Boolean.class) { - conversionFunction = of(conversionProcessor.convertBoolean()); - } else if (sourceFieldType == boolean.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveBoolean()); - } else { - conversionFunction = empty(); - } - CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); - return conversionFunction; - }); - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java deleted file mode 100644 index 26c270015..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion; - -import java.util.function.Function; - -/** - * Conversion methods for all primitive types. - */ -public interface ConversionProcessor { - /** - * Converts a byte type. - * @return the converted value - */ - Function convertPrimitiveByte(); - - /** - * Converts a {@link Byte} type. - * @return the converted value - */ - Function convertByte(); - - /** - * Converts a short type. - * @return the converted value - */ - Function convertPrimitiveShort(); - - /** - * Converts a {@link Short} type. - * @return the converted value - */ - Function convertShort(); - - /** - * Converts an int type. - * @return the converted value - */ - Function convertInt(); - - /** - * Converts an {@link Integer} type. - * @return the converted value - */ - Function convertInteger(); - - /** - * Converts a long type. - * @return the converted value - */ - Function convertPrimitiveLong(); - - /** - * Converts a {@link Long} type. - * @return the converted value - */ - Function convertLong(); - - /** - * Converts a float type. - * @return the converted value - */ - Function convertPrimitiveFloat(); - - /** - * Converts an {@link Float} type. - * @return the converted value - */ - Function convertFloat(); - - /** - * Converts a double type. - * @return the converted value - */ - Function convertPrimitiveDouble(); - - /** - * Converts a {@link Double} type. - * @return the converted value - */ - Function convertDouble(); - - /** - * Converts a char type. - * @return the converted value - */ - Function convertChar(); - - /** - * Converts a {@link Character} type. - * @return the converted value - */ - Function convertCharacter(); - - /** - * Converts a boolean type. - * @return the converted value - */ - Function convertPrimitiveBoolean(); - - /** - * Converts a {@link Boolean} type. - * @return the converted value - */ - Function convertBoolean(); - - /** - * Converts a {@link String} type. - * @return the converted value - */ - Function convertString(); -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java deleted file mode 100644 index 9affbb8b5..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion; - -import static lombok.AccessLevel.PRIVATE; - -import lombok.NoArgsConstructor; - -/** - * Creates a {@link ConversionProcessor} instance for the given class. - */ -@NoArgsConstructor(access = PRIVATE) -public final class ConversionProcessorFactory { - /** - * Returns a conversion processor for the given type. - * @param clazz the class for which the conversion processor has to be retrieved. - * @return a conversion processor for the given type - */ - public static ConversionProcessor getConversionProcessor(final Class clazz) { - ConversionProcessor conversionProcessor = null; - if (clazz == String.class) { - conversionProcessor = new StringConversionProcessor(); - } -// else if (clazz == Byte.class) { -// conversionProcessor = new ByteConversionProcessor(); -// } else if (clazz == byte.class) { -// conversionProcessor = new PrimitiveByteConversionProcessor(); -// } else if (clazz == Short.class) { -// conversionProcessor = new ShortConversionProcessor(); -// } else if (clazz == short.class) { -// conversionProcessor = new PrimitiveShortConversionProcessor(); -// } else if (clazz == Integer.class) { -// conversionProcessor = new IntegerConversionProcessor(); -// } else if (clazz == int.class) { -// conversionProcessor = new IntConversionProcessor(); -// } else if (clazz == Long.class) { -// conversionProcessor = new LongConversionProcessor(); -// } else if (clazz == long.class) { -// conversionProcessor = new PrimitiveLongConversionProcessor(); -// } else if (clazz == Float.class) { -// conversionProcessor = new FloatConversionProcessor(); -// } else if (clazz == float.class) { -// conversionProcessor = new PrimitiveFloatConversionProcessor(); -// } else if (clazz == Double.class) { -// conversionProcessor = new DoubleConversionProcessor(); -// } else if (clazz == double.class) { -// conversionProcessor = new PrimitiveDoubleConversionProcessor(); -// } else if (clazz == Character.class) { -// conversionProcessor = new CharacterConversionProcessor(); -// } else if (clazz == char.class) { -// conversionProcessor = new CharConversionProcessor(); -// } else if (clazz == Boolean.class) { -// conversionProcessor = new BooleanConversionProcessor(); -// } else if (clazz == boolean.class) { -// conversionProcessor = new PrimitiveBooleanConversionProcessor(); -// } - return conversionProcessor; - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java deleted file mode 100644 index 1f0711f06..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion; - -import java.util.function.Function; - -/** - * Provides all method for converting any primitive type to a String. - */ -public class StringConversionProcessor implements ConversionProcessor { - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveByte() { - return val -> Byte.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertByte() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveShort() { - return val -> Short.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertShort() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertInt() { - return val -> Integer.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertInteger() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveLong() { - return val -> Long.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertLong() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveFloat() { - return val -> Float.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertFloat() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveDouble() { - return val -> Double.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertDouble() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertChar() { - return val -> Character.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertCharacter() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertPrimitiveBoolean() { - return val -> Boolean.toString(val); - } - - /** - * {@inheritDoc} - */ - public final Function convertBoolean() { - return Object::toString; - } - - /** - * {@inheritDoc} - */ - public final Function convertString() { - return val -> val; - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java deleted file mode 100644 index eb89044b2..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Type conversion processor package. - */ - -package com.hotels.beans.conversion; diff --git a/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea..000000000 --- a/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3068c3726..b7d430cfa 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,6 @@ bean-utils-library bull-common - bull-converter From 013c40ee534959b980b3280a2fb5976f25c1c0f4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 28 May 2019 11:26:56 +0200 Subject: [PATCH 0609/1786] Removed not existing module --- bean-utils-library/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index ad359aec5..597dfe939 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -17,11 +17,6 @@ bull-common ${project.version} - - com.hotels.beans - bull-converter - ${project.version} - com.hotels.beans From 7efbda954593e54d1697542f07892fc3cd8cd782 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 28 May 2019 17:51:30 +0200 Subject: [PATCH 0610/1786] Integrated primitive type conversion into the transformation flow --- bean-utils-library/pom.xml | 5 + .../transformer/AbstractTransformer.java | 7 + .../beans/transformer/TransformerImpl.java | 38 ++++- bull-converter/pom.xml | 24 +++ .../beans/conversion/ConversionAnalyzer.java | 134 ++++++++++++++++ .../beans/conversion/ConversionProcessor.java | 126 +++++++++++++++ .../ConversionProcessorFactory.java | 73 +++++++++ .../conversion/StringConversionProcessor.java | 144 ++++++++++++++++++ .../hotels/beans/conversion/package-info.java | 20 +++ .../org.mockito.plugins.MockMaker | 1 + pom.xml | 1 + 11 files changed, 565 insertions(+), 8 deletions(-) create mode 100644 bull-converter/pom.xml create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java create mode 100644 bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 597dfe939..ad359aec5 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -17,6 +17,11 @@ bull-common ${project.version} + + com.hotels.beans + bull-converter + ${project.version} + com.hotels.beans diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 5a2284283..9dedaf65e 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -24,6 +24,7 @@ import java.util.Map; import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.conversion.ConversionAnalyzer; import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.utils.ClassUtils; @@ -61,6 +62,11 @@ abstract class AbstractTransformer implements Transformer { */ final Validator validator; + /** + * Conversion analyzer. It allows to automatically convert common field types. + */ + final ConversionAnalyzer conversionAnalyzer; + /** * Default constructor. */ @@ -69,6 +75,7 @@ abstract class AbstractTransformer implements Transformer { this.classUtils = new ClassUtils(); this.validator = new ValidatorImpl(); this.settings = new TransformerSettings(); + this.conversionAnalyzer = new ConversionAnalyzer(); this.cacheManager = getCacheManager("transformer"); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 321964bf0..635a90891 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -19,6 +19,7 @@ import static java.util.Arrays.stream; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; +import static java.util.Optional.of; import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; @@ -37,8 +38,10 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Parameter; +import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.function.Function; import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.constant.ClassType; @@ -305,7 +308,6 @@ private Object getFieldValue(final T sourceObj, final Class targetClas * @return the field value * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ - @SuppressWarnings("unchecked") private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); Class fieldType = field.getType(); @@ -313,8 +315,8 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN return defaultValue(fieldType); } boolean primitiveType = classUtils.isPrimitiveType(fieldType); - FieldTransformer transformerFunction = getTransformerFunction(field, fieldBreadcrumb); - boolean isTransformerFunctionDefined = nonNull(transformerFunction); + List transformerFunction = getTransformerFunction(sourceObj.getClass(), field, primitiveType, fieldBreadcrumb); + boolean isTransformerFunctionDefined = !transformerFunction.isEmpty(); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, isTransformerFunctionDefined); if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function @@ -327,10 +329,19 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN } else if (primitiveType && !isTransformerFunctionDefined) { fieldValue = defaultValue(fieldType); // assign the default value } + fieldValue = getTransformedValue(transformerFunction, isTransformerFunctionDefined, fieldValue); + return fieldValue; + } + + @SuppressWarnings("unchecked") + private Object getTransformedValue(final List transformerFunctions, final boolean isTransformerFunctionDefined, final Object fieldValue) { + Object transformedValue = fieldValue; if (isTransformerFunctionDefined) { - fieldValue = transformerFunction.getTransformedObject(fieldValue); + for (FieldTransformer transformerFunction : transformerFunctions) { + transformedValue = transformerFunction.getTransformedObject(transformedValue); + } } - return fieldValue; + return transformedValue; } /** @@ -371,13 +382,24 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie } /** - * Retrieves the transformer function. + * Retrieves the transformer function. If the field type is different and they are primitive + * a conversion function is automatically added. + * @param sourceObjectClass the source object class * @param field The field on which the transformation should be applied. + * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @param breadcrumb The full field path on which the transformation should be applied. * @return the transformer function. */ - private FieldTransformer getTransformerFunction(final Field field, final String breadcrumb) { - return settings.getFieldsTransformers().get(settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb); + private List getTransformerFunction(final Class sourceObjectClass, final Field field, + final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { + List fieldTransformers = new ArrayList<>(); + if (isDestinationFieldPrimitiveType) { + conversionAnalyzer.getConversionFunction(sourceObjectClass, field.getType(), isDestinationFieldPrimitiveType) + .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(field.getName(), conversionFunction))); + } + ofNullable(settings.getFieldsTransformers().get(settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb)) + .ifPresent(fieldTransformers::add); + return fieldTransformers; } /** diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml new file mode 100644 index 000000000..22df85407 --- /dev/null +++ b/bull-converter/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + BULL - Converter + bull-converter + jar + Provides the conversion related classes + + + com.hotels.beans + bean-utils-library-parent + 1.4.3-SNAPSHOT + + + + + com.hotels.beans + bull-common + ${project.version} + + + \ No newline at end of file diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java new file mode 100644 index 000000000..ef611a989 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java @@ -0,0 +1,134 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import static java.util.Optional.empty; +import static java.util.Optional.of; + +import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.conversion.ConversionProcessorFactory.getConversionProcessor; + +import java.util.Optional; +import java.util.function.Function; + +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.utils.ClassUtils; + +/** + * This class analyzes the two classes received in input, and returns the conversion processor to be used. + */ +public final class ConversionAnalyzer { + /** + * CacheManager instance {@link CacheManager}. + */ + private static final CacheManager CACHE_MANAGER = getCacheManager("conversionAnalyzer"); + + /** + * Class utils instance {@link ClassUtils}. + */ + private final ClassUtils classUtils; + + /** + * Default constructor. + */ + public ConversionAnalyzer() { + this.classUtils = new ClassUtils(); + } + + /** + * Analyzes Fields given as input and returns the conversion processor. + * @param sourceFieldType source field class + * @param destinationFieldType the destination field class + * @return an {@link Optional} containing the conversion function (if exists) + */ + public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { + return getConversionFunction(sourceFieldType, destinationFieldType, classUtils.isPrimitiveType(destinationFieldType)); + } + + /** + * Analyzes Fields given as input and returns the conversion processor. + * @param sourceFieldType source field class + * @param destinationFieldType the destination field class + * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not + * @return an {@link Optional} containing the conversion function (if exists) + */ + @SuppressWarnings("unchecked") + public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType, final boolean isDestinationFieldPrimitiveType) { + final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { + Optional> conversionFunction = empty(); + if (destinationFieldType != sourceFieldType && isDestinationFieldPrimitiveType && classUtils.isPrimitiveType(sourceFieldType)) { + conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); + } + CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); + return conversionFunction; + }); + } + + /** + * Returns the type transformer function for the given type. + * @param conversionProcessor the {@link ConversionProcessor} for the given type + * @param sourceFieldType the source field class + * @return the conversion function + */ + @SuppressWarnings("unchecked") + private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { + Optional> conversionFunction; + if (sourceFieldType == String.class) { + conversionFunction = of(conversionProcessor.convertString()); + } else if (sourceFieldType == Byte.class) { + conversionFunction = of(conversionProcessor.convertByte()); + } else if (sourceFieldType == byte.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveByte()); + } else if (sourceFieldType == Short.class) { + conversionFunction = of(conversionProcessor.convertShort()); + } else if (sourceFieldType == short.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveShort()); + } else if (sourceFieldType == Integer.class) { + conversionFunction = of(conversionProcessor.convertInteger()); + } else if (sourceFieldType == int.class) { + conversionFunction = of(conversionProcessor.convertInt()); + } else if (sourceFieldType == Long.class) { + conversionFunction = of(conversionProcessor.convertLong()); + } else if (sourceFieldType == long.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveLong()); + } else if (sourceFieldType == Float.class) { + conversionFunction = of(conversionProcessor.convertFloat()); + } else if (sourceFieldType == float.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveFloat()); + } else if (sourceFieldType == Double.class) { + conversionFunction = of(conversionProcessor.convertDouble()); + } else if (sourceFieldType == double.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveDouble()); + } else if (sourceFieldType == Character.class) { + conversionFunction = of(conversionProcessor.convertCharacter()); + } else if (sourceFieldType == char.class) { + conversionFunction = of(conversionProcessor.convertChar()); + } else if (sourceFieldType == Boolean.class) { + conversionFunction = of(conversionProcessor.convertBoolean()); + } else if (sourceFieldType == boolean.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveBoolean()); + } else { + conversionFunction = empty(); + } + CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); + return conversionFunction; + }); + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java new file mode 100644 index 000000000..26c270015 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java @@ -0,0 +1,126 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import java.util.function.Function; + +/** + * Conversion methods for all primitive types. + */ +public interface ConversionProcessor { + /** + * Converts a byte type. + * @return the converted value + */ + Function convertPrimitiveByte(); + + /** + * Converts a {@link Byte} type. + * @return the converted value + */ + Function convertByte(); + + /** + * Converts a short type. + * @return the converted value + */ + Function convertPrimitiveShort(); + + /** + * Converts a {@link Short} type. + * @return the converted value + */ + Function convertShort(); + + /** + * Converts an int type. + * @return the converted value + */ + Function convertInt(); + + /** + * Converts an {@link Integer} type. + * @return the converted value + */ + Function convertInteger(); + + /** + * Converts a long type. + * @return the converted value + */ + Function convertPrimitiveLong(); + + /** + * Converts a {@link Long} type. + * @return the converted value + */ + Function convertLong(); + + /** + * Converts a float type. + * @return the converted value + */ + Function convertPrimitiveFloat(); + + /** + * Converts an {@link Float} type. + * @return the converted value + */ + Function convertFloat(); + + /** + * Converts a double type. + * @return the converted value + */ + Function convertPrimitiveDouble(); + + /** + * Converts a {@link Double} type. + * @return the converted value + */ + Function convertDouble(); + + /** + * Converts a char type. + * @return the converted value + */ + Function convertChar(); + + /** + * Converts a {@link Character} type. + * @return the converted value + */ + Function convertCharacter(); + + /** + * Converts a boolean type. + * @return the converted value + */ + Function convertPrimitiveBoolean(); + + /** + * Converts a {@link Boolean} type. + * @return the converted value + */ + Function convertBoolean(); + + /** + * Converts a {@link String} type. + * @return the converted value + */ + Function convertString(); +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java new file mode 100644 index 000000000..9affbb8b5 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import static lombok.AccessLevel.PRIVATE; + +import lombok.NoArgsConstructor; + +/** + * Creates a {@link ConversionProcessor} instance for the given class. + */ +@NoArgsConstructor(access = PRIVATE) +public final class ConversionProcessorFactory { + /** + * Returns a conversion processor for the given type. + * @param clazz the class for which the conversion processor has to be retrieved. + * @return a conversion processor for the given type + */ + public static ConversionProcessor getConversionProcessor(final Class clazz) { + ConversionProcessor conversionProcessor = null; + if (clazz == String.class) { + conversionProcessor = new StringConversionProcessor(); + } +// else if (clazz == Byte.class) { +// conversionProcessor = new ByteConversionProcessor(); +// } else if (clazz == byte.class) { +// conversionProcessor = new PrimitiveByteConversionProcessor(); +// } else if (clazz == Short.class) { +// conversionProcessor = new ShortConversionProcessor(); +// } else if (clazz == short.class) { +// conversionProcessor = new PrimitiveShortConversionProcessor(); +// } else if (clazz == Integer.class) { +// conversionProcessor = new IntegerConversionProcessor(); +// } else if (clazz == int.class) { +// conversionProcessor = new IntConversionProcessor(); +// } else if (clazz == Long.class) { +// conversionProcessor = new LongConversionProcessor(); +// } else if (clazz == long.class) { +// conversionProcessor = new PrimitiveLongConversionProcessor(); +// } else if (clazz == Float.class) { +// conversionProcessor = new FloatConversionProcessor(); +// } else if (clazz == float.class) { +// conversionProcessor = new PrimitiveFloatConversionProcessor(); +// } else if (clazz == Double.class) { +// conversionProcessor = new DoubleConversionProcessor(); +// } else if (clazz == double.class) { +// conversionProcessor = new PrimitiveDoubleConversionProcessor(); +// } else if (clazz == Character.class) { +// conversionProcessor = new CharacterConversionProcessor(); +// } else if (clazz == char.class) { +// conversionProcessor = new CharConversionProcessor(); +// } else if (clazz == Boolean.class) { +// conversionProcessor = new BooleanConversionProcessor(); +// } else if (clazz == boolean.class) { +// conversionProcessor = new PrimitiveBooleanConversionProcessor(); +// } + return conversionProcessor; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java new file mode 100644 index 000000000..1f0711f06 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java @@ -0,0 +1,144 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import java.util.function.Function; + +/** + * Provides all method for converting any primitive type to a String. + */ +public class StringConversionProcessor implements ConversionProcessor { + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveByte() { + return val -> Byte.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertByte() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveShort() { + return val -> Short.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertShort() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertInt() { + return val -> Integer.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertInteger() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveLong() { + return val -> Long.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertLong() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveFloat() { + return val -> Float.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertFloat() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveDouble() { + return val -> Double.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertDouble() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertChar() { + return val -> Character.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertCharacter() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertPrimitiveBoolean() { + return val -> Boolean.toString(val); + } + + /** + * {@inheritDoc} + */ + public final Function convertBoolean() { + return Object::toString; + } + + /** + * {@inheritDoc} + */ + public final Function convertString() { + return val -> val; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java new file mode 100644 index 000000000..eb89044b2 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Type conversion processor package. + */ + +package com.hotels.beans.conversion; diff --git a/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/bull-converter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/pom.xml b/pom.xml index b7d430cfa..3068c3726 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,7 @@ bean-utils-library bull-common + bull-converter From e78c34f986270491cb83ba3c417f587dab56b1c7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 15:09:18 +0200 Subject: [PATCH 0611/1786] Added reference to Dzone and InfoQ articles --- README.md | 7 +++++++ docs/site/markdown/index.md | 14 ++++++++++++++ docs/site/markdown/transformer/samples.md | 2 +- docs/site/site.xml | 4 ++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f78919619..ac45ca335 100644 --- a/README.md +++ b/README.md @@ -629,6 +629,8 @@ Set> violatedConstraints = beanUtils.getValidator(). A detailed project documentation is available [here](https://hotelsdotcom.github.io/bull), including some samples for [testing the library](https://hotelsdotcom.github.io/bull/transformer/testing.html) inside your project. +An article that explains how it works, with suggestion and examples is available on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) + ## Credits Created by: [Fabio Borriello](https://github.com/fborriello) with the contribution of: [Patrizio Munzi](https://github.com/patriziomunzi), @@ -636,6 +638,11 @@ Created by: [Fabio Borriello](https://github.com/fborriello) with the contributi The application's logo has been designed by: Rob Light. +## Related articles + + - DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) + - InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) + ## Legal This project is available under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html). diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 2b3d1820d..51edd3af8 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -33,3 +33,17 @@ This BeanUtils library is a utility library for managing Bean objects. The libra * allows to set the default value for all objects not existing in the source object. * allows to skip transformation for a given set of fields. +- #### Bean Validation: + + Validates a Java Bean against a set of rules can be precious, especially when we need to be sure that the object data is compliant with our expectations. + The validation works with both the default `javax.constraints` provided by Java and the custom one + + ##### Features: + * Java Bean validation + * retrieve the violated constraints + +# Related articles + + - DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) + - InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) + diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 7def1ba76..cba5aa27e 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -410,4 +410,4 @@ beanUtils.getTransformer() .transform(fromBean2, toBean); ~~~ -More sample beans can be found in the test package: `com.hotels.beans.sample` \ No newline at end of file +More sample beans can be found in the test package: `com.hotels.beans.sample` or on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) \ No newline at end of file diff --git a/docs/site/site.xml b/docs/site/site.xml index 63d1dde45..5d04e9e05 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -39,6 +39,10 @@ + + + + \ No newline at end of file From 84a2b6cb4aaf383e1df49355247f3f210973fb6a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 15:16:52 +0200 Subject: [PATCH 0612/1786] Preparing release --- CHANGELOG.md | 5 +++++ docs/site/site.xml | 2 +- pom.xml | 32 ++++++++++++++++---------------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ccb0b00d..b5bae84d9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.4.3] 2019.05.29 +#### Changed +* Improved Javadoc +* Added reference to the articles published on **DZone** and **InfoQ** + ### [1.4.2] 2019.05.24 #### Added * Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/HotelsDotCom/bull/issues/62)). diff --git a/docs/site/site.xml b/docs/site/site.xml index 5d04e9e05..440af14d9 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -41,7 +41,7 @@ - + diff --git a/pom.xml b/pom.xml index b7d430cfa..424f6b7b1 100644 --- a/pom.xml +++ b/pom.xml @@ -468,22 +468,22 @@ - - com.github.github - site-maven-plugin - ${github.site.maven.plugin.version} - - Creating site for ${project.artifactId} ${project.version} - - - - - site - - site - - - + + + + + + + + + + + + + + + + From f5e2e9b0b6b2005c9bdd8eda3687f53ae7a05e4b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 15:25:31 +0200 Subject: [PATCH 0613/1786] preparing release --- .travis.yml | 2 +- pom.xml | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.travis.yml b/.travis.yml index f3952178c..a807ad983 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true javadoc:aggregate -B + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -B deploy: provider: pages local-dir: target/site diff --git a/pom.xml b/pom.xml index 424f6b7b1..b7d430cfa 100644 --- a/pom.xml +++ b/pom.xml @@ -468,22 +468,22 @@ - - - - - - - - - - - - - - - - + + com.github.github + site-maven-plugin + ${github.site.maven.plugin.version} + + Creating site for ${project.artifactId} ${project.version} + + + + + site + + site + + + From e5c38f812c7202ce282999c5dde8a3d3e0a7969f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 15:30:27 +0200 Subject: [PATCH 0614/1786] [maven-release-plugin] prepare release 1.4.3 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 597dfe939..8722d44a7 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3-SNAPSHOT + 1.4.3 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 2da3e9755..bc243ce75 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3-SNAPSHOT + 1.4.3 diff --git a/pom.xml b/pom.xml index b7d430cfa..9fe3c6c8d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.3-SNAPSHOT + 1.4.3 pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.3 From aa89b36c2cadfa98c93ae4b5c17091f755c27637 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 15:30:35 +0200 Subject: [PATCH 0615/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 8722d44a7..aeeb276f3 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3 + 1.4.4-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index bc243ce75..4a789bb44 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3 + 1.4.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index 9fe3c6c8d..9efa42b52 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.3 + 1.4.4-SNAPSHOT pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.3 + HEAD From 0cb5960cfeef90880b20e899a31513e8c6f17eb7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 15:42:05 +0200 Subject: [PATCH 0616/1786] Removed jacoco report from travis --- .travis.yml | 2 +- docs/site/site.xml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a807ad983..f3952178c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -B + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true javadoc:aggregate -B deploy: provider: pages local-dir: target/site diff --git a/docs/site/site.xml b/docs/site/site.xml index 440af14d9..ca83d967a 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -36,7 +36,6 @@ - From b28c47ce2c3120ead38d20d002d93767b7b4e384 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 15:53:49 +0200 Subject: [PATCH 0617/1786] Fixed bull-converter parent version --- bull-converter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 22df85407..4d6bfbd7d 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -11,7 +11,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.3-SNAPSHOT + 1.4.4-SNAPSHOT From 9701e9c5a88d8beaf22b3902bcf3ebc9a9dfceec Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 17:21:18 +0200 Subject: [PATCH 0618/1786] changed snapshot version --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index aeeb276f3..7a958f62e 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.4-SNAPSHOT + 1.4.5-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 4a789bb44..5bb6ccff4 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.4-SNAPSHOT + 1.4.5-SNAPSHOT diff --git a/pom.xml b/pom.xml index 9efa42b52..57711fbe7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.4-SNAPSHOT + 1.4.5-SNAPSHOT pom 2019 From 96f15b5302b75321611c7a4dddf56f330a6d2092 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 21:08:59 +0200 Subject: [PATCH 0619/1786] Modified site markup page --- docs/site/markdown/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 51edd3af8..027e2a0ef 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -42,8 +42,8 @@ This BeanUtils library is a utility library for managing Bean objects. The libra * Java Bean validation * retrieve the violated constraints -# Related articles +- #### Related articles - - DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) - - InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) + * DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) + * InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) From 9097b182db0925897143b7e4ceb3005d2e71e61e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 21:54:15 +0200 Subject: [PATCH 0620/1786] preparing new release as per the javadoc upload failure --- CHANGELOG.md | 2 +- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5bae84d9..b84152120 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.4.3] 2019.05.29 +### [1.4.4.1] 2019.05.29 #### Changed * Improved Javadoc * Added reference to the articles published on **DZone** and **InfoQ** diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 7a958f62e..abee7aed2 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.5-SNAPSHOT + 1.4.4.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 5bb6ccff4..25eab01a4 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.5-SNAPSHOT + 1.4.4.1 diff --git a/pom.xml b/pom.xml index 57711fbe7..d5b4f8f3b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.5-SNAPSHOT + 1.4.4.1 pom 2019 From e2d7175110a5e3df032e5ff7dfd567511d48afad Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 21:55:13 +0200 Subject: [PATCH 0621/1786] preparing javadoc release --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index abee7aed2..08b53d5db 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.4.1 + 1.4.4.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 25eab01a4..8d9865850 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.4.1 + 1.4.4.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index d5b4f8f3b..38d51dd98 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.4.1 + 1.4.4.1-SNAPSHOT pom 2019 From 28cbdbd5f1b02a47524f7ba5b2aa26cbbf03dda0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 21:58:31 +0200 Subject: [PATCH 0622/1786] [maven-release-plugin] prepare release 1.4.4.1 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 08b53d5db..abee7aed2 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.4.1-SNAPSHOT + 1.4.4.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 8d9865850..25eab01a4 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.4.1-SNAPSHOT + 1.4.4.1 diff --git a/pom.xml b/pom.xml index 38d51dd98..ce834b5b0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.4.1-SNAPSHOT + 1.4.4.1 pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.4.1 From 39ad15540bbbeccd6bd76ceaa6ce7ffefad0dfb1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 29 May 2019 21:58:39 +0200 Subject: [PATCH 0623/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index abee7aed2..7a958f62e 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.4.1 + 1.4.5-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 25eab01a4..5bb6ccff4 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.4.1 + 1.4.5-SNAPSHOT diff --git a/pom.xml b/pom.xml index ce834b5b0..57711fbe7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.4.1 + 1.4.5-SNAPSHOT pom 2019 @@ -64,7 +64,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.4.1 + HEAD From 15c61e048a490c3c9b7c8e027c9f1916d72f1eae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 3 Jun 2019 10:15:37 +0200 Subject: [PATCH 0624/1786] Modified site index page --- docs/site/markdown/index.md | 72 ++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 027e2a0ef..51c566f37 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -8,42 +8,42 @@ This BeanUtils library is a utility library for managing Bean objects. The library offers the following components: -- #### Bean Transformer: - - is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. - It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. - - ##### Features: - * support copy of immutable beans. - * support copy of mutable beans. - * support copy of hybrid beans (some fields private and some not). - * support copy of Java beans without getter and setter methods. - * support copy with Java primitive type. - * support copy with Java Collection type. e.g. `List => List` - * support copy with nested map fields. e.g. `Map>` - * support copy with array containing primitive types. e.g. `String[]` => `String[]` - * support copy with array type. e.g. `BeanA[]` => `BeanB[]` - * support copy with property name mapping. e.g. `int id => int userId` - * support copy with recursion copy. - * support validation through annotations. - * support copy of beans with different field's name. - * support lambda function field transformation. - * support copy of java bean built through Builder. - * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. - * allows to set the default value for all objects not existing in the source object. - * allows to skip transformation for a given set of fields. - -- #### Bean Validation: - - Validates a Java Bean against a set of rules can be precious, especially when we need to be sure that the object data is compliant with our expectations. - The validation works with both the default `javax.constraints` provided by Java and the custom one - - ##### Features: - * Java Bean validation - * retrieve the violated constraints +#### Bean Transformer: + +is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. +It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. + +##### Features: +* support copy of immutable beans. +* support copy of mutable beans. +* support copy of hybrid beans (some fields private and some not). +* support copy of Java beans without getter and setter methods. +* support copy with Java primitive type. +* support copy with Java Collection type. e.g. `List => List` +* support copy with nested map fields. e.g. `Map>` +* support copy with array containing primitive types. e.g. `String[]` => `String[]` +* support copy with array type. e.g. `BeanA[]` => `BeanB[]` +* support copy with property name mapping. e.g. `int id => int userId` +* support copy with recursion copy. +* support validation through annotations. +* support copy of beans with different field's name. +* support lambda function field transformation. +* support copy of java bean built through Builder. +* easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. +* allows to set the default value for all objects not existing in the source object. +* allows to skip transformation for a given set of fields. + +#### Bean Validation: + +Validates a Java Bean against a set of rules can be precious, especially when we need to be sure that the object data is compliant with our expectations. +The validation works with both the default `javax.constraints` provided by Java and the custom one + +##### Features: +* Java Bean validation +* retrieve the violated constraints -- #### Related articles +#### Related articles - * DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) - * InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) +* DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) +* InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) From 2afc2538b0be56a35fbc667466931071ed98fe66 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 3 Jun 2019 11:19:13 +0200 Subject: [PATCH 0625/1786] Added converter for Byte (primitive and not) --- .../transformer/AbstractTransformer.java | 2 +- .../{ => analyzer}/ConversionAnalyzer.java | 5 +- .../conversion/analyzer/package-info.java | 23 +++ .../hotels/beans/conversion/package-info.java | 4 +- .../processor/ByteConversionProcessor.java | 143 ++++++++++++++++++ .../{ => processor}/ConversionProcessor.java | 2 +- .../ConversionProcessorFactory.java | 12 +- .../PrimitiveByteConversionProcessor.java | 141 +++++++++++++++++ .../StringConversionProcessor.java | 4 +- .../conversion/processor/package-info.java | 27 ++++ 10 files changed, 349 insertions(+), 14 deletions(-) rename bull-converter/src/main/java/com/hotels/beans/conversion/{ => analyzer}/ConversionAnalyzer.java (96%) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/ByteConversionProcessor.java rename bull-converter/src/main/java/com/hotels/beans/conversion/{ => processor}/ConversionProcessor.java (98%) rename bull-converter/src/main/java/com/hotels/beans/conversion/{ => processor}/ConversionProcessorFactory.java (90%) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/PrimitiveByteConversionProcessor.java rename bull-converter/src/main/java/com/hotels/beans/conversion/{ => processor}/StringConversionProcessor.java (96%) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 9dedaf65e..162b143e8 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -24,7 +24,7 @@ import java.util.Map; import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.conversion.ConversionAnalyzer; +import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.utils.ClassUtils; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java similarity index 96% rename from bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 7a30ecdc1..22db90c01 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -14,18 +14,19 @@ * limitations under the License. */ -package com.hotels.beans.conversion; +package com.hotels.beans.conversion.analyzer; import static java.util.Optional.empty; import static java.util.Optional.of; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.conversion.ConversionProcessorFactory.getConversionProcessor; +import static com.hotels.beans.conversion.processor.ConversionProcessorFactory.getConversionProcessor; import java.util.Optional; import java.util.function.Function; import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.conversion.processor.ConversionProcessor; import com.hotels.beans.utils.ClassUtils; /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java new file mode 100644 index 000000000..f09de5ed2 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java @@ -0,0 +1,23 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Type conversion processor package. + */ + +/** + * Analyzer package. + */ +package com.hotels.beans.conversion.analyzer; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java index eb89044b2..db3079203 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /** - * Type conversion processor package. + * Conversion package. */ - package com.hotels.beans.conversion; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ByteConversionProcessor.java new file mode 100644 index 000000000..cd5413afb --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ByteConversionProcessor.java @@ -0,0 +1,143 @@ +package com.hotels.beans.conversion.processor; + +import static java.lang.Byte.valueOf; + +import java.util.function.Function; + +/** + * Provides all method for converting any primitive type to a {@link Byte}. + */ +public class ByteConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveByte() { + return Byte::valueOf; + } + + @Override + public Function convertByte() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveShort() { + return val -> valueOf((byte) ((short) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return val -> valueOf(val.byteValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInt() { + return val -> valueOf((byte) ((int) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return val -> valueOf(val.byteValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveLong() { + return val -> valueOf((byte) ((long) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return val -> valueOf(val.byteValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveFloat() { + return val -> valueOf((byte) ((float) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return val -> valueOf(val.byteValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveDouble() { + return val -> valueOf((byte) ((double) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return val -> valueOf(val.byteValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertChar() { + return val -> valueOf((byte) ((char) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> valueOf((byte) val.charValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveBoolean() { + return val -> valueOf(val ? (byte) 1 : (byte) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> valueOf(val ? (byte) 1 : (byte) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Byte::valueOf; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java similarity index 98% rename from bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index 26c270015..22cb72d96 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.conversion; +package com.hotels.beans.conversion.processor; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java similarity index 90% rename from bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index 9affbb8b5..a1414bffe 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.conversion; +package com.hotels.beans.conversion.processor; import static lombok.AccessLevel.PRIVATE; @@ -34,12 +34,12 @@ public static ConversionProcessor getConversionProcessor(final Class clazz) { ConversionProcessor conversionProcessor = null; if (clazz == String.class) { conversionProcessor = new StringConversionProcessor(); + } else if (clazz == Byte.class) { + conversionProcessor = new ByteConversionProcessor(); + } else if (clazz == byte.class) { + conversionProcessor = new PrimitiveByteConversionProcessor(); } -// else if (clazz == Byte.class) { -// conversionProcessor = new ByteConversionProcessor(); -// } else if (clazz == byte.class) { -// conversionProcessor = new PrimitiveByteConversionProcessor(); -// } else if (clazz == Short.class) { +// else if (clazz == Short.class) { // conversionProcessor = new ShortConversionProcessor(); // } else if (clazz == short.class) { // conversionProcessor = new PrimitiveShortConversionProcessor(); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/PrimitiveByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/PrimitiveByteConversionProcessor.java new file mode 100644 index 000000000..6dcce76d8 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/PrimitiveByteConversionProcessor.java @@ -0,0 +1,141 @@ +package com.hotels.beans.conversion.processor; + +import java.util.function.Function; + +/** + * Provides all method for converting any primitive type to a primitive byte. + */ +public class PrimitiveByteConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveByte() { + return val -> val; + } + + @Override + public Function convertByte() { + return Byte::byteValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveShort() { + return val -> (byte) ((short) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return Short::byteValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInt() { + return val -> (byte) ((int) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return Integer::byteValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveLong() { + return val -> (byte) ((long) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return Long::byteValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveFloat() { + return val -> (byte) ((float) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return Float::byteValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveDouble() { + return val -> (byte) ((double) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return Double::byteValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertChar() { + return val -> (byte) ((char) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> (byte) val.charValue(); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveBoolean() { + return val -> val ? (byte) 1 : (byte) 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> val ? (byte) 1 : (byte) 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Byte::parseByte; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/StringConversionProcessor.java similarity index 96% rename from bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/processor/StringConversionProcessor.java index 1f0711f06..4fd72d89e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/StringConversionProcessor.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.hotels.beans.conversion; +package com.hotels.beans.conversion.processor; import java.util.function.Function; /** - * Provides all method for converting any primitive type to a String. + * Provides all method for converting any primitive type to a {@link String}. */ public class StringConversionProcessor implements ConversionProcessor { diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java new file mode 100644 index 000000000..ebce374eb --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Type conversion processor package. + */ + +/** + * Analyzer package. + */ + +/** + * Processor package. + */ +package com.hotels.beans.conversion.processor; From bf60bf10c0aa42b69c32064eb9ea2a345fcef037 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 3 Jun 2019 12:16:07 +0200 Subject: [PATCH 0626/1786] Fixed problem with cyclomatic complexity in class: ConversionAnalyzer --- .../analyzer/ConversionAnalyzer.java | 107 +++++++++++------- 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 22db90c01..642b4f059 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -68,8 +68,8 @@ public Optional> getConversionFunction(final Class s * @return an {@link Optional} containing the conversion function (if exists) */ @SuppressWarnings("unchecked") - public Optional> getConversionFunction(final Class sourceFieldType, - final Class destinationFieldType, final boolean isDestinationFieldPrimitiveType) { + public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType, + final boolean isDestinationFieldPrimitiveType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional> conversionFunction = empty(); @@ -91,46 +91,73 @@ public Optional> getConversionFunction(final Class s private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional> conversionFunction; - if (sourceFieldType == String.class) { - conversionFunction = of(conversionProcessor.convertString()); - } else if (sourceFieldType == Byte.class) { - conversionFunction = of(conversionProcessor.convertByte()); - } else if (sourceFieldType == byte.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveByte()); - } else if (sourceFieldType == Short.class) { - conversionFunction = of(conversionProcessor.convertShort()); - } else if (sourceFieldType == short.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveShort()); - } else if (sourceFieldType == Integer.class) { - conversionFunction = of(conversionProcessor.convertInteger()); - } else if (sourceFieldType == int.class) { - conversionFunction = of(conversionProcessor.convertInt()); - } else if (sourceFieldType == Long.class) { - conversionFunction = of(conversionProcessor.convertLong()); - } else if (sourceFieldType == long.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveLong()); - } else if (sourceFieldType == Float.class) { - conversionFunction = of(conversionProcessor.convertFloat()); - } else if (sourceFieldType == float.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveFloat()); - } else if (sourceFieldType == Double.class) { - conversionFunction = of(conversionProcessor.convertDouble()); - } else if (sourceFieldType == double.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveDouble()); - } else if (sourceFieldType == Character.class) { - conversionFunction = of(conversionProcessor.convertCharacter()); - } else if (sourceFieldType == char.class) { - conversionFunction = of(conversionProcessor.convertChar()); - } else if (sourceFieldType == Boolean.class) { - conversionFunction = of(conversionProcessor.convertBoolean()); - } else if (sourceFieldType == boolean.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveBoolean()); - } else { - conversionFunction = empty(); - } + Optional> conversionFunction = getNativeTypeConversionFunction(conversionProcessor, sourceFieldType) + .or(() -> getPrimitiveTypeConversionFunction(conversionProcessor, sourceFieldType)); CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); return conversionFunction; }); } + + /** + * Returns a function that converts to a native type: byte, short, int, long, float, double, char and boolean. + * @param conversionProcessor the {@link ConversionProcessor} for the given type + * @param sourceFieldType he source field class + * @return the conversion function + */ + private Optional> getNativeTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + final Optional> conversionFunction; + if (sourceFieldType == byte.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveByte()); + } else if (sourceFieldType == short.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveShort()); + } else if (sourceFieldType == int.class) { + conversionFunction = of(conversionProcessor.convertInt()); + } else if (sourceFieldType == long.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveLong()); + } else if (sourceFieldType == float.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveFloat()); + } else if (sourceFieldType == double.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveDouble()); + } else if (sourceFieldType == char.class) { + conversionFunction = of(conversionProcessor.convertChar()); + } else if (sourceFieldType == boolean.class) { + conversionFunction = of(conversionProcessor.convertPrimitiveBoolean()); + } else { + conversionFunction = empty(); + } + return conversionFunction; + } + + /** + * Returns a function that converts to a primitive type: {@link Byte}, {@link Short}, {@link Integer}, {@link Long}, + * {@link Float}, {@link Double}, {@link Character} and {@link Boolean}. + * @param conversionProcessor the {@link ConversionProcessor} for the given type + * @param sourceFieldType he source field class + * @return the conversion function + */ + private Optional> getPrimitiveTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + final Optional> conversionFunction; + if (sourceFieldType == String.class) { + conversionFunction = of(conversionProcessor.convertString()); + } else if (sourceFieldType == Byte.class) { + conversionFunction = of(conversionProcessor.convertByte()); + } else if (sourceFieldType == Short.class) { + conversionFunction = of(conversionProcessor.convertShort()); + } else if (sourceFieldType == Integer.class) { + conversionFunction = of(conversionProcessor.convertInteger()); + } else if (sourceFieldType == Long.class) { + conversionFunction = of(conversionProcessor.convertLong()); + } else if (sourceFieldType == Float.class) { + conversionFunction = of(conversionProcessor.convertFloat()); + } else if (sourceFieldType == Double.class) { + conversionFunction = of(conversionProcessor.convertDouble()); + } else if (sourceFieldType == Character.class) { + conversionFunction = of(conversionProcessor.convertCharacter()); + } else if (sourceFieldType == Boolean.class) { + conversionFunction = of(conversionProcessor.convertBoolean()); + } else { + conversionFunction = empty(); + } + return conversionFunction; + } } From 6afdd772b05db64e97074d4136f47e34c3351d73 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 3 Jun 2019 22:15:00 +0200 Subject: [PATCH 0627/1786] Moved conversion to impl package --- .../processor/ConversionProcessorFactory.java | 4 ++++ .../{ => impl}/ByteConversionProcessor.java | 4 +++- .../PrimitiveByteConversionProcessor.java | 4 +++- .../{ => impl}/StringConversionProcessor.java | 4 +++- .../processor/impl/package-info.java | 20 +++++++++++++++++++ .../conversion/processor/package-info.java | 7 ------- 6 files changed, 33 insertions(+), 10 deletions(-) rename bull-converter/src/main/java/com/hotels/beans/conversion/processor/{ => impl}/ByteConversionProcessor.java (96%) rename bull-converter/src/main/java/com/hotels/beans/conversion/processor/{ => impl}/PrimitiveByteConversionProcessor.java (95%) rename bull-converter/src/main/java/com/hotels/beans/conversion/processor/{ => impl}/StringConversionProcessor.java (96%) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index a1414bffe..aea6a923f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -18,6 +18,10 @@ import static lombok.AccessLevel.PRIVATE; +import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; +import com.hotels.beans.conversion.processor.impl.PrimitiveByteConversionProcessor; +import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; + import lombok.NoArgsConstructor; /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java similarity index 96% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/ByteConversionProcessor.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index cd5413afb..4b4e2d15f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -1,9 +1,11 @@ -package com.hotels.beans.conversion.processor; +package com.hotels.beans.conversion.processor.impl; import static java.lang.Byte.valueOf; import java.util.function.Function; +import com.hotels.beans.conversion.processor.ConversionProcessor; + /** * Provides all method for converting any primitive type to a {@link Byte}. */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/PrimitiveByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java similarity index 95% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/PrimitiveByteConversionProcessor.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java index 6dcce76d8..8e3b5f3b5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/PrimitiveByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java @@ -1,7 +1,9 @@ -package com.hotels.beans.conversion.processor; +package com.hotels.beans.conversion.processor.impl; import java.util.function.Function; +import com.hotels.beans.conversion.processor.ConversionProcessor; + /** * Provides all method for converting any primitive type to a primitive byte. */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java similarity index 96% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/StringConversionProcessor.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index 4fd72d89e..5dd9b8a58 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -14,10 +14,12 @@ * limitations under the License. */ -package com.hotels.beans.conversion.processor; +package com.hotels.beans.conversion.processor.impl; import java.util.function.Function; +import com.hotels.beans.conversion.processor.ConversionProcessor; + /** * Provides all method for converting any primitive type to a {@link String}. */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java new file mode 100644 index 000000000..f4b54d2a8 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Processor impl package. + */ +package com.hotels.beans.conversion.processor.impl; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java index ebce374eb..c14028c3f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java @@ -13,13 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * Type conversion processor package. - */ - -/** - * Analyzer package. - */ /** * Processor package. From 5251ebd45698ae1a19ef4bca5e0989a53334409b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 4 Jun 2019 12:16:50 +0200 Subject: [PATCH 0628/1786] Modified code in order to retrieve a value from the source field from the getter method if the field does not exists --- .../beans/transformer/TransformerImpl.java | 7 +-- .../java/com/hotels/beans/BeanUtilsTest.java | 3 +- .../beans/performance/PerformanceTest.java | 3 +- .../transformer/AbstractTransformerTest.java | 3 +- .../ImmutableObjectTransformationTest.java | 5 ++- .../MixedObjectTransformationTest.java | 3 +- .../MutableObjectTransformationTest.java | 25 +++++++++-- .../beans/transformer/TransformerTest.java | 8 ++-- .../hotels/beans/utils/ReflectionUtils.java | 45 +++++++++++++++++-- .../hotels/beans/sample/FromFooNoField.java | 43 ++++++++++++++++++ .../hotels/beans/sample/FromFooSimple.java | 8 ++-- .../beans/sample/FromFooSimpleNoGetters.java | 1 + .../immutable/ImmutableToFooSimple.java | 6 +-- .../sample/mutable/MutableToFooSimple.java | 6 +-- .../mutable/MutableToFooSimpleNoSetters.java | 1 + .../beans/utils/ReflectionUtilsTest.java | 15 ++++--- 16 files changed, 142 insertions(+), 40 deletions(-) create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 321964bf0..69cb02659 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -315,7 +315,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN boolean primitiveType = classUtils.isPrimitiveType(fieldType); FieldTransformer transformerFunction = getTransformerFunction(field, fieldBreadcrumb); boolean isTransformerFunctionDefined = nonNull(transformerFunction); - Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, isTransformerFunctionDefined); + Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function // defined it recursively evaluate the value @@ -347,14 +347,15 @@ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { * Gets the source field value. If a field transformer function is defined and the field does not exists in the source object it raises an exception. * @param sourceObj sourceObj the source object * @param sourceFieldName sourceFieldName the field name in the source object (if different from the target one) + * @param field The field for which the value has to be retrieved * @param isFieldTransformerDefined indicates if a transformer function is implemented for this field * @param the sourceObj object type * @return the source field value */ - private Object getSourceFieldValue(final T sourceObj, final String sourceFieldName, final boolean isFieldTransformerDefined) { + private Object getSourceFieldValue(final T sourceObj, final String sourceFieldName, final Field field, final boolean isFieldTransformerDefined) { Object fieldValue = null; try { - fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName); + fieldValue = reflectionUtils.getFieldValue(sourceObj, sourceFieldName, field.getType()); } catch (MissingFieldException e) { // in case the source field is a primitive type and the destination one is composite, the source field value is returned without going in deep if (classUtils.isPrimitiveType(sourceObj.getClass())) { diff --git a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java index 39f2636ed..58e8ea26a 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -47,6 +47,7 @@ public class BeanUtilsTest { private static final BigInteger ID = new BigInteger("1234"); private static final String NAME = "Goofy"; + private static final boolean ACTIVE = true; /** * The class to be tested. @@ -155,6 +156,6 @@ public void testValidateThrowsExceptionIfTheGivenBeanIsInvalid() { * @return the {@link FromFooSimple} instance. */ private FromFooSimple createFromFooSimple() { - return new FromFooSimple(NAME, ID); + return new FromFooSimple(NAME, ID, ACTIVE); } } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java index cd0510b7b..b6304a68c 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -74,6 +74,7 @@ public class PerformanceTest { private static final double COMPLEX_OBJECTS_MAX_TRANSFORMATION_TIME = 1; private static final int WAIT_INTERVAL = 1000; private static final int NO_WAIT_INTERVAL = 0; + private static final boolean ACTIVE = true; private static FromFoo fromFoo; private static FromFooSimple fromFooSimple; @@ -173,7 +174,7 @@ private FromFoo createFromFoo() { * @return the {@link FromFooSimple} instance. */ private FromFooSimple createFromFooSimple() { - return new FromFooSimple(NAME, ID); + return new FromFooSimple(NAME, ID, ACTIVE); } /** diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index 26d4b6596..3f40e2d1e 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -67,6 +67,7 @@ public abstract class AbstractTransformerTest { private static final String ITEM_1 = "donald"; private static final String ITEM_2 = "duck"; private static final String SURNAME = "surname"; + private static final boolean ACTIVE = true; private static final int PHONE = 123; private static final String INDEX_NUMBER = null; private static final boolean CHECK = true; @@ -124,7 +125,7 @@ private FromFoo createFromFoo(final FromSubFoo fromSubFoo) { * @return the {@link FromFooSimple} instance. */ private FromFooSimple createFromFooSimple() { - return new FromFooSimple(NAME, ID); + return new FromFooSimple(NAME, ID, ACTIVE); } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index d0154bacb..a29442dfd 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -80,6 +80,7 @@ public class ImmutableObjectTransformationTest extends AbstractTransformerTest { private static final String PRICE_FIELD_NAME = "price"; private static final String NET_PRICE_FIELD_NAME = "price.netPrice"; private static final String GROSS_PRICE_FIELD_NAME = "price.grossPrice"; + private static final boolean ACTIVE = true; /** * The class to be tested. @@ -145,7 +146,7 @@ private Object[][] dataDefaultTransformationTesting() { @Test public void testTransformationOnAnExistingDestinationWorksProperly() { //GIVEN - ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null); + ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null, false); //WHEN underTest.transform(fromFooSimple, immutableToFoo); @@ -459,7 +460,7 @@ public void testTransformationReturnsAMeaningfulException() { @Test public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { //GIVEN - FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, () -> AGE); //WHEN diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 2047df50d..fbb193b5d 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -46,6 +46,7 @@ * Unit test for all {@link Transformer} functions related to Mixed type Java Beans. */ public class MixedObjectTransformationTest extends AbstractTransformerTest { + private static final boolean ACTIVE = true; /** * The class to be tested. */ @@ -166,7 +167,7 @@ public void testMixedBeanWithMissingFieldsThrowsMissingFieldExceptionWhenTheSour @Test public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { //GIVEN - FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); //WHEN diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 1c7fd854c..e49078bb2 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -32,6 +32,7 @@ import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.sample.FromFooNoField; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSimpleNoGetters; import com.hotels.beans.sample.mutable.MutableToFoo; @@ -45,6 +46,7 @@ * Unit test for all {@link Transformer} functions related to Mutable type Java Beans. */ public class MutableObjectTransformationTest extends AbstractTransformerTest { + private static final boolean ACTIVE = true; /** * The class to be tested. */ @@ -164,7 +166,7 @@ public void testFieldTransformationIsAppliedToAllMatchingFields() { @Test public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { //GIVEN - FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, ID); + FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, ID, ACTIVE); //WHEN MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); @@ -173,13 +175,30 @@ public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); } + /** + * Test that the transformer is able to copy object even if the source object has no fields but has getter methods. + */ + @Test + public void testTransformerIsAbleToCopyObjectsWithoutFieldButWithGetterMethods() { + //GIVEN + FromFooNoField fromFooNoField = new FromFooNoField(); + + //WHEN + MutableToFooSimpleNoSetters actual = underTest.transform(fromFooNoField, MutableToFooSimpleNoSetters.class); + + //THEN + assertEquals(actual.getId(), fromFooNoField.getId()); + assertEquals(actual.getName(), fromFooNoField.getName()); + assertEquals(actual.isActive(), fromFooNoField.isActive()); + } + /** * Test that a bean containing a field not existing in the source object, but with a transformer function defined for such object is correctly copied. */ @Test public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { //GIVEN - FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, () -> AGE); //WHEN @@ -199,7 +218,7 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor @Test(dataProvider = "dataTransformationTesting") public void testTransformationWithFieldTransformationWorksProperly(final String testCaseDescription, final String fieldToTransform, final Object transformationResult) { //GIVEN - FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID); + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); FieldTransformer fieldTransformer = new FieldTransformer<>(fieldToTransform, val -> transformationResult); //WHEN diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 5f5f54c92..05f1b1240 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -65,7 +65,7 @@ public void testRemoveFieldMappingWorksProperly() { //WHEN beanTransformer.removeFieldMapping(DEST_FIELD_NAME); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN assertFalse(transformerSettings.getFieldsNameMapping().containsKey(DEST_FIELD_NAME)); @@ -94,7 +94,7 @@ public void testResetFieldsMappingWorksProperly() { //WHEN beanTransformer.resetFieldsMapping(); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN assertTrue(transformerSettings.getFieldsNameMapping().isEmpty()); @@ -111,7 +111,7 @@ public void testResetFieldsTransformerWorksProperly() { //WHEN beanTransformer.resetFieldsTransformer(); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN assertTrue(transformerSettings.getFieldsTransformers().isEmpty()); @@ -127,7 +127,7 @@ public void testRemoveFieldTransformerWorksProperly() { //WHEN beanTransformer.removeFieldTransformer(DEST_FIELD_NAME); - TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME); + TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN assertFalse(transformerSettings.getFieldsTransformers().containsKey(DEST_FIELD_NAME)); diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 111e4b8f7..3194f57f2 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -115,35 +115,74 @@ public boolean isSetter(final Method method) { }); } + /** + * Gets the value of a field. + * @param target the field's class + * @param field the field {@link Field} + * @return the field value + */ + public Object getFieldValue(final Object target, final Field field) { + return getFieldValue(target, field.getName(), field.getType()); + } + /** * Gets the value of a field through getter method. * @param target the field's class * @param fieldName the field name + * @param fieldType the field type * @return the field value */ @SuppressWarnings("unchecked") - public Object getFieldValue(final Object target, final String fieldName) { + public Object getFieldValue(final Object target, final String fieldName, final Class fieldType) { Object fieldValue = getRealTarget(target); for (String currFieldName : fieldName.split(DOT_SPLIT_REGEX)) { if (fieldValue == null) { break; } try { - fieldValue = getGetterMethod(fieldValue.getClass(), currFieldName).apply(fieldValue); + fieldValue = getGetterMethodFunction(fieldValue.getClass(), currFieldName).apply(fieldValue); } catch (final ClassCastException | MissingMethodException | InvalidBeanException e) { fieldValue = getFieldValueDirectAccess(fieldValue, currFieldName); + } catch (final MissingFieldException e) { + fieldValue = invokeMethod(getGetterMethod(fieldValue.getClass(), currFieldName, fieldType), fieldValue); } } return fieldValue; } + /** + * Returns the getter method for the given field. + * @param fieldClass the field's class + * @param fieldName the field name + * @param fieldType the field type + * @return the getter method + */ + private Method getGetterMethod(final Class fieldClass, final String fieldName, final Class fieldType) { + final String cacheKey = "GetterMethod-" + fieldClass.getName() + '-' + fieldName; + return CACHE_MANAGER.getFromCache(cacheKey, Method.class).orElseGet(() -> { + try { + Method method = fieldClass.getMethod(getGetterMethodPrefix(fieldType) + capitalize(fieldName)); + method.setAccessible(true); + CACHE_MANAGER.cacheObject(cacheKey, method); + return method; + } catch (NoSuchMethodException e) { + if (new ClassUtils().hasField(fieldClass, fieldName)) { + throw new MissingMethodException(fieldClass.getName() + " does not allow to get value for field: " + fieldName + + ". Is a getter method defined?"); + } else { + throw new MissingFieldException(fieldClass.getName() + " hasn't a field called: " + fieldName + "."); + } + } + }); + } + /** * Returns the getter method for the given field. * @param fieldClass the field's class * @param fieldName the field name * @return the getter method */ - private Function getGetterMethod(final Class fieldClass, final String fieldName) { + private Function getGetterMethodFunction(final Class fieldClass, final String fieldName) { final String cacheKey = "GetterMethod-" + fieldClass.getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, Function.class).orElseGet(() -> { Function function; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java new file mode 100644 index 000000000..9f5c88179 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import static java.lang.Boolean.TRUE; +import static java.math.BigInteger.ONE; + +import java.math.BigInteger; + +import lombok.ToString; + +/** + * Sample object without any field but with getter methods. + */ +@ToString +public class FromFooNoField { + + public String getName() { + return "FromFooNoField"; + } + + public BigInteger getId() { + return ONE; + } + + public boolean isActive() { + return TRUE; + } +} diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java index 944a7d5bd..506887825 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java @@ -22,6 +22,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.ToString; /** * Sample immutable object. @@ -30,12 +31,9 @@ @AllArgsConstructor @Getter @Setter +@ToString public class FromFooSimple { public String name; public BigInteger id; - - @Override - public String toString() { - return "FromFooSimple"; - } + public boolean active; } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java index e5b34d849..43cdebe68 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java @@ -31,4 +31,5 @@ public class FromFooSimpleNoGetters { public String name; public BigInteger id; + public boolean active; } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java index c93c28c6c..124775776 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java @@ -29,9 +29,5 @@ public class ImmutableToFooSimple { private final String name; private final BigInteger id; - - @Override - public String toString() { - return "ImmutableToFooSimple"; - } + private boolean active; } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java index 8e33a8a56..992514188 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java @@ -29,9 +29,5 @@ public class MutableToFooSimple { private String name; private BigInteger id; - - @Override - public String toString() { - return "MutableToFooSimple"; - } + private boolean active; } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java index 39830a2e6..ded54b5d2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java @@ -27,4 +27,5 @@ public class MutableToFooSimpleNoSetters { private String name; private BigInteger id; + private boolean active; } diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index ca05a56d3..1be33c2af 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -99,11 +99,12 @@ public void beforeClass() { * @param expectedResult the expected result */ @Test(dataProvider = "dataGetFieldValueTesting") - public void testGetFieldValueWorksAsExpected(final String testCaseDescription, final Object beanObject, final String fieldName, final Object expectedResult) { + public void testGetFieldValueWorksAsExpected(final String testCaseDescription, final Object beanObject, + final String fieldName, final Class fieldType, final Object expectedResult) { // GIVEN // WHEN - Object actual = underTest.getFieldValue(beanObject, fieldName); + Object actual = underTest.getFieldValue(beanObject, fieldName, fieldType); // THEN assertEquals(expectedResult, actual); @@ -117,9 +118,11 @@ public void testGetFieldValueWorksAsExpected(final String testCaseDescription, f private Object[][] dataGetFieldValueTesting() { MutableToFoo mutableToFoo = createMutableToFoo(ZERO); return new Object[][] { - {"Tests that the method returns the field value", mutableToFoo, ID_FIELD_NAME, ZERO}, - {"Tests that the method returns null if the required field is inside a null object", mutableToFoo, NESTED_OBJECT_FIELD_NAME, null}, - {"Tests that the method returns the field value even if there is no getter method defined", createFromFooSimpleNoGetters(), ID_FIELD_NAME, ZERO} + {"Tests that the method returns the field value", mutableToFoo, ID_FIELD_NAME, BigInteger.class, ZERO}, + {"Tests that the method returns null if the required field is inside a null object", mutableToFoo, NESTED_OBJECT_FIELD_NAME, + String.class, null}, + {"Tests that the method returns the field value even if there is no getter method defined", createFromFooSimpleNoGetters(), + ID_FIELD_NAME, BigInteger.class, ZERO} }; } @@ -132,7 +135,7 @@ public void testGetFieldValueThrowsExceptionIfTheFieldDoesNotExists() { MutableToFoo mutableToFoo = createMutableToFoo(null); // WHEN - underTest.getFieldValue(mutableToFoo, NOT_EXISTING_FIELD_NAME); + underTest.getFieldValue(mutableToFoo, NOT_EXISTING_FIELD_NAME, Object.class); } /** From b07227784ef01f39bdf754eb8f9784634817605c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 4 Jun 2019 17:51:13 +0200 Subject: [PATCH 0629/1786] Provided additional test cases --- .../ImmutableObjectTransformationTest.java | 3 +- .../hotels/beans/utils/ReflectionUtils.java | 15 +- .../sample/mutable/MutableToFooAdvFields.java | 4 + .../beans/utils/ReflectionUtilsTest.java | 139 ++++++++++++++++-- 4 files changed, 137 insertions(+), 24 deletions(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index a29442dfd..060b923db 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -149,10 +149,11 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null, false); //WHEN - underTest.transform(fromFooSimple, immutableToFoo); + underTest.setValidationEnabled(true).transform(fromFooSimple, immutableToFoo); //THEN assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); + underTest.setValidationEnabled(false); } /** diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 3194f57f2..565a95b3a 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -89,7 +89,7 @@ public final class ReflectionUtils { * @param args the method parameters * @return the method result */ - private Object invokeMethod(final Method method, final Object target, final Object... args) { + protected Object invokeMethod(final Method method, final Object target, final Object... args) { try { return method.invoke(target, args); } catch (final Exception e) { @@ -166,12 +166,7 @@ private Method getGetterMethod(final Class fieldClass, final String fieldName CACHE_MANAGER.cacheObject(cacheKey, method); return method; } catch (NoSuchMethodException e) { - if (new ClassUtils().hasField(fieldClass, fieldName)) { - throw new MissingMethodException(fieldClass.getName() + " does not allow to get value for field: " + fieldName - + ". Is a getter method defined?"); - } else { - throw new MissingFieldException(fieldClass.getName() + " hasn't a field called: " + fieldName + "."); - } + throw new MissingFieldException(fieldClass.getName() + " hasn't a field called: " + fieldName + "."); } }); } @@ -183,7 +178,7 @@ private Method getGetterMethod(final Class fieldClass, final String fieldName * @return the getter method */ private Function getGetterMethodFunction(final Class fieldClass, final String fieldName) { - final String cacheKey = "GetterMethod-" + fieldClass.getName() + '-' + fieldName; + final String cacheKey = "getGetterMethodFunction-" + fieldClass.getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, Function.class).orElseGet(() -> { Function function; try { @@ -544,9 +539,9 @@ public Class getArrayType(final Field arrayField) { */ void handleReflectionException(final Exception ex) { if (ex instanceof NoSuchMethodException) { - throw new IllegalStateException("Method not found: " + ex.getMessage()); + throw new MissingMethodException("Method not found: " + ex.getMessage()); } else if (ex instanceof IllegalAccessException) { - throw new IllegalStateException("Could not access method: " + ex.getMessage()); + throw new IllegalStateException("Could not access method: " + ex.getMessage(), ex); } else { if (ex instanceof RuntimeException) { throw (RuntimeException) ex; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java index 1a90e991c..4ca500dcb 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java @@ -37,4 +37,8 @@ public class MutableToFooAdvFields { private String indexNumber; private ClassType classType; private Locale locale; + + private void setIndex(final String indexNumber) { + this.indexNumber = indexNumber; + } } diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index 1be33c2af..f0d373a93 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -52,12 +52,14 @@ import com.hotels.beans.model.ItemType; import com.hotels.beans.model.MapElemType; import com.hotels.beans.model.MapType; +import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSimpleNoGetters; import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.FromSubFoo; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToSubFoo; import com.hotels.beans.sample.mutable.MutableToFoo; +import com.hotels.beans.sample.mutable.MutableToFooAdvFields; import com.hotels.beans.sample.mutable.MutableToFooSimple; /** @@ -76,6 +78,11 @@ public class ReflectionUtilsTest { private static final String DECLARING_CLASS_NAME = "declaringClassName"; private static final String INVOKE_METHOD_NAME = "invokeMethod"; private static final String VERY_COMPLEX_MAP_FIELD_NAME = "veryComplexMap"; + private static final String GET_GETTER_METHOD_NAME = "getGetterMethod"; + private static final String NAME = "Donald Duck"; + private static final String SET_NAME_METHOD_NAME = "setName"; + private static final String SET_INDEX_METHOD_NAME = "setIndex"; + private static final String INDEX_NUMBER = "123"; /** * The class to be tested. @@ -190,7 +197,7 @@ private Object[][] dataGetFieldValueDirectAccessTesting() { /** * Tests that the method {@code handleReflectionException} raises the expected exception. */ - @Test(expectedExceptions = IllegalStateException.class) + @Test(expectedExceptions = MissingMethodException.class) public void testHandleReflectionExceptionThrowsIllegalStateExceptionWhenGivenExceptionIsNoSuchMethodException() { // GIVEN NoSuchMethodException noSuchMethodException = new NoSuchMethodException(); @@ -385,7 +392,8 @@ public void testInvokeMethodWorksProperly() throws Exception { Method idSetterMethod = underTest.getSetterMethodForField(MutableToFoo.class, ID_FIELD_NAME, BigInteger.class); // WHEN - getMethod(INVOKE_METHOD_NAME).invoke(underTest, idSetterMethod, mutableToFoo, new Object[] {ONE}); + getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) + .invoke(underTest, idSetterMethod, mutableToFoo, new Object[] {ONE}); // THEN assertEquals(ONE, mutableToFoo.getId()); @@ -395,14 +403,24 @@ public void testInvokeMethodWorksProperly() throws Exception { * Tests that the method {@code getSetterMethodForField} raises an {@link InvocationTargetException} if the argument is wrong. * @throws Exception if something goes wrong. */ - @Test(expectedExceptions = InvocationTargetException.class) + @Test public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong() throws Exception { // GIVEN MutableToFoo mutableToFoo = createMutableToFoo(null); Method idSetterMethod = underTest.getSetterMethodForField(MutableToFoo.class, LIST_FIELD_NAME, List.class); + // WHEN - getMethod(INVOKE_METHOD_NAME).invoke(underTest, idSetterMethod, mutableToFoo, new Object[] {ONE}); + InvocationTargetException actualException = null; + try { + getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) + .invoke(underTest, idSetterMethod, mutableToFoo, new Object[] {ONE}); + } catch (final InvocationTargetException e) { + actualException = e; + } + + // THEN + assertEquals(IllegalArgumentException.class, actualException.getTargetException().getClass()); } /** @@ -509,19 +527,58 @@ public void testMapGenericFieldTypeWorksProperly() { } /** - * Tests that the method {@code setFieldValue} works properly. + * Tests that the method {@code getGetterMethod} works properly. + * @throws Exception in case an error occurs */ @Test - public void testSetFieldValueWorksProperly() { + public void testGetGetterMethodWorksProperly() throws Exception { // GIVEN - MutableToFooSimple mutableToFoo = new MutableToFooSimple(); - Field idField = underTest.getDeclaredField(ID_FIELD_NAME, mutableToFoo.getClass()); + Method methodUnderTest = getMethod(underTest.getClass(), GET_GETTER_METHOD_NAME, true, Class.class, String.class, Class.class); // WHEN - underTest.setFieldValue(mutableToFoo, idField, ONE); + Object actual = methodUnderTest.invoke(underTest, FromFooSimple.class, ID_FIELD_NAME, BigInteger.class); // THEN - assertEquals(ONE, mutableToFoo.getId()); + assertNotNull(actual); + } + + /** + * Tests that the method returned by {@code getGetterMethod} returns the expected value once invoked. + * @throws Exception in case an error occurs + */ + @Test + public void testThatTheReturnedMethodFromGetGetterMethodReturnsTheExpectedValue() throws Exception { + // GIVEN + MutableToFoo mutableToFoo = createMutableToFoo(ONE); + Method getGetterMethod = getMethod(underTest.getClass(), GET_GETTER_METHOD_NAME, true, Class.class, String.class, Class.class); + Method methodUnderTest = (Method) getGetterMethod.invoke(underTest, MutableToFoo.class, ID_FIELD_NAME, BigInteger.class); + + // WHEN + BigInteger actual = (BigInteger) methodUnderTest.invoke(mutableToFoo); + + // THEN + assertEquals(ONE, actual); + } + + /** + * Tests that the method {@code getGetterMethod} raises an exception in case the given class does not have the method. + * @throws Exception in case an error occurs + */ + @Test + public void testGetGetterMethodThrowsExceptionIfTheMethodDoesNotExists() throws Exception { + // GIVEN + Method methodUnderTest = getMethod(underTest.getClass(), GET_GETTER_METHOD_NAME, true, Class.class, String.class, Class.class); + + // WHEN + InvocationTargetException actualException = null; + try { + methodUnderTest.invoke(underTest, FromFooSimpleNoGetters.class, ID_FIELD_NAME, BigInteger.class); + } catch (final InvocationTargetException e) { + actualException = e; + } + + // THEN + assertEquals(MissingFieldException.class, actualException.getTargetException().getClass()); } /** @@ -550,15 +607,71 @@ public void testSetFieldValueRaiseAnExceptionIfTheValueToSetIsNotValid() { underTest.setFieldValue(mutableToFoo, idField, Boolean.TRUE); } + @Test + public void testSetFieldValueWorksProperly() { + // GIVEN + MutableToFooSimple mutableToFoo = new MutableToFooSimple(); + Field idField = underTest.getDeclaredField(ID_FIELD_NAME, mutableToFoo.getClass()); + + // WHEN + underTest.setFieldValue(mutableToFoo, idField, ONE); + + // THEN + assertEquals(ONE, mutableToFoo.getId()); + } + + /** + * Tests that the method {@code invokeMethod} manages the exception properly. + * @param testCaseDescription the test case description + * @param methodArg the argument to pass to the invoke method + * @param isAccessible the accessibility that the {@code invokeMethod} must have + * @param expectedException the expected exception class + */ + @Test(dataProvider = "dataInvokeMethodTesting") + public void testInvokeMethodCorrectlyHandlesExceptions(final String testCaseDescription, final Object targetObject, final String methodNameToInvoke, + final Object methodArg, final boolean isAccessible, final Class expectedException) throws Exception { + // GIVEN + Method setMethodToInvoke = getMethod(targetObject.getClass(), methodNameToInvoke, isAccessible, String.class); + + // WHEN + Throwable actualException = null; + try { + underTest.invokeMethod(setMethodToInvoke, targetObject, methodArg); + } catch (final Throwable e) { + actualException = e; + } + + // THEN + assertEquals(expectedException, actualException.getClass()); + } + + /** + * Creates the parameters to be used for testing the method {@code invokeMethod}. + * @return parameters to be used for testing the the method {@code invokeMethod}. + */ + @DataProvider + private Object[][] dataInvokeMethodTesting() { + return new Object[][] { + {"Tests that the method raises an IllegalArgumentException in case the given argument is wrong", createMutableToFoo(ONE), SET_NAME_METHOD_NAME, ZERO, + true, IllegalArgumentException.class}, + {"Tests that the method raises an IllegalAccessException in case the method is not accessible", new MutableToFooAdvFields(), SET_INDEX_METHOD_NAME, + INDEX_NUMBER, false, IllegalStateException.class} + }; + } + /** * Retrieves a method. + * @param targetClass the class on which look for the method * @param methodName the method to retrieve + * @param makeAccessible sets the method visibility + * @param parameterTypes the parameter types * @return the method * @throws NoSuchMethodException if the method does not exists */ - private Method getMethod(final String methodName) throws NoSuchMethodException { - Method invokeMethod = underTest.getClass().getDeclaredMethod(methodName, Method.class, Object.class, Object[].class); - invokeMethod.setAccessible(true); + private Method getMethod(final Class targetClass, final String methodName, final boolean makeAccessible, final Class... parameterTypes) + throws NoSuchMethodException { + Method invokeMethod = targetClass.getDeclaredMethod(methodName, parameterTypes); + invokeMethod.setAccessible(makeAccessible); return invokeMethod; } From b283de559adbc7b7da28aa7610e2a5438049e84c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 4 Jun 2019 17:57:31 +0200 Subject: [PATCH 0630/1786] Added test case for getFieldValue method --- .../hotels/beans/utils/ReflectionUtilsTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index f0d373a93..ba5a9d7fc 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -117,6 +117,22 @@ public void testGetFieldValueWorksAsExpected(final String testCaseDescription, f assertEquals(expectedResult, actual); } + /** + * Tests that the method {@code getFieldValue} with a a given field returns the expected value. + */ + @Test + public void testGetFieldValueWithAGivenFieldWorksAsExpected() throws Exception { + // GIVEN + FromFooSimpleNoGetters fromFooSimpleNoGetters = createFromFooSimpleNoGetters(); + Field field = FromFooSimpleNoGetters.class.getDeclaredField(ID_FIELD_NAME); + + // WHEN + Object actual = underTest.getFieldValue(fromFooSimpleNoGetters, field); + + // THEN + assertEquals(ZERO, actual); + } + /** * Creates the parameters to be used for testing the method {@code getFieldValue}. * @return parameters to be used for testing the the method {@code getFieldValue}. From 28930da9144a697a8dc0300ec30deb8b681db1eb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 4 Jun 2019 18:19:57 +0200 Subject: [PATCH 0631/1786] Modified changelog as per the new feature --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b84152120..a6600ad7d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.4.5] 2019.06.05 +#### Added +* Modified library in order to let it able to retrieve values from getters if a field does not exists (see: [Issue 66](https://github.com/HotelsDotCom/bull/issues/66)). + ### [1.4.4.1] 2019.05.29 #### Changed * Improved Javadoc From b3ca81d022a350a7f879c19157589731fdbdf77c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 4 Jun 2019 18:35:08 +0200 Subject: [PATCH 0632/1786] Added PerformaceTest skip while deploying the artifact and during the site build --- .travis.yml | 2 +- CHANGELOG.md | 2 +- pom.xml | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f3952178c..ada84ff76 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true javadoc:aggregate -B + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true javadoc:aggregate -P site-release -B deploy: provider: pages local-dir: target/site diff --git a/CHANGELOG.md b/CHANGELOG.md index a6600ad7d..2944c91da 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.4.5] 2019.06.05 #### Added -* Modified library in order to let it able to retrieve values from getters if a field does not exists (see: [Issue 66](https://github.com/HotelsDotCom/bull/issues/66)). +* Modified library in order to let it able to retrieve values from getters if a field does not exist (see: [Issue 66](https://github.com/HotelsDotCom/bull/issues/66)). ### [1.4.4.1] 2019.05.29 #### Changed diff --git a/pom.xml b/pom.xml index 57711fbe7..84113ba85 100644 --- a/pom.xml +++ b/pom.xml @@ -213,6 +213,30 @@ + + site-release + + false + true + false + true + false + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/PerformanceTest.java + + + + + + release @@ -239,6 +263,16 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/PerformanceTest.java + + + maven-jar-plugin From c8f81e8df09fc42d36e0d8f2b5e6545edfcf9680 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 4 Jun 2019 21:55:56 +0200 Subject: [PATCH 0633/1786] Modified profile config in order to have the common properties shared --- pom.xml | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index 84113ba85..0492be6e0 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,12 @@ 3.3.2 0.12 github + + false + true + false + true + false @@ -167,27 +173,12 @@ - - full - - true - - - false - true - false - true - false - - relaxed true false true - true - false @@ -196,7 +187,6 @@ true false true - true true @@ -216,11 +206,8 @@ site-release - false - true - false - true - false + true + false @@ -244,7 +231,6 @@ true false true - true true @@ -354,8 +340,7 @@ true true ${checkstyle.check.skip} - ${checkstyle.includeTestSourceDirectory} - + ${checkstyle.includeTestSourceDirectory} check From b553721ab0cb43c267e48e974176cdd50fd18ff0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jun 2019 09:21:58 +0200 Subject: [PATCH 0634/1786] testing site release without install --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ada84ff76..8f25dbd9f 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site -Dmaven.test.skip=true javadoc:aggregate -P site-release -B + - travis_retry mvn sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release -B deploy: provider: pages local-dir: target/site From 633a9b94fa1fb98a3bf3d0e312212ea3e70b3e30 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jun 2019 09:22:17 +0200 Subject: [PATCH 0635/1786] testing site build --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8f25dbd9f..ddb782a0e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,9 +21,9 @@ jobs: install: travis_retry mvn clean install -DskipTests - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" - if: type NOT IN (pull_request) AND tag IS present +# if: type NOT IN (pull_request) AND tag IS present before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} +# - mvn versions:set -D newVersion=${TRAVIS_TAG} - travis_retry mvn sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release -B deploy: provider: pages From a61bdbddf76e3dd84ab22d48c443a34b27a3d36a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jun 2019 09:23:04 +0200 Subject: [PATCH 0636/1786] restore site release only after a tag --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ddb782a0e..8f25dbd9f 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,9 +21,9 @@ jobs: install: travis_retry mvn clean install -DskipTests - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" -# if: type NOT IN (pull_request) AND tag IS present + if: type NOT IN (pull_request) AND tag IS present before_deploy: -# - mvn versions:set -D newVersion=${TRAVIS_TAG} + - mvn versions:set -D newVersion=${TRAVIS_TAG} - travis_retry mvn sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release -B deploy: provider: pages From 9fcc772be1315f232d00c2e4700026804b66587d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jun 2019 09:29:53 +0200 Subject: [PATCH 0637/1786] restored existing configuration --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8f25dbd9f..f4e280fa2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release -B + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release -B deploy: provider: pages local-dir: target/site From cb9956aa5f058947550f4be4141aa1d4f2b3d909 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jun 2019 10:13:56 +0200 Subject: [PATCH 0638/1786] re-added test skip during the site build --- .travis.yml | 2 +- .../main/java/com/hotels/beans/transformer/TransformerImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f4e280fa2..982b6833c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release -B + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dmaven.test.skip=true site:site javadoc:aggregate -P site-release -B deploy: provider: pages local-dir: target/site diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 69cb02659..8447d42dc 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -347,7 +347,7 @@ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { * Gets the source field value. If a field transformer function is defined and the field does not exists in the source object it raises an exception. * @param sourceObj sourceObj the source object * @param sourceFieldName sourceFieldName the field name in the source object (if different from the target one) - * @param field The field for which the value has to be retrieved + * @param field the field for which the value has to be retrieved * @param isFieldTransformerDefined indicates if a transformer function is implemented for this field * @param the sourceObj object type * @return the source field value From f027cf2d5f327f08fa02cb706b87ebca59df9565 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jun 2019 10:26:55 +0200 Subject: [PATCH 0639/1786] removed -B option from mvn site build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 982b6833c..17cf8cde2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dmaven.test.skip=true site:site javadoc:aggregate -P site-release -B + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dmaven.test.skip=true site:site javadoc:aggregate -P site-release deploy: provider: pages local-dir: target/site From 86cf8c91a5e0ecf1b9df71066cae9fefed7b2dd2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jun 2019 10:39:57 +0200 Subject: [PATCH 0640/1786] [maven-release-plugin] prepare release 1.4.5 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 7a958f62e..177edaa81 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.5-SNAPSHOT + 1.4.5 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 5bb6ccff4..3dc6d9edb 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.5-SNAPSHOT + 1.4.5 diff --git a/pom.xml b/pom.xml index 0492be6e0..43eded802 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.5-SNAPSHOT + 1.4.5 pom 2019 @@ -70,7 +70,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.5 From 219b3426ef31c09e5c36ca3a990efded68e92b6d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jun 2019 10:40:08 +0200 Subject: [PATCH 0641/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 177edaa81..42ca9a987 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.5 + 1.4.6-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 3dc6d9edb..385b26ea5 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.5 + 1.4.6-SNAPSHOT diff --git a/pom.xml b/pom.xml index 43eded802..263ee0ba7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.5 + 1.4.6-SNAPSHOT pom 2019 @@ -70,7 +70,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.5 + HEAD From 1bf2e5e0539869d5158e3b0a65e89eb5861ca337 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jun 2019 14:28:53 +0200 Subject: [PATCH 0642/1786] Added supported feature --- README.md | 1 + docs/site/markdown/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index ac45ca335..8bcd96b7b 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ mvnw.cmd clean install -P relaxed * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. * allows to skip transformation for a given set of fields. +* supports the values retrieval from getters if a field does not exists in the source object # Feature samples diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 51c566f37..46cf37c61 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -32,6 +32,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. * allows to skip transformation for a given set of fields. +* supports the values retrieval from getters if a field does not exists in the source object #### Bean Validation: From 3f64a7f295df52ed53def88610cf2efa1216125b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 6 Jun 2019 16:52:28 +0200 Subject: [PATCH 0643/1786] Added feature sample --- README.md | 17 +++++++++++++++++ docs/site/markdown/transformer/samples.md | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/README.md b/README.md index ac45ca335..a72060f69 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ mvnw.cmd clean install -P relaxed * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. * allows to skip transformation for a given set of fields. +* supports the values retrieval from getters if a field does not exists in the source object # Feature samples @@ -487,6 +488,22 @@ beanUtils.getTransformer() .transform(fromBean2, toBean); ~~~ +### Not existing field in the source object: +In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should get the field value from that method. +~~~Java +public class FromBean { public class ToBean { + private final BigInteger id; + public BigInteger getId() { + return BigInteger.TEN; // all args constructor + } // getters... +} + } +~~~ +And one line code as: +~~~Java +ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` ## Third party library comparison diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index cba5aa27e..05c610b5e 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -410,4 +410,20 @@ beanUtils.getTransformer() .transform(fromBean2, toBean); ~~~ +### Not existing field in the source object: +In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should get the field value from that method. +~~~Java +public class FromBean { public class ToBean { + private final BigInteger id; + public BigInteger getId() { + return BigInteger.TEN; // all args constructor + } // getters... +} + } +~~~ +And one line code as: +~~~Java +ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` or on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) \ No newline at end of file From 0a5170f3abb5cb79413c8dbcd5104f5f3876fb46 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 6 Jun 2019 16:55:55 +0200 Subject: [PATCH 0644/1786] Minor: fixed explanation in the readme file --- README.md | 2 +- docs/site/markdown/transformer/samples.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a72060f69..7183bffa5 100644 --- a/README.md +++ b/README.md @@ -489,7 +489,7 @@ beanUtils.getTransformer() ~~~ ### Not existing field in the source object: -In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should get the field value from that method. +In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should gets the field value from that method. ~~~Java public class FromBean { public class ToBean { private final BigInteger id; diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 05c610b5e..d102276c6 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -411,7 +411,7 @@ beanUtils.getTransformer() ~~~ ### Not existing field in the source object: -In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should get the field value from that method. +In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library gets the field value from that method. ~~~Java public class FromBean { public class ToBean { private final BigInteger id; From 62070f2868bad6d32c2cbff23739de5b6617b78e Mon Sep 17 00:00:00 2001 From: amarsiglia Date: Fri, 7 Jun 2019 10:16:42 +0200 Subject: [PATCH 0645/1786] Added Integer, Long and Short conversion processors + minor fixes --- .../analyzer/ConversionAnalyzer.java | 2 +- .../processor/ConversionProcessor.java | 2 +- .../processor/ConversionProcessorFactory.java | 30 ++-- .../impl/ByteConversionProcessor.java | 2 +- .../impl/IntegerConversionProcessor.java | 145 ++++++++++++++++++ .../impl/LongConversionProcessor.java | 145 ++++++++++++++++++ .../PrimitiveByteConversionProcessor.java | 4 +- .../impl/PrimitiveIntConversionProcessor.java | 143 +++++++++++++++++ .../PrimitiveShortConversionProcessor.java | 143 +++++++++++++++++ .../impl/ShortConversionProcessor.java | 145 ++++++++++++++++++ .../impl/StringConversionProcessor.java | 2 +- 11 files changed, 744 insertions(+), 19 deletions(-) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 642b4f059..0f261ee9c 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -111,7 +111,7 @@ public Optional> getConversionFunction(final Class s } else if (sourceFieldType == short.class) { conversionFunction = of(conversionProcessor.convertPrimitiveShort()); } else if (sourceFieldType == int.class) { - conversionFunction = of(conversionProcessor.convertInt()); + conversionFunction = of(conversionProcessor.convertPrimitiveInt()); } else if (sourceFieldType == long.class) { conversionFunction = of(conversionProcessor.convertPrimitiveLong()); } else if (sourceFieldType == float.class) { diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index 22cb72d96..7d97667a4 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -50,7 +50,7 @@ public interface ConversionProcessor { * Converts an int type. * @return the converted value */ - Function convertInt(); + Function convertPrimitiveInt(); /** * Converts an {@link Integer} type. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index aea6a923f..4b52e5e0b 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -19,7 +19,12 @@ import static lombok.AccessLevel.PRIVATE; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; +import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; +import com.hotels.beans.conversion.processor.impl.LongConversionProcessor; import com.hotels.beans.conversion.processor.impl.PrimitiveByteConversionProcessor; +import com.hotels.beans.conversion.processor.impl.PrimitiveIntConversionProcessor; +import com.hotels.beans.conversion.processor.impl.PrimitiveShortConversionProcessor; +import com.hotels.beans.conversion.processor.impl.ShortConversionProcessor; import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; import lombok.NoArgsConstructor; @@ -42,18 +47,17 @@ public static ConversionProcessor getConversionProcessor(final Class clazz) { conversionProcessor = new ByteConversionProcessor(); } else if (clazz == byte.class) { conversionProcessor = new PrimitiveByteConversionProcessor(); - } -// else if (clazz == Short.class) { -// conversionProcessor = new ShortConversionProcessor(); -// } else if (clazz == short.class) { -// conversionProcessor = new PrimitiveShortConversionProcessor(); -// } else if (clazz == Integer.class) { -// conversionProcessor = new IntegerConversionProcessor(); -// } else if (clazz == int.class) { -// conversionProcessor = new IntConversionProcessor(); -// } else if (clazz == Long.class) { -// conversionProcessor = new LongConversionProcessor(); -// } else if (clazz == long.class) { + } else if (clazz == Short.class) { + conversionProcessor = new ShortConversionProcessor(); + } else if (clazz == short.class) { + conversionProcessor = new PrimitiveShortConversionProcessor(); + } else if (clazz == Integer.class) { + conversionProcessor = new IntegerConversionProcessor(); + } else if (clazz == int.class) { + conversionProcessor = new PrimitiveIntConversionProcessor(); + } else if (clazz == Long.class) { + conversionProcessor = new LongConversionProcessor(); + } //else if (clazz == long.class) { // conversionProcessor = new PrimitiveLongConversionProcessor(); // } else if (clazz == Float.class) { // conversionProcessor = new FloatConversionProcessor(); @@ -74,4 +78,4 @@ public static ConversionProcessor getConversionProcessor(final Class clazz) { // } return conversionProcessor; } -} +} \ No newline at end of file diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index 4b4e2d15f..ba478c10b 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -43,7 +43,7 @@ public Function convertShort() { * {@inheritDoc} */ @Override - public Function convertInt() { + public Function convertPrimitiveInt() { return val -> valueOf((byte) ((int) val)); } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java new file mode 100644 index 000000000..7521448a2 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -0,0 +1,145 @@ +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Integer.valueOf; + +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a {@link Integer}. + */ +public class IntegerConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveByte() { + return val -> valueOf((int) ((byte)val)); + } + + @Override + public Function convertByte() { + return Integer::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveShort() { + return val -> valueOf((int) ((short)val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return Integer::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveInt() { + return val -> (int) val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveLong() { + return val -> valueOf((int) ((long) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return val -> valueOf(val.intValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveFloat() { + return val -> valueOf((int) ((float) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return val -> valueOf(val.intValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveDouble() { + return val -> valueOf((int) ((double) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return val -> valueOf(val.intValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertChar() { + return val -> valueOf((int) ((char) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return Integer::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveBoolean() { + return val -> valueOf(val ? (int) 1 : (int) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> valueOf(val ? (int) 1 : (int) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Integer::valueOf; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java new file mode 100644 index 000000000..eed6a43d5 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -0,0 +1,145 @@ +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Long.valueOf; + +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a {@link Long}. + */ +public class LongConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveByte() { + return val -> valueOf((long) ((byte) val)); + } + + @Override + public Function convertByte() { + return Long::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveShort() { + return val -> valueOf((short) ((long) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return Short::longValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveInt() { + return val -> valueOf((long) ((int) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return val -> valueOf(val.longValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveLong() { + return Long::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return Long::longValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveFloat() { + return val -> valueOf((long) ((float) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return Float::longValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveDouble() { + return val -> valueOf((long) ((double) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return Double::longValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertChar() { + return val -> valueOf((long) ((char) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> valueOf((long) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveBoolean() { + return val -> valueOf(val ? (long) 1 : (long) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> valueOf(val ? (long) 1 : (long) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Long::valueOf; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java index 8e3b5f3b5..10a088003 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java @@ -13,7 +13,7 @@ public class PrimitiveByteConversionProcessor implements ConversionProcessor { */ @Override public Function convertPrimitiveByte() { - return val -> val; + return val -> (byte) val; } @Override @@ -41,7 +41,7 @@ public Function convertShort() { * {@inheritDoc} */ @Override - public Function convertInt() { + public Function convertPrimitiveInt() { return val -> (byte) ((int) val); } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java new file mode 100644 index 000000000..361623596 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java @@ -0,0 +1,143 @@ +package com.hotels.beans.conversion.processor.impl; + +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a primitive int. + */ +public class PrimitiveIntConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveByte() { + return val -> (int) ((byte) val); + } + + @Override + public Function convertByte() { + return Byte::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveShort() { + return val -> (int) val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return Short::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveInt() { + return val -> (int) val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveLong() { + return val -> (int) ((long) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return Long::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveFloat() { + return val -> (int) ((float) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return Float::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveDouble() { + return val -> (int) ((double) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return Double::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertChar() { + return val -> (int) ((char) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> (int) val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveBoolean() { + return val -> val ? (int) 1 : (int) 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> val ? (int) 1 : (int) 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Integer::parseInt; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java new file mode 100644 index 000000000..535556aa7 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java @@ -0,0 +1,143 @@ +package com.hotels.beans.conversion.processor.impl; + +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a primitive short. + */ +public class PrimitiveShortConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveByte() { + return val -> (short) ((byte) val); + } + + @Override + public Function convertByte() { + return Byte::shortValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveShort() { + return val -> (short) val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return Short::shortValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveInt() { + return val -> (short) ((int) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return Integer::shortValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveLong() { + return val -> (short) ((long) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return Long::shortValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveFloat() { + return val -> (short) ((float) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return Float::shortValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveDouble() { + return val -> (short) ((double) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return Double::shortValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertChar() { + return val -> (short) ((char) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> (short) val.charValue(); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveBoolean() { + return val -> val ? (short) 1 : (short) 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> val ? (short) 1 : (short) 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Short::parseShort; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java new file mode 100644 index 000000000..233fe5e86 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -0,0 +1,145 @@ +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Short.valueOf; + +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a {@link Short}. + */ +public class ShortConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveByte() { + return val -> (short) val; + } + + @Override + public Function convertByte() { + return Short::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveShort() { + return Short::shortValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveInt() { + return val -> valueOf((short) ((int) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return val -> valueOf(val.shortValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveLong() { + return val -> valueOf((short) ((long) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return val -> valueOf(val.shortValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveFloat() { + return val -> valueOf((short) ((float) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return val -> valueOf(val.shortValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveDouble() { + return val -> valueOf((short) ((double) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return val -> valueOf(val.shortValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertChar() { + return val -> valueOf((short) ((char) val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> valueOf((short) val.charValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertPrimitiveBoolean() { + return val -> valueOf(val ? (short) 1 : (short) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> valueOf(val ? (short) 1 : (short) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Short::valueOf; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index 5dd9b8a58..a30af9b38 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -56,7 +56,7 @@ public final Function convertShort() { /** * {@inheritDoc} */ - public final Function convertInt() { + public final Function convertPrimitiveInt() { return val -> Integer.toString(val); } From 681b3004aafc4410c9d12df9f5cf0f03ba997869 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 9 Jun 2019 16:02:51 +0200 Subject: [PATCH 0646/1786] Added class name for the "No default constructor available" exception message --- .../src/main/java/com/hotels/beans/utils/ClassUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java index f6c69ec13..02a6026fb 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -420,7 +420,7 @@ public Supplier getNoArgsConstructor(final Class clazz) { CACHE_MANAGER.cacheObject(cacheKey, constructor); return constructor; } catch (Throwable e) { - throw new InvalidBeanException("No default constructors available"); + throw new InvalidBeanException("No default constructors available for class: " + clazz.getName()); } }); } From e2675f7d2eabe45a2f425c143f96e300a7579c20 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 12 Jun 2019 10:57:31 +0200 Subject: [PATCH 0647/1786] Merged with upstream --- .../processor/impl/ByteConversionProcessor.java | 15 +++++++++++++++ .../impl/IntegerConversionProcessor.java | 15 +++++++++++++++ .../processor/impl/LongConversionProcessor.java | 15 +++++++++++++++ .../impl/PrimitiveByteConversionProcessor.java | 15 +++++++++++++++ .../impl/PrimitiveIntConversionProcessor.java | 15 +++++++++++++++ .../impl/PrimitiveShortConversionProcessor.java | 15 +++++++++++++++ .../processor/impl/ShortConversionProcessor.java | 15 +++++++++++++++ 7 files changed, 105 insertions(+) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index ba478c10b..f3a74c88a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -1,3 +1,18 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.conversion.processor.impl; import static java.lang.Byte.valueOf; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index 7521448a2..39d73eac5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -1,3 +1,18 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.conversion.processor.impl; import static java.lang.Integer.valueOf; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index eed6a43d5..0985bef5b 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -1,3 +1,18 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.conversion.processor.impl; import static java.lang.Long.valueOf; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java index 10a088003..f5359d5af 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java @@ -1,3 +1,18 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.conversion.processor.impl; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java index 361623596..8c53e4ee4 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java @@ -1,3 +1,18 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.conversion.processor.impl; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java index 535556aa7..d2fd1557a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java @@ -1,3 +1,18 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.conversion.processor.impl; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index 233fe5e86..3a6847a37 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -1,3 +1,18 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.conversion.processor.impl; import static java.lang.Short.valueOf; From 1bb36e7950c9585fae8c5e6ff3af826331df5874 Mon Sep 17 00:00:00 2001 From: amarsiglia Date: Tue, 18 Jun 2019 16:42:11 +0200 Subject: [PATCH 0648/1786] Added funtional interfaces to convert objects to the desired primitives --- .../function/ToBooleanFunction.java | 51 +++++++++++++++++++ .../conversion/function/ToByteFunction.java | 51 +++++++++++++++++++ .../conversion/function/ToCharFunction.java | 51 +++++++++++++++++++ .../conversion/function/ToFloatFunction.java | 51 +++++++++++++++++++ .../conversion/function/ToShortFunction.java | 51 +++++++++++++++++++ 5 files changed, 255 insertions(+) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java new file mode 100644 index 000000000..359b22642 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.hotels.beans.conversion.function; + +import java.util.function.Function; + +/** + * Represents a function that produces a double-valued result. This is the + * {@code boolean}-producing primitive specialization for {@link Function}. + * + *

      This is a functional interface + * whose functional method is {@link #applyAsBoolean(Object)}. + * + * @param the type of the input to the function + * + * @see Function + * @since 1.8 + */ +@FunctionalInterface +public interface ToBooleanFunction { + + /** + * Applies this function to the given argument. + * + * @param value the function argument + * @return the function result + */ + boolean applyAsBoolean(T value); +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java new file mode 100644 index 000000000..9b7ca48d0 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.hotels.beans.conversion.function; + +import java.util.function.Function; + +/** + * Represents a function that produces a double-valued result. This is the + * {@code byte}-producing primitive specialization for {@link Function}. + * + *

      This is a functional interface + * whose functional method is {@link #applyAsByte(Object)}. + * + * @param the type of the input to the function + * + * @see Function + * @since 1.8 + */ +@FunctionalInterface +public interface ToByteFunction { + + /** + * Applies this function to the given argument. + * + * @param value the function argument + * @return the function result + */ + byte applyAsByte(T value); +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java new file mode 100644 index 000000000..ce23e8d88 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.hotels.beans.conversion.function; + +import java.util.function.Function; + +/** + * Represents a function that produces a double-valued result. This is the + * {@code char}-producing primitive specialization for {@link Function}. + * + *

      This is a functional interface + * whose functional method is {@link #applyAsChar(Object)}. + * + * @param the type of the input to the function + * + * @see Function + * @since 1.8 + */ +@FunctionalInterface +public interface ToCharFunction { + + /** + * Applies this function to the given argument. + * + * @param value the function argument + * @return the function result + */ + char applyAsChar(T value); +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java new file mode 100644 index 000000000..da9b31a83 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.hotels.beans.conversion.function; + +import java.util.function.Function; + +/** + * Represents a function that produces a double-valued result. This is the + * {@code float}-producing primitive specialization for {@link Function}. + * + *

      This is a functional interface + * whose functional method is {@link #applyAsFloat(Object)}. + * + * @param the type of the input to the function + * + * @see Function + * @since 1.8 + */ +@FunctionalInterface +public interface ToFloatFunction { + + /** + * Applies this function to the given argument. + * + * @param value the function argument + * @return the function result + */ + float applyAsFloat(T value); +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java new file mode 100644 index 000000000..ec63ec9ae --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.hotels.beans.conversion.function; + +import java.util.function.Function; + +/** + * Represents a function that produces a double-valued result. This is the + * {@code short}-producing primitive specialization for {@link Function}. + * + *

      This is a functional interface + * whose functional method is {@link #applyAsShort(Object)}. + * + * @param the type of the input to the function + * + * @see Function + * @since 1.8 + */ +@FunctionalInterface +public interface ToShortFunction { + + /** + * Applies this function to the given argument. + * + * @param value the function argument + * @return the function result + */ + short applyAsShort(T value); +} From bc15033d458c17d4bd0ce85e103d7d49ba7965bb Mon Sep 17 00:00:00 2001 From: amarsiglia Date: Fri, 21 Jun 2019 19:52:07 +0200 Subject: [PATCH 0649/1786] Moved primitives types conversion processor logic to a single class. Not working atm. --- .../analyzer/ConversionAnalyzer.java | 21 ++- .../function/ToBooleanFunction.java | 31 ++-- .../conversion/function/ToByteFunction.java | 31 ++-- .../conversion/function/ToCharFunction.java | 31 ++-- .../conversion/function/ToFloatFunction.java | 31 ++-- .../conversion/function/ToShortFunction.java | 31 ++-- .../processor/ConversionProcessor.java | 79 +++++++-- .../processor/ConversionProcessorFactory.java | 46 +++-- .../impl/ByteConversionProcessor.java | 65 +------ .../impl/IntegerConversionProcessor.java | 65 +------ .../impl/LongConversionProcessor.java | 65 +------ .../PrimitiveByteConversionProcessor.java | 159 ------------------ .../impl/PrimitiveConversionProcessor.java | 70 ++++++++ .../impl/PrimitiveIntConversionProcessor.java | 158 ----------------- .../PrimitiveShortConversionProcessor.java | 158 ----------------- .../impl/ShortConversionProcessor.java | 65 +------ .../impl/StringConversionProcessor.java | 66 +------- .../processor/impl/package-info.java | 20 --- 18 files changed, 223 insertions(+), 969 deletions(-) delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveConversionProcessor.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 0f261ee9c..765409965 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -23,7 +23,6 @@ import static com.hotels.beans.conversion.processor.ConversionProcessorFactory.getConversionProcessor; import java.util.Optional; -import java.util.function.Function; import com.hotels.beans.cache.CacheManager; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -56,7 +55,7 @@ public ConversionAnalyzer() { * @param destinationFieldType the destination field class * @return an {@link Optional} containing the conversion function (if exists) */ - public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { + public Optional getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { return getConversionFunction(sourceFieldType, destinationFieldType, classUtils.isPrimitiveType(destinationFieldType)); } @@ -68,11 +67,11 @@ public Optional> getConversionFunction(final Class s * @return an {@link Optional} containing the conversion function (if exists) */ @SuppressWarnings("unchecked") - public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType, + public Optional getConversionFunction(final Class sourceFieldType, final Class destinationFieldType, final boolean isDestinationFieldPrimitiveType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional> conversionFunction = empty(); + Optional conversionFunction = empty(); if (destinationFieldType != sourceFieldType && isDestinationFieldPrimitiveType && classUtils.isPrimitiveType(sourceFieldType)) { conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); } @@ -88,10 +87,10 @@ public Optional> getConversionFunction(final Class s * @return the conversion function */ @SuppressWarnings("unchecked") - private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + private Optional getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional> conversionFunction = getNativeTypeConversionFunction(conversionProcessor, sourceFieldType) + Optional conversionFunction = getNativeTypeConversionFunction(conversionProcessor, sourceFieldType) .or(() -> getPrimitiveTypeConversionFunction(conversionProcessor, sourceFieldType)); CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); return conversionFunction; @@ -104,8 +103,8 @@ public Optional> getConversionFunction(final Class s * @param sourceFieldType he source field class * @return the conversion function */ - private Optional> getNativeTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { - final Optional> conversionFunction; + private Optional getNativeTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + final Optional conversionFunction; if (sourceFieldType == byte.class) { conversionFunction = of(conversionProcessor.convertPrimitiveByte()); } else if (sourceFieldType == short.class) { @@ -119,7 +118,7 @@ public Optional> getConversionFunction(final Class s } else if (sourceFieldType == double.class) { conversionFunction = of(conversionProcessor.convertPrimitiveDouble()); } else if (sourceFieldType == char.class) { - conversionFunction = of(conversionProcessor.convertChar()); + conversionFunction = of(conversionProcessor.convertPrimitiveChar()); } else if (sourceFieldType == boolean.class) { conversionFunction = of(conversionProcessor.convertPrimitiveBoolean()); } else { @@ -135,8 +134,8 @@ public Optional> getConversionFunction(final Class s * @param sourceFieldType he source field class * @return the conversion function */ - private Optional> getPrimitiveTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { - final Optional> conversionFunction; + private Optional getPrimitiveTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + final Optional conversionFunction; if (sourceFieldType == String.class) { conversionFunction = of(conversionProcessor.convertString()); } else if (sourceFieldType == Byte.class) { diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java index 359b22642..8255f0c3a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java @@ -1,26 +1,17 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. +/** + * Copyright (C) 2019 Expedia, Inc. * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.hotels.beans.conversion.function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java index 9b7ca48d0..a73e58f76 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java @@ -1,26 +1,17 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. +/** + * Copyright (C) 2019 Expedia, Inc. * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.hotels.beans.conversion.function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java index ce23e8d88..58f87c85d 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java @@ -1,26 +1,17 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. +/** + * Copyright (C) 2019 Expedia, Inc. * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.hotels.beans.conversion.function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java index da9b31a83..a5bbb2cb9 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java @@ -1,26 +1,17 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. +/** + * Copyright (C) 2019 Expedia, Inc. * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.hotels.beans.conversion.function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java index ec63ec9ae..f4ca99f1f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java @@ -1,26 +1,17 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. +/** + * Copyright (C) 2019 Expedia, Inc. * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.hotels.beans.conversion.function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index 7d97667a4..9e5061a1b 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -17,110 +17,153 @@ package com.hotels.beans.conversion.processor; import java.util.function.Function; +import java.util.function.ToDoubleFunction; +import java.util.function.ToIntFunction; +import java.util.function.ToLongFunction; + +import com.hotels.beans.conversion.function.ToBooleanFunction; +import com.hotels.beans.conversion.function.ToByteFunction; +import com.hotels.beans.conversion.function.ToCharFunction; +import com.hotels.beans.conversion.function.ToFloatFunction; +import com.hotels.beans.conversion.function.ToShortFunction; /** * Conversion methods for all primitive types. */ -public interface ConversionProcessor { +public abstract class ConversionProcessor { /** * Converts a byte type. * @return the converted value */ - Function convertPrimitiveByte(); + public ToByteFunction convertPrimitiveByte() { + return val -> (byte) val; + } /** * Converts a {@link Byte} type. * @return the converted value */ - Function convertByte(); + public Function convertByte() { + return val -> val; + } /** * Converts a short type. * @return the converted value */ - Function convertPrimitiveShort(); + public ToShortFunction convertPrimitiveShort() { + return val -> (short) val; + } /** * Converts a {@link Short} type. * @return the converted value */ - Function convertShort(); + public Function convertShort() { + return val -> val; + } /** * Converts an int type. * @return the converted value */ - Function convertPrimitiveInt(); + public ToIntFunction convertPrimitiveInt() { + return val -> (int) val; + } /** * Converts an {@link Integer} type. * @return the converted value */ - Function convertInteger(); + public Function convertInteger() { + return val -> val; + } /** * Converts a long type. * @return the converted value */ - Function convertPrimitiveLong(); + public ToLongFunction convertPrimitiveLong() { + return val -> (long) val; + } /** * Converts a {@link Long} type. * @return the converted value */ - Function convertLong(); + public Function convertLong() { + return val -> val; + } /** * Converts a float type. * @return the converted value */ - Function convertPrimitiveFloat(); + public ToFloatFunction convertPrimitiveFloat() { + return val -> (float) val; + } /** * Converts an {@link Float} type. * @return the converted value */ - Function convertFloat(); + public Function convertFloat() { + return val -> val; + } /** * Converts a double type. * @return the converted value */ - Function convertPrimitiveDouble(); + public ToDoubleFunction convertPrimitiveDouble() { + return val -> (double) val; + } /** * Converts a {@link Double} type. * @return the converted value */ - Function convertDouble(); + public Function convertDouble() { + return val -> val; + } /** * Converts a char type. * @return the converted value */ - Function convertChar(); + public ToCharFunction convertPrimitiveChar() { + return val -> (char) val; + } /** * Converts a {@link Character} type. * @return the converted value */ - Function convertCharacter(); + public Function convertCharacter() { + return val -> val; + } /** * Converts a boolean type. * @return the converted value */ - Function convertPrimitiveBoolean(); + public ToBooleanFunction convertPrimitiveBoolean() { + return val -> (boolean) val; + } /** * Converts a {@link Boolean} type. * @return the converted value */ - Function convertBoolean(); + public Function convertBoolean() { + return val -> val; + } /** * Converts a {@link String} type. * @return the converted value */ - Function convertString(); + public Function convertString() { + return val -> val; + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index 4b52e5e0b..afed3739b 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -21,9 +21,7 @@ import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; import com.hotels.beans.conversion.processor.impl.LongConversionProcessor; -import com.hotels.beans.conversion.processor.impl.PrimitiveByteConversionProcessor; -import com.hotels.beans.conversion.processor.impl.PrimitiveIntConversionProcessor; -import com.hotels.beans.conversion.processor.impl.PrimitiveShortConversionProcessor; +import com.hotels.beans.conversion.processor.impl.PrimitiveConversionProcessor; import com.hotels.beans.conversion.processor.impl.ShortConversionProcessor; import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; @@ -41,41 +39,41 @@ public final class ConversionProcessorFactory { */ public static ConversionProcessor getConversionProcessor(final Class clazz) { ConversionProcessor conversionProcessor = null; - if (clazz == String.class) { - conversionProcessor = new StringConversionProcessor(); - } else if (clazz == Byte.class) { + if (clazz == Byte.class) { conversionProcessor = new ByteConversionProcessor(); } else if (clazz == byte.class) { - conversionProcessor = new PrimitiveByteConversionProcessor(); - } else if (clazz == Short.class) { - conversionProcessor = new ShortConversionProcessor(); - } else if (clazz == short.class) { - conversionProcessor = new PrimitiveShortConversionProcessor(); - } else if (clazz == Integer.class) { - conversionProcessor = new IntegerConversionProcessor(); - } else if (clazz == int.class) { - conversionProcessor = new PrimitiveIntConversionProcessor(); - } else if (clazz == Long.class) { - conversionProcessor = new LongConversionProcessor(); - } //else if (clazz == long.class) { -// conversionProcessor = new PrimitiveLongConversionProcessor(); + conversionProcessor = new PrimitiveConversionProcessor(); +// } else if (clazz == Short.class) { +// conversionProcessor = new ShortConversionProcessor(); +// } else if (clazz == short.class) { +// conversionProcessor = new PrimitiveShortConversionProcessor(); +// } else if (clazz == Integer.class) { +// conversionProcessor = new IntegerConversionProcessor(); +// } else if (clazz == int.class) { +// conversionProcessor = new PrimitiveConversionProcessor(); +// } else if (clazz == Long.class) { +// conversionProcessor = new LongConversionProcessor(); +// } else if (clazz == long.class) { +// conversionProcessor = new PrimitiveConversionProcessor(); // } else if (clazz == Float.class) { // conversionProcessor = new FloatConversionProcessor(); // } else if (clazz == float.class) { -// conversionProcessor = new PrimitiveFloatConversionProcessor(); +// conversionProcessor = new PrimitiveConversionProcessor(); // } else if (clazz == Double.class) { // conversionProcessor = new DoubleConversionProcessor(); // } else if (clazz == double.class) { -// conversionProcessor = new PrimitiveDoubleConversionProcessor(); +// conversionProcessor = new PrimitiveConversionProcessor(); // } else if (clazz == Character.class) { // conversionProcessor = new CharacterConversionProcessor(); // } else if (clazz == char.class) { -// conversionProcessor = new CharConversionProcessor(); +// conversionProcessor = new PrimitiveConversionProcessor(); // } else if (clazz == Boolean.class) { // conversionProcessor = new BooleanConversionProcessor(); // } else if (clazz == boolean.class) { -// conversionProcessor = new PrimitiveBooleanConversionProcessor(); -// } +// conversionProcessor = new PrimitiveConversionProcessor(); +// } else if (clazz == String.class) { +// conversionProcessor = new StringConversionProcessor(); + } return conversionProcessor; } } \ No newline at end of file diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index f38254d8a..cf1761342 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -24,28 +24,13 @@ /** * Provides all method for converting any primitive type to a {@link Byte}. */ -public final class ByteConversionProcessor implements ConversionProcessor { - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveByte() { - return Byte::valueOf; - } +public final class ByteConversionProcessor extends ConversionProcessor { @Override public Function convertByte() { return val -> val; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveShort() { - return val -> valueOf((byte) ((short) val)); - } - /** * {@inheritDoc} */ @@ -54,14 +39,6 @@ public Function convertShort() { return val -> valueOf(val.byteValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveInt() { - return val -> valueOf((byte) ((int) val)); - } - /** * {@inheritDoc} */ @@ -70,14 +47,6 @@ public Function convertInteger() { return val -> valueOf(val.byteValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveLong() { - return val -> valueOf((byte) ((long) val)); - } - /** * {@inheritDoc} */ @@ -86,14 +55,6 @@ public Function convertLong() { return val -> valueOf(val.byteValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveFloat() { - return val -> valueOf((byte) ((float) val)); - } - /** * {@inheritDoc} */ @@ -102,14 +63,6 @@ public Function convertFloat() { return val -> valueOf(val.byteValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveDouble() { - return val -> valueOf((byte) ((double) val)); - } - /** * {@inheritDoc} */ @@ -118,14 +71,6 @@ public Function convertDouble() { return val -> valueOf(val.byteValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertChar() { - return val -> valueOf((byte) ((char) val)); - } - /** * {@inheritDoc} */ @@ -134,14 +79,6 @@ public Function convertCharacter() { return val -> valueOf((byte) val.charValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveBoolean() { - return val -> valueOf(val ? (byte) 1 : (byte) 0); - } - /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index 5e82526e6..ddf1559b4 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -24,28 +24,13 @@ /** * Provides all method for converting any primitive type to a {@link Integer}. */ -public final class IntegerConversionProcessor implements ConversionProcessor { - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveByte() { - return val -> valueOf((int) ((byte) val)); - } +public final class IntegerConversionProcessor extends ConversionProcessor { @Override public Function convertByte() { return Integer::valueOf; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveShort() { - return val -> valueOf((int) ((short)val)); - } - /** * {@inheritDoc} */ @@ -54,14 +39,6 @@ public Function convertShort() { return Integer::valueOf; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveInt() { - return val -> (int) val; - } - /** * {@inheritDoc} */ @@ -70,14 +47,6 @@ public Function convertInteger() { return val -> val; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveLong() { - return val -> valueOf((int) ((long) val)); - } - /** * {@inheritDoc} */ @@ -86,14 +55,6 @@ public Function convertLong() { return val -> valueOf(val.intValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveFloat() { - return val -> valueOf((int) ((float) val)); - } - /** * {@inheritDoc} */ @@ -102,14 +63,6 @@ public Function convertFloat() { return val -> valueOf(val.intValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveDouble() { - return val -> valueOf((int) ((double) val)); - } - /** * {@inheritDoc} */ @@ -118,14 +71,6 @@ public Function convertDouble() { return val -> valueOf(val.intValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertChar() { - return val -> valueOf((int) ((char) val)); - } - /** * {@inheritDoc} */ @@ -134,14 +79,6 @@ public Function convertCharacter() { return Integer::valueOf; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveBoolean() { - return val -> valueOf(val ? 1 : 0); - } - /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index 6da7abb07..2da061c42 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -24,14 +24,7 @@ /** * Provides all method for converting any primitive type to a {@link Long}. */ -public final class LongConversionProcessor implements ConversionProcessor { - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveByte() { - return val -> valueOf((long) ((byte) val)); - } +public final class LongConversionProcessor extends ConversionProcessor { /** * {@inheritDoc} @@ -41,14 +34,6 @@ public Function convertByte() { return Long::valueOf; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveShort() { - return val -> valueOf((short) ((long) val)); - } - /** * {@inheritDoc} */ @@ -57,14 +42,6 @@ public Function convertShort() { return Short::longValue; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveInt() { - return val -> valueOf((long) ((int) val)); - } - /** * {@inheritDoc} */ @@ -73,14 +50,6 @@ public Function convertInteger() { return val -> valueOf(val.longValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveLong() { - return Long::valueOf; - } - /** * {@inheritDoc} */ @@ -89,14 +58,6 @@ public Function convertLong() { return Long::longValue; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveFloat() { - return val -> valueOf((long) ((float) val)); - } - /** * {@inheritDoc} */ @@ -105,14 +66,6 @@ public Function convertFloat() { return Float::longValue; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveDouble() { - return val -> valueOf((long) ((double) val)); - } - /** * {@inheritDoc} */ @@ -121,14 +74,6 @@ public Function convertDouble() { return Double::longValue; } - /** - * {@inheritDoc} - */ - @Override - public Function convertChar() { - return val -> valueOf((long) ((char) val)); - } - /** * {@inheritDoc} */ @@ -137,14 +82,6 @@ public Function convertCharacter() { return val -> valueOf((long) val); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveBoolean() { - return val -> valueOf(val ? (long) 1 : (long) 0); - } - /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java deleted file mode 100644 index 58e0801f4..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveByteConversionProcessor.java +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion.processor.impl; - -import java.util.function.Function; - -import com.hotels.beans.conversion.processor.ConversionProcessor; - -/** - * Provides all method for converting any primitive type to a primitive byte. - */ -public final class PrimitiveByteConversionProcessor implements ConversionProcessor { - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveByte() { - return val -> (byte) val; - } - - @Override - public Function convertByte() { - return Byte::byteValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveShort() { - return val -> (byte) ((short) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertShort() { - return Short::byteValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveInt() { - return val -> (byte) ((int) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertInteger() { - return Integer::byteValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveLong() { - return val -> (byte) ((long) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertLong() { - return Long::byteValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveFloat() { - return val -> (byte) ((float) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertFloat() { - return Float::byteValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveDouble() { - return val -> (byte) ((double) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertDouble() { - return Double::byteValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertChar() { - return val -> (byte) ((char) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertCharacter() { - return val -> (byte) val.charValue(); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveBoolean() { - return val -> val ? (byte) 1 : (byte) 0; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertBoolean() { - return val -> val ? (byte) 1 : (byte) 0; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertString() { - return Byte::parseByte; - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveConversionProcessor.java new file mode 100644 index 000000000..fe7198e58 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveConversionProcessor.java @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.hotels.beans.conversion.processor.impl; + +import java.util.function.ToDoubleFunction; +import java.util.function.ToIntFunction; +import java.util.function.ToLongFunction; + +import com.hotels.beans.conversion.function.ToBooleanFunction; +import com.hotels.beans.conversion.function.ToByteFunction; +import com.hotels.beans.conversion.function.ToCharFunction; +import com.hotels.beans.conversion.function.ToFloatFunction; +import com.hotels.beans.conversion.function.ToShortFunction; +import com.hotels.beans.conversion.processor.ConversionProcessor; + +public class PrimitiveConversionProcessor extends ConversionProcessor { + + @Override + public ToByteFunction convertPrimitiveByte() { + return super.convertPrimitiveByte(); + } + + @Override + public ToShortFunction convertPrimitiveShort() { + return super.convertPrimitiveShort(); + } + + @Override + public ToIntFunction convertPrimitiveInt() { + return super.convertPrimitiveInt(); + } + + @Override + public ToLongFunction convertPrimitiveLong() { + return super.convertPrimitiveLong(); + } + + @Override + public ToFloatFunction convertPrimitiveFloat() { + return super.convertPrimitiveFloat(); + } + + @Override + public ToDoubleFunction convertPrimitiveDouble() { + return super.convertPrimitiveDouble(); + } + + @Override + public ToCharFunction convertPrimitiveChar() { + return super.convertPrimitiveChar(); + } + + @Override + public ToBooleanFunction convertPrimitiveBoolean() { + return super.convertPrimitiveBoolean(); + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java deleted file mode 100644 index e9f69ae76..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveIntConversionProcessor.java +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.hotels.beans.conversion.processor.impl; - -import java.util.function.Function; - -import com.hotels.beans.conversion.processor.ConversionProcessor; - -/** - * Provides all method for converting any primitive type to a primitive int. - */ -public final class PrimitiveIntConversionProcessor implements ConversionProcessor { - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveByte() { - return val -> (int) ((byte) val); - } - - @Override - public Function convertByte() { - return Byte::intValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveShort() { - return val -> (int) val; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertShort() { - return Short::intValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveInt() { - return val -> (int) val; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertInteger() { - return val -> val; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveLong() { - return val -> (int) ((long) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertLong() { - return Long::intValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveFloat() { - return val -> (int) ((float) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertFloat() { - return Float::intValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveDouble() { - return val -> (int) ((double) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertDouble() { - return Double::intValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertChar() { - return val -> (int) ((char) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertCharacter() { - return val -> (int) val; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveBoolean() { - return val -> val ? (int) 1 : (int) 0; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertBoolean() { - return val -> val ? (int) 1 : (int) 0; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertString() { - return Integer::parseInt; - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java deleted file mode 100644 index eebfffcc9..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveShortConversionProcessor.java +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.hotels.beans.conversion.processor.impl; - -import java.util.function.Function; - -import com.hotels.beans.conversion.processor.ConversionProcessor; - -/** - * Provides all method for converting any primitive type to a primitive short. - */ -public final class PrimitiveShortConversionProcessor implements ConversionProcessor { - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveByte() { - return val -> (short) ((byte) val); - } - - @Override - public Function convertByte() { - return Byte::shortValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveShort() { - return val -> (short) val; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertShort() { - return Short::shortValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveInt() { - return val -> (short) ((int) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertInteger() { - return Integer::shortValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveLong() { - return val -> (short) ((long) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertLong() { - return Long::shortValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveFloat() { - return val -> (short) ((float) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertFloat() { - return Float::shortValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveDouble() { - return val -> (short) ((double) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertDouble() { - return Double::shortValue; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertChar() { - return val -> (short) ((char) val); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertCharacter() { - return val -> (short) val.charValue(); - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveBoolean() { - return val -> val ? (short) 1 : (short) 0; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertBoolean() { - return val -> val ? (short) 1 : (short) 0; - } - - /** - * {@inheritDoc} - */ - @Override - public Function convertString() { - return Short::parseShort; - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index 96f690943..a88ce0a66 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -24,28 +24,13 @@ /** * Provides all method for converting any primitive type to a {@link Short}. */ -public final class ShortConversionProcessor implements ConversionProcessor { - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveByte() { - return val -> (short) val; - } +public final class ShortConversionProcessor extends ConversionProcessor { @Override public Function convertByte() { return Short::valueOf; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveShort() { - return Short::shortValue; - } - /** * {@inheritDoc} */ @@ -54,14 +39,6 @@ public Function convertShort() { return val -> val; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveInt() { - return val -> valueOf((short) ((int) val)); - } - /** * {@inheritDoc} */ @@ -70,14 +47,6 @@ public Function convertInteger() { return val -> valueOf(val.shortValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveLong() { - return val -> valueOf((short) ((long) val)); - } - /** * {@inheritDoc} */ @@ -86,14 +55,6 @@ public Function convertLong() { return val -> valueOf(val.shortValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveFloat() { - return val -> valueOf((short) ((float) val)); - } - /** * {@inheritDoc} */ @@ -102,14 +63,6 @@ public Function convertFloat() { return val -> valueOf(val.shortValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveDouble() { - return val -> valueOf((short) ((double) val)); - } - /** * {@inheritDoc} */ @@ -118,14 +71,6 @@ public Function convertDouble() { return val -> valueOf(val.shortValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertChar() { - return val -> valueOf((short) ((char) val)); - } - /** * {@inheritDoc} */ @@ -134,14 +79,6 @@ public Function convertCharacter() { return val -> valueOf((short) val.charValue()); } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveBoolean() { - return val -> valueOf(val ? (short) 1 : (short) 0); - } - /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index 417ce4459..bdca58d55 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -23,15 +23,7 @@ /** * Provides all method for converting any primitive type to a {@link String}. */ -public final class StringConversionProcessor implements ConversionProcessor { - - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveByte() { - return val -> Byte.toString(val); - } +public final class StringConversionProcessor extends ConversionProcessor { /** * {@inheritDoc} @@ -41,14 +33,6 @@ public Function convertByte() { return Object::toString; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveShort() { - return val -> Short.toString(val); - } - /** * {@inheritDoc} */ @@ -57,14 +41,6 @@ public Function convertShort() { return Object::toString; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveInt() { - return val -> Integer.toString(val); - } - /** * {@inheritDoc} */ @@ -73,14 +49,6 @@ public Function convertInteger() { return Object::toString; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveLong() { - return val -> Long.toString(val); - } - /** * {@inheritDoc} */ @@ -89,14 +57,6 @@ public Function convertLong() { return Object::toString; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveFloat() { - return val -> Float.toString(val); - } - /** * {@inheritDoc} */ @@ -105,14 +65,6 @@ public Function convertFloat() { return Object::toString; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveDouble() { - return val -> Double.toString(val); - } - /** * {@inheritDoc} */ @@ -121,14 +73,6 @@ public Function convertDouble() { return Object::toString; } - /** - * {@inheritDoc} - */ - @Override - public Function convertChar() { - return val -> Character.toString(val); - } - /** * {@inheritDoc} */ @@ -137,14 +81,6 @@ public Function convertCharacter() { return Object::toString; } - /** - * {@inheritDoc} - */ - @Override - public Function convertPrimitiveBoolean() { - return val -> Boolean.toString(val); - } - /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java deleted file mode 100644 index f4b54d2a8..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Processor impl package. - */ -package com.hotels.beans.conversion.processor.impl; From 55f740101aefa87b64491c13649749000cde3fac Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 22 Jun 2019 00:43:01 +0200 Subject: [PATCH 0650/1786] - Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). - Added check during project build in order to prevent the add different versions of the same dependency. --- CHANGELOG-JDK8.md | 2 + CHANGELOG.md | 4 +- config/maven/updateRules.xml | 15 +++++++ pom.xml | 76 ++++++++++++++++++++++++++++++++++-- 4 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 config/maven/updateRules.xml diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index f631b499e..2ca4a77c9 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. ### [1.1.20] 2019.05.24 #### Added * Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/HotelsDotCom/bull/issues/62)). +* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). +* Added check during project build in order to prevent the add different versions of the same dependency. #### Fixed * Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). diff --git a/CHANGELOG.md b/CHANGELOG.md index 2944c91da..44e6b2bcf 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ All notable changes to this project will be documented in this file. ### [1.4.5] 2019.06.05 -#### Added +* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). +* Added check during project build in order to prevent the add different versions of the same dependency. +#### Changes * Modified library in order to let it able to retrieve values from getters if a field does not exist (see: [Issue 66](https://github.com/HotelsDotCom/bull/issues/66)). ### [1.4.4.1] 2019.05.29 diff --git a/config/maven/updateRules.xml b/config/maven/updateRules.xml new file mode 100644 index 000000000..fc1620c19 --- /dev/null +++ b/config/maven/updateRules.xml @@ -0,0 +1,15 @@ + + + + + (?i).*Alpha(?:-?\d+)? + (?i).*a(?:-?\d+)? + (?i).*Beta(?:-?\d+)? + (?i).*-B(?:-?\d+)? + (?i).*RC(?:-?\d+)? + (?i).*CR(?:-?\d+)? + (?i).*M(?:-?\d+)? + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 263ee0ba7..4d676b483 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,10 @@ ${jdk.version} 3.12.0 3.1.0 - 2.1.5.RELEASE + 2.7 + 3.3.9 + 3.0.0-M2 + 2.1.6.RELEASE 1.18.8 3.9 0.11 @@ -41,7 +44,7 @@ 6.14.3 2.0.1.Final - 6.0.16.Final + 6.0.17.Final 1.7.26 3.0.0 2.2.6 @@ -54,7 +57,7 @@ 0.85 0.85 - 3.3.2 + 3.3.3 0.12 github @@ -135,6 +138,16 @@ shazamcrest ${shazamcrest.version} test + + + org.skyscreamer + jsonassert + + + junit + junit + + com.google.code.gson @@ -281,6 +294,19 @@ + + + check-for-updates + + + + org.codehaus.mojo + versions-maven-plugin + false + + + + @@ -503,6 +529,46 @@ + + + org.apache.maven.plugins + maven-enforcer-plugin + ${maven.enforcer.plugin.version} + + + enforce-maven + + enforce + + + + + ${required.maven.version} + + + + + + + + + + org.codehaus.mojo + versions-maven-plugin + ${maven.update.checker.version} + + file:///${project.basedir}/config/maven/updateRules.xml + + + + compile + + display-dependency-updates + display-plugin-updates + + + + @@ -551,6 +617,10 @@ + + org.apache.maven.plugins + maven-enforcer-plugin + From 50b12ed3e04a24cdc7e65c7c064ccde0b527efcb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 22 Jun 2019 07:44:56 +0200 Subject: [PATCH 0651/1786] Updated bean comment --- .../src/test/java/com/hotels/beans/sample/FromFoo.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java index d9662e008..30999f4a2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java @@ -22,13 +22,15 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import lombok.ToString; /** - * Sample immutable object. + * Sample mixed object. */ @AllArgsConstructor @Getter @Setter +@ToString public class FromFoo implements Cloneable { private final String name; private BigInteger id; @@ -39,9 +41,4 @@ public class FromFoo implements Cloneable { public FromFoo clone() throws CloneNotSupportedException { return (FromFoo) super.clone(); } - - @Override - public String toString() { - return "FromFoo"; - } } From 59109ffeaf452df9d619fe496d21be149724947f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 25 Jun 2019 17:16:59 +0200 Subject: [PATCH 0652/1786] - Upgraded parent pom - Removed version inherited by parent pom --- .../main/java/com/hotels/beans/BeanUtils.java | 2 +- .../hotels/beans/validator/ValidatorImpl.java | 2 +- config/checkstyle/rules.xml | 25 +++++++++++-------- ...ateRules.xml => versions-plugin-rules.xml} | 0 pom.xml | 15 +++-------- 5 files changed, 20 insertions(+), 24 deletions(-) rename config/maven/{updateRules.xml => versions-plugin-rules.xml} (100%) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java b/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java index 065be7f88..78d46ce7f 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java @@ -20,8 +20,8 @@ import java.util.function.Function; -import com.hotels.beans.transformer.TransformerImpl; import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.TransformerImpl; import com.hotels.beans.validator.Validator; import com.hotels.beans.validator.ValidatorImpl; diff --git a/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java index a2246e618..13ab2a9ae 100644 --- a/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java @@ -32,8 +32,8 @@ import javax.validation.ConstraintViolation; -import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.error.InvalidBeanException; /** * Java Bean validation class. diff --git a/config/checkstyle/rules.xml b/config/checkstyle/rules.xml index 1d7840aae..92f3a4897 100644 --- a/config/checkstyle/rules.xml +++ b/config/checkstyle/rules.xml @@ -1,7 +1,6 @@ - + "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" + "https://checkstyle.org/dtds/configuration_1_3.dtd"> + + + + + + + + + + + + - - - - - - - - diff --git a/config/maven/updateRules.xml b/config/maven/versions-plugin-rules.xml similarity index 100% rename from config/maven/updateRules.xml rename to config/maven/versions-plugin-rules.xml diff --git a/pom.xml b/pom.xml index 4d676b483..a64a9b192 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.hotels hotels-oss-parent - 4.0.1 + 4.1.0 @@ -31,11 +31,6 @@ 11 ${jdk.version} ${jdk.version} - 3.12.0 - 3.1.0 - 2.7 - 3.3.9 - 3.0.0-M2 2.1.6.RELEASE 1.18.8 3.9 @@ -207,6 +202,7 @@ com.mycila license-maven-plugin + ${license.maven.plugin.version} none @@ -533,7 +529,6 @@ org.apache.maven.plugins maven-enforcer-plugin - ${maven.enforcer.plugin.version} enforce-maven @@ -543,7 +538,7 @@ - ${required.maven.version} + ${maven.required.version} @@ -555,9 +550,8 @@ org.codehaus.mojo versions-maven-plugin - ${maven.update.checker.version} - file:///${project.basedir}/config/maven/updateRules.xml + file:///${project.basedir}/config/maven/versions-plugin-rules.xml @@ -603,7 +597,6 @@ org.apache.maven.plugins maven-javadoc-plugin - ${maven.javadoc.plugin.version} ${javadoc.skip} From 0a9434c156b8576a98516bf666cff0668759b4d7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 14:07:01 +0200 Subject: [PATCH 0653/1786] Improved documentation messages --- CHANGELOG-JDK8.md | 12 ++++++++---- CHANGELOG.md | 16 ++++++++++------ .../hotels/beans/utils/ReflectionUtilsTest.java | 2 ++ config/checkstyle/rules.xml | 1 + 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 2ca4a77c9..f0d52843d 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.1.21] 2019.06.27 +#### Changed +* Improved exception messages in order to provide more details. + ### [1.1.20] 2019.05.24 #### Added * Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/HotelsDotCom/bull/issues/62)). @@ -11,16 +15,16 @@ All notable changes to this project will be documented in this file. * Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). ### [1.1.19] 2019.05.23 -#### Changes +#### Changed * Made the project multi module ### [1.1.18] 2019.05.18 -#### Changes +#### Changed * Removed deprecated method: `setValidationDisabled` * Updated dependencies ### [1.1.17] 2019.05.13 -#### Changes +#### Changed * **Modified project behaviour:** since this version the **"Bean Validation" is disabled by default**, to enable it, the following instruction needs to be executed: `transformer.setValidationEnabled(true);` ### [1.1.16] 2019.05.11 @@ -28,7 +32,7 @@ All notable changes to this project will be documented in this file. * Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/HotelsDotCom/bull/issues/57)). ### [1.1.15] 2019.05.08 -#### Changes +#### Changed * Modified value retrieval/set from/to source/destination object in order to minimise the executed actions * Updated `hotels-oss-parent` version to `4.0.1` (was `4.0.0`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 44e6b2bcf..146c43c1a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,14 @@ All notable changes to this project will be documented in this file. +### [1.4.6] 2019.06.27 +#### Changed +* Improved exception messages in order to provide more details. + ### [1.4.5] 2019.06.05 * Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). * Added check during project build in order to prevent the add different versions of the same dependency. -#### Changes +#### Changed * Modified library in order to let it able to retrieve values from getters if a field does not exist (see: [Issue 66](https://github.com/HotelsDotCom/bull/issues/66)). ### [1.4.4.1] 2019.05.29 @@ -20,16 +24,16 @@ All notable changes to this project will be documented in this file. * Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). ### [1.4.1.1] 2019.05.24 -#### Changes +#### Changed * Made the project multi module ### [1.4.1] 2019.05.18 -#### Changes +#### Changed * Removed deprecated method: `setValidationDisabled` * Updated dependencies ### [1.4.0] 2019.05.13 -#### Changes +#### Changed * **Modified project behaviour:** since this version the **"Bean Validation" is disabled by default**, to enable it, the following instruction needs to be executed: `transformer.setValidationEnabled(true);` ### [1.3.2] 2019.05.11 @@ -37,8 +41,8 @@ All notable changes to this project will be documented in this file. * Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/HotelsDotCom/bull/issues/57)). ### [1.3.1] 2019.05.08 -#### Changes -* In order to improve the library performances the following changes have been applied: +#### Changed +* In order to improve the library performances the following Changed have been applied: * Modified no args constructor invocation in order to use `LambdaMetafactory` * Modified field value retrieval in order to use `LambdaMetafactory` * Modified value retrieval/set from/to source/destination object in order to minimise the executed actions diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index ba5a9d7fc..56c4b3ce6 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -103,6 +103,7 @@ public void beforeClass() { * @param testCaseDescription the test case description * @param beanObject the java bean from which the value has to be retrieved * @param fieldName the name of the field to retrieve + * @param fieldType the type of the field to retrieve * @param expectedResult the expected result */ @Test(dataProvider = "dataGetFieldValueTesting") @@ -119,6 +120,7 @@ public void testGetFieldValueWorksAsExpected(final String testCaseDescription, f /** * Tests that the method {@code getFieldValue} with a a given field returns the expected value. + * @throws Exception in case of issues */ @Test public void testGetFieldValueWithAGivenFieldWorksAsExpected() throws Exception { diff --git a/config/checkstyle/rules.xml b/config/checkstyle/rules.xml index 92f3a4897..644d056f3 100644 --- a/config/checkstyle/rules.xml +++ b/config/checkstyle/rules.xml @@ -1,3 +1,4 @@ + From 26c480a8b8d898a8b40cea86691cdc7d8f4923b7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 14:11:42 +0200 Subject: [PATCH 0654/1786] Improved changelog --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index f0d52843d..a93d8e4da 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.1.21] 2019.06.27 #### Changed -* Improved exception messages in order to provide more details. +* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/HotelsDotCom/bull/issues/70)). ### [1.1.20] 2019.05.24 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 146c43c1a..b29030c32 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.4.6] 2019.06.27 #### Changed -* Improved exception messages in order to provide more details. +* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/HotelsDotCom/bull/issues/70)). ### [1.4.5] 2019.06.05 * Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). From e34bc9f49b37ef51d48d87f87a2858275dcfdc6e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 14:28:32 +0200 Subject: [PATCH 0655/1786] testing travis build with open jdk --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 17cf8cde2..ec067c0da 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -jdk: oraclejdk11 +jdk: openjdk11 env: global: # Sonatype jira info From 5d9af00a25a102a5d6ad0c35f59df10a1c4754a8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 14:36:50 +0200 Subject: [PATCH 0656/1786] restored oracle jdk for travis build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ec067c0da..17cf8cde2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -jdk: openjdk11 +jdk: oraclejdk11 env: global: # Sonatype jira info From 0bfe87fdbbc42ccde31938fda44bc2ff033ac421 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 15:30:56 +0200 Subject: [PATCH 0657/1786] Testing travis build with openjdk --- .travis.yml | 4 ++-- pom.xml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 17cf8cde2..84ed9e6ad 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -jdk: oraclejdk11 +jdk: openjdk11 env: global: # Sonatype jira info @@ -18,7 +18,7 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - install: travis_retry mvn clean install -DskipTests + install: travis_retry mvn clean install -DskipTests javadoc:aggregate site:site - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present diff --git a/pom.xml b/pom.xml index a64a9b192..44dca9e8c 100644 --- a/pom.xml +++ b/pom.xml @@ -45,12 +45,12 @@ 2.2.6 0.8.2 - 0.85 - 0.85 - 0.85 - 0.85 - 0.85 - 0.85 + 0.9 + 0.9 + 0.9 + 0.9 + 0.9 + 0.9 3.3.3 0.12 From 5b272acb786c17e9a9e98df2c4e89395ed66e448 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 15:42:58 +0200 Subject: [PATCH 0658/1786] removed testing build param --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 84ed9e6ad..ec067c0da 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - install: travis_retry mvn clean install -DskipTests javadoc:aggregate site:site + install: travis_retry mvn clean install -DskipTests - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present From 15296509d7a76bc419643984cd8fedf9064eef4f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 16:50:34 +0200 Subject: [PATCH 0659/1786] re adding oracle jdk --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ec067c0da..17cf8cde2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -jdk: openjdk11 +jdk: oraclejdk11 env: global: # Sonatype jira info From 1dce29cf03ec09254338ae9a3237e05dafc03ae8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 16:59:56 +0200 Subject: [PATCH 0660/1786] Using openjdk due to a travis issue --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 17cf8cde2..ec067c0da 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -jdk: oraclejdk11 +jdk: openjdk11 env: global: # Sonatype jira info From f1cd2ba2e143007bace1e86316f1f43d90b0cae8 Mon Sep 17 00:00:00 2001 From: amarsiglia Date: Thu, 27 Jun 2019 17:36:51 +0200 Subject: [PATCH 0661/1786] Removed functions for primitives handling since the conversion for primitives should be done by java. Some other improvements. --- .../analyzer/ConversionAnalyzer.java | 40 +------ .../processor/ConversionProcessor.java | 111 ++---------------- .../processor/ConversionProcessorFactory.java | 51 +++----- .../impl/ByteConversionProcessor.java | 12 +- .../impl/CharacterConversionProcessor.java | 99 ++++++++++++++++ .../impl/DoubleConversionProcessor.java | 84 +++++++++++++ .../impl/FloatConversionProcessor.java | 85 ++++++++++++++ .../impl/IntegerConversionProcessor.java | 14 +-- .../impl/LongConversionProcessor.java | 6 +- .../impl/PrimitiveConversionProcessor.java | 70 ----------- .../impl/ShortConversionProcessor.java | 12 +- .../impl/StringConversionProcessor.java | 4 +- 12 files changed, 326 insertions(+), 262 deletions(-) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveConversionProcessor.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 765409965..000e20e5b 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -90,43 +90,12 @@ public Optional getConversionFunction(final Class sourceFieldType, fin private Optional getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional conversionFunction = getNativeTypeConversionFunction(conversionProcessor, sourceFieldType) - .or(() -> getPrimitiveTypeConversionFunction(conversionProcessor, sourceFieldType)); + Optional conversionFunction = getPrimitiveTypeConversionFunction(conversionProcessor, sourceFieldType); CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); return conversionFunction; }); } - /** - * Returns a function that converts to a native type: byte, short, int, long, float, double, char and boolean. - * @param conversionProcessor the {@link ConversionProcessor} for the given type - * @param sourceFieldType he source field class - * @return the conversion function - */ - private Optional getNativeTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { - final Optional conversionFunction; - if (sourceFieldType == byte.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveByte()); - } else if (sourceFieldType == short.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveShort()); - } else if (sourceFieldType == int.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveInt()); - } else if (sourceFieldType == long.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveLong()); - } else if (sourceFieldType == float.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveFloat()); - } else if (sourceFieldType == double.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveDouble()); - } else if (sourceFieldType == char.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveChar()); - } else if (sourceFieldType == boolean.class) { - conversionFunction = of(conversionProcessor.convertPrimitiveBoolean()); - } else { - conversionFunction = empty(); - } - return conversionFunction; - } - /** * Returns a function that converts to a primitive type: {@link Byte}, {@link Short}, {@link Integer}, {@link Long}, * {@link Float}, {@link Double}, {@link Character} and {@link Boolean}. @@ -152,9 +121,10 @@ private Optional getPrimitiveTypeConversionFunction(final ConversionProcessor co conversionFunction = of(conversionProcessor.convertDouble()); } else if (sourceFieldType == Character.class) { conversionFunction = of(conversionProcessor.convertCharacter()); - } else if (sourceFieldType == Boolean.class) { - conversionFunction = of(conversionProcessor.convertBoolean()); - } else { + } //else if (sourceFieldType == Boolean.class) { +// conversionFunction = of(conversionProcessor.convertBoolean()); +// } + else { conversionFunction = empty(); } return conversionFunction; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index 9e5061a1b..2d8209704 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -17,153 +17,62 @@ package com.hotels.beans.conversion.processor; import java.util.function.Function; -import java.util.function.ToDoubleFunction; -import java.util.function.ToIntFunction; -import java.util.function.ToLongFunction; - -import com.hotels.beans.conversion.function.ToBooleanFunction; -import com.hotels.beans.conversion.function.ToByteFunction; -import com.hotels.beans.conversion.function.ToCharFunction; -import com.hotels.beans.conversion.function.ToFloatFunction; -import com.hotels.beans.conversion.function.ToShortFunction; /** * Conversion methods for all primitive types. */ -public abstract class ConversionProcessor { - /** - * Converts a byte type. - * @return the converted value - */ - public ToByteFunction convertPrimitiveByte() { - return val -> (byte) val; - } - +public interface ConversionProcessor { /** * Converts a {@link Byte} type. * @return the converted value */ - public Function convertByte() { - return val -> val; - } - - /** - * Converts a short type. - * @return the converted value - */ - public ToShortFunction convertPrimitiveShort() { - return val -> (short) val; - } + Function convertByte(); /** * Converts a {@link Short} type. * @return the converted value */ - public Function convertShort() { - return val -> val; - } - - /** - * Converts an int type. - * @return the converted value - */ - public ToIntFunction convertPrimitiveInt() { - return val -> (int) val; - } + Function convertShort(); /** * Converts an {@link Integer} type. * @return the converted value */ - public Function convertInteger() { - return val -> val; - } - - /** - * Converts a long type. - * @return the converted value - */ - public ToLongFunction convertPrimitiveLong() { - return val -> (long) val; - } + Function convertInteger(); /** * Converts a {@link Long} type. * @return the converted value */ - public Function convertLong() { - return val -> val; - } - - /** - * Converts a float type. - * @return the converted value - */ - public ToFloatFunction convertPrimitiveFloat() { - return val -> (float) val; - } + Function convertLong(); /** * Converts an {@link Float} type. * @return the converted value */ - public Function convertFloat() { - return val -> val; - } - - /** - * Converts a double type. - * @return the converted value - */ - public ToDoubleFunction convertPrimitiveDouble() { - return val -> (double) val; - } + Function convertFloat(); /** * Converts a {@link Double} type. * @return the converted value */ - public Function convertDouble() { - return val -> val; - } - - /** - * Converts a char type. - * @return the converted value - */ - public ToCharFunction convertPrimitiveChar() { - return val -> (char) val; - } + Function convertDouble(); /** * Converts a {@link Character} type. * @return the converted value */ - public Function convertCharacter() { - return val -> val; - } - - /** - * Converts a boolean type. - * @return the converted value - */ - public ToBooleanFunction convertPrimitiveBoolean() { - return val -> (boolean) val; - } + Function convertCharacter(); /** * Converts a {@link Boolean} type. * @return the converted value */ - public Function convertBoolean() { - return val -> val; - } + Function convertBoolean(); /** * Converts a {@link String} type. * @return the converted value */ - public Function convertString() { - return val -> val; - } + Function convertString(); } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index afed3739b..115962a37 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -19,9 +19,11 @@ import static lombok.AccessLevel.PRIVATE; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; +import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; +import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; +import com.hotels.beans.conversion.processor.impl.FloatConversionProcessor; import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; import com.hotels.beans.conversion.processor.impl.LongConversionProcessor; -import com.hotels.beans.conversion.processor.impl.PrimitiveConversionProcessor; import com.hotels.beans.conversion.processor.impl.ShortConversionProcessor; import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; @@ -41,39 +43,24 @@ public static ConversionProcessor getConversionProcessor(final Class clazz) { ConversionProcessor conversionProcessor = null; if (clazz == Byte.class) { conversionProcessor = new ByteConversionProcessor(); - } else if (clazz == byte.class) { - conversionProcessor = new PrimitiveConversionProcessor(); -// } else if (clazz == Short.class) { -// conversionProcessor = new ShortConversionProcessor(); -// } else if (clazz == short.class) { -// conversionProcessor = new PrimitiveShortConversionProcessor(); -// } else if (clazz == Integer.class) { -// conversionProcessor = new IntegerConversionProcessor(); -// } else if (clazz == int.class) { -// conversionProcessor = new PrimitiveConversionProcessor(); -// } else if (clazz == Long.class) { -// conversionProcessor = new LongConversionProcessor(); -// } else if (clazz == long.class) { -// conversionProcessor = new PrimitiveConversionProcessor(); -// } else if (clazz == Float.class) { -// conversionProcessor = new FloatConversionProcessor(); -// } else if (clazz == float.class) { -// conversionProcessor = new PrimitiveConversionProcessor(); -// } else if (clazz == Double.class) { -// conversionProcessor = new DoubleConversionProcessor(); -// } else if (clazz == double.class) { -// conversionProcessor = new PrimitiveConversionProcessor(); -// } else if (clazz == Character.class) { -// conversionProcessor = new CharacterConversionProcessor(); -// } else if (clazz == char.class) { -// conversionProcessor = new PrimitiveConversionProcessor(); + } else if (clazz == Short.class) { + conversionProcessor = new ShortConversionProcessor(); + } else if (clazz == Integer.class) { + conversionProcessor = new IntegerConversionProcessor(); + } else if (clazz == Long.class) { + conversionProcessor = new LongConversionProcessor(); + } else if (clazz == Float.class) { + conversionProcessor = new FloatConversionProcessor(); + } else if (clazz == Double.class) { + conversionProcessor = new DoubleConversionProcessor(); + } else if (clazz == Character.class) { + conversionProcessor = new CharacterConversionProcessor(); + } else if (clazz == String.class) { + conversionProcessor = new StringConversionProcessor(); + } // } else if (clazz == Boolean.class) { // conversionProcessor = new BooleanConversionProcessor(); -// } else if (clazz == boolean.class) { -// conversionProcessor = new PrimitiveConversionProcessor(); -// } else if (clazz == String.class) { -// conversionProcessor = new StringConversionProcessor(); - } +// } return conversionProcessor; } } \ No newline at end of file diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index cf1761342..47acbc71a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -24,7 +24,7 @@ /** * Provides all method for converting any primitive type to a {@link Byte}. */ -public final class ByteConversionProcessor extends ConversionProcessor { +public final class ByteConversionProcessor implements ConversionProcessor { @Override public Function convertByte() { @@ -36,7 +36,7 @@ public Function convertByte() { */ @Override public Function convertShort() { - return val -> valueOf(val.byteValue()); + return Short::byteValue; } /** @@ -44,7 +44,7 @@ public Function convertShort() { */ @Override public Function convertInteger() { - return val -> valueOf(val.byteValue()); + return Integer::byteValue; } /** @@ -52,7 +52,7 @@ public Function convertInteger() { */ @Override public Function convertLong() { - return val -> valueOf(val.byteValue()); + return Long::byteValue; } /** @@ -60,7 +60,7 @@ public Function convertLong() { */ @Override public Function convertFloat() { - return val -> valueOf(val.byteValue()); + return Float::byteValue; } /** @@ -68,7 +68,7 @@ public Function convertFloat() { */ @Override public Function convertDouble() { - return val -> valueOf(val.byteValue()); + return Double::byteValue; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java new file mode 100644 index 000000000..586d9cdb2 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -0,0 +1,99 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a {@link Character}. + */ +public final class CharacterConversionProcessor implements ConversionProcessor { + + /** + * {@inheritDoc} + */ + @Override + public Function convertByte() { + return val -> val.toString().charAt(0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return val -> val.toString().charAt(0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return val -> val.toString().charAt(0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return val -> val.toString().charAt(0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return val -> val.toString().charAt(0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return val -> val.toString().charAt(0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> val.toString().charAt(0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return val -> val.charAt(0); + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java new file mode 100644 index 000000000..abaa20b1a --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -0,0 +1,84 @@ +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Double.valueOf; + +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a {@link Double}. + */ +public class DoubleConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertByte() { + return Byte::doubleValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return Short::doubleValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return Integer::doubleValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return Long::doubleValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return Float::doubleValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return Double::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> valueOf(val ? (double) 1 : (double) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Double::valueOf; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java new file mode 100644 index 000000000..57ec0685c --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -0,0 +1,85 @@ +package com.hotels.beans.conversion.processor.impl; + + +import static java.lang.Float.valueOf; + +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a {@link Float}. + */ +public class FloatConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertByte() { + return Float::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return Short::floatValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return Integer::floatValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return Long::floatValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return Double::floatValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> valueOf((float) val); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> valueOf(val ? (float) 1 : (float) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Float::valueOf; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index ddf1559b4..b59977110 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -24,11 +24,11 @@ /** * Provides all method for converting any primitive type to a {@link Integer}. */ -public final class IntegerConversionProcessor extends ConversionProcessor { +public final class IntegerConversionProcessor implements ConversionProcessor { @Override public Function convertByte() { - return Integer::valueOf; + return Byte::intValue; } /** @@ -36,7 +36,7 @@ public Function convertByte() { */ @Override public Function convertShort() { - return Integer::valueOf; + return Short::intValue; } /** @@ -52,7 +52,7 @@ public Function convertInteger() { */ @Override public Function convertLong() { - return val -> valueOf(val.intValue()); + return Long::intValue; } /** @@ -60,7 +60,7 @@ public Function convertLong() { */ @Override public Function convertFloat() { - return val -> valueOf(val.intValue()); + return Float::intValue; } /** @@ -68,7 +68,7 @@ public Function convertFloat() { */ @Override public Function convertDouble() { - return val -> valueOf(val.intValue()); + return Double::intValue; } /** @@ -76,7 +76,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return Integer::valueOf; + return val -> valueOf((int) val); } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index 2da061c42..ccce93c07 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -24,14 +24,14 @@ /** * Provides all method for converting any primitive type to a {@link Long}. */ -public final class LongConversionProcessor extends ConversionProcessor { +public final class LongConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} */ @Override public Function convertByte() { - return Long::valueOf; + return Byte::longValue; } /** @@ -47,7 +47,7 @@ public Function convertShort() { */ @Override public Function convertInteger() { - return val -> valueOf(val.longValue()); + return Integer::longValue; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveConversionProcessor.java deleted file mode 100644 index fe7198e58..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/PrimitiveConversionProcessor.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.hotels.beans.conversion.processor.impl; - -import java.util.function.ToDoubleFunction; -import java.util.function.ToIntFunction; -import java.util.function.ToLongFunction; - -import com.hotels.beans.conversion.function.ToBooleanFunction; -import com.hotels.beans.conversion.function.ToByteFunction; -import com.hotels.beans.conversion.function.ToCharFunction; -import com.hotels.beans.conversion.function.ToFloatFunction; -import com.hotels.beans.conversion.function.ToShortFunction; -import com.hotels.beans.conversion.processor.ConversionProcessor; - -public class PrimitiveConversionProcessor extends ConversionProcessor { - - @Override - public ToByteFunction convertPrimitiveByte() { - return super.convertPrimitiveByte(); - } - - @Override - public ToShortFunction convertPrimitiveShort() { - return super.convertPrimitiveShort(); - } - - @Override - public ToIntFunction convertPrimitiveInt() { - return super.convertPrimitiveInt(); - } - - @Override - public ToLongFunction convertPrimitiveLong() { - return super.convertPrimitiveLong(); - } - - @Override - public ToFloatFunction convertPrimitiveFloat() { - return super.convertPrimitiveFloat(); - } - - @Override - public ToDoubleFunction convertPrimitiveDouble() { - return super.convertPrimitiveDouble(); - } - - @Override - public ToCharFunction convertPrimitiveChar() { - return super.convertPrimitiveChar(); - } - - @Override - public ToBooleanFunction convertPrimitiveBoolean() { - return super.convertPrimitiveBoolean(); - } -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index a88ce0a66..7941008cd 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -24,11 +24,11 @@ /** * Provides all method for converting any primitive type to a {@link Short}. */ -public final class ShortConversionProcessor extends ConversionProcessor { +public final class ShortConversionProcessor implements ConversionProcessor { @Override public Function convertByte() { - return Short::valueOf; + return Byte::shortValue; } /** @@ -44,7 +44,7 @@ public Function convertShort() { */ @Override public Function convertInteger() { - return val -> valueOf(val.shortValue()); + return Integer::shortValue; } /** @@ -52,7 +52,7 @@ public Function convertInteger() { */ @Override public Function convertLong() { - return val -> valueOf(val.shortValue()); + return Long::shortValue; } /** @@ -60,7 +60,7 @@ public Function convertLong() { */ @Override public Function convertFloat() { - return val -> valueOf(val.shortValue()); + return Float::shortValue; } /** @@ -68,7 +68,7 @@ public Function convertFloat() { */ @Override public Function convertDouble() { - return val -> valueOf(val.shortValue()); + return Double::shortValue; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index bdca58d55..91be53248 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -23,13 +23,13 @@ /** * Provides all method for converting any primitive type to a {@link String}. */ -public final class StringConversionProcessor extends ConversionProcessor { +public final class StringConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} */ @Override - public Function convertByte() { + public Function convertByte() { return Object::toString; } From 2742c7ec3ede2fc123da8972103496b6ee0630d0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 18:05:25 +0200 Subject: [PATCH 0662/1786] git restored jacoco config --- pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 44dca9e8c..a64a9b192 100644 --- a/pom.xml +++ b/pom.xml @@ -45,12 +45,12 @@ 2.2.6 0.8.2 - 0.9 - 0.9 - 0.9 - 0.9 - 0.9 - 0.9 + 0.85 + 0.85 + 0.85 + 0.85 + 0.85 + 0.85 3.3.3 0.12 From 2fdfe66cca44dcf04838c638eeb22fa618a9e658 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 18:06:54 +0200 Subject: [PATCH 0663/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 42ca9a987..5989e4284 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.6-SNAPSHOT + 1.4.7-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 385b26ea5..f576694b3 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.6-SNAPSHOT + 1.4.7-SNAPSHOT diff --git a/pom.xml b/pom.xml index a64a9b192..40da66207 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.6-SNAPSHOT + 1.4.7-SNAPSHOT pom 2019 From b276714cce42ba01c2492342c2eb85074f0e0f39 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 19:17:55 +0200 Subject: [PATCH 0664/1786] preparing release --- .travis.yml | 2 +- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ec067c0da..df568e821 100755 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dmaven.test.skip=true site:site javadoc:aggregate -P site-release + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release deploy: provider: pages local-dir: target/site diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 5989e4284..42ca9a987 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7-SNAPSHOT + 1.4.6-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f576694b3..385b26ea5 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7-SNAPSHOT + 1.4.6-SNAPSHOT diff --git a/pom.xml b/pom.xml index 40da66207..a64a9b192 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.7-SNAPSHOT + 1.4.6-SNAPSHOT pom 2019 From a5d51f938f3e7d44f8c1634e27804dd986869027 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 19:20:40 +0200 Subject: [PATCH 0665/1786] [maven-release-plugin] prepare release 1.4.6 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 42ca9a987..c4544bd8c 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.6-SNAPSHOT + 1.4.6 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 385b26ea5..5fa845896 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.6-SNAPSHOT + 1.4.6 diff --git a/pom.xml b/pom.xml index a64a9b192..25343e24a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.6-SNAPSHOT + 1.4.6 pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.6 From 84a142a8bb16667057b510252cc30b9b5592333e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Jun 2019 19:20:47 +0200 Subject: [PATCH 0666/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index c4544bd8c..5989e4284 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.6 + 1.4.7-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 5fa845896..f576694b3 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.6 + 1.4.7-SNAPSHOT diff --git a/pom.xml b/pom.xml index 25343e24a..40da66207 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.6 + 1.4.7-SNAPSHOT pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.6 + HEAD From e98d4d50ae4aaf79e61a293ceea507c40348c424 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 28 Jun 2019 09:40:32 +0200 Subject: [PATCH 0667/1786] Added boolean conversion processor --- .../analyzer/ConversionAnalyzer.java | 11 ++- .../processor/ConversionProcessorFactory.java | 6 +- .../impl/BooleanConversionProcessor.java | 81 +++++++++++++++++++ 3 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 000e20e5b..5cabfc6c7 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -90,7 +90,7 @@ public Optional getConversionFunction(final Class sourceFieldType, fin private Optional getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional conversionFunction = getPrimitiveTypeConversionFunction(conversionProcessor, sourceFieldType); + Optional conversionFunction = getTypeConversionFunction(conversionProcessor, sourceFieldType); CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); return conversionFunction; }); @@ -103,7 +103,7 @@ private Optional getConversionFunction(final ConversionProcessor conversionProce * @param sourceFieldType he source field class * @return the conversion function */ - private Optional getPrimitiveTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + private Optional getTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { final Optional conversionFunction; if (sourceFieldType == String.class) { conversionFunction = of(conversionProcessor.convertString()); @@ -121,10 +121,9 @@ private Optional getPrimitiveTypeConversionFunction(final ConversionProcessor co conversionFunction = of(conversionProcessor.convertDouble()); } else if (sourceFieldType == Character.class) { conversionFunction = of(conversionProcessor.convertCharacter()); - } //else if (sourceFieldType == Boolean.class) { -// conversionFunction = of(conversionProcessor.convertBoolean()); -// } - else { + } else if (sourceFieldType == Boolean.class) { + conversionFunction = of(conversionProcessor.convertBoolean()); + } else { conversionFunction = empty(); } return conversionFunction; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index 115962a37..f4920d930 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -18,6 +18,7 @@ import static lombok.AccessLevel.PRIVATE; +import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; @@ -57,10 +58,9 @@ public static ConversionProcessor getConversionProcessor(final Class clazz) { conversionProcessor = new CharacterConversionProcessor(); } else if (clazz == String.class) { conversionProcessor = new StringConversionProcessor(); + } else if (clazz == Boolean.class) { + conversionProcessor = new BooleanConversionProcessor(); } -// } else if (clazz == Boolean.class) { -// conversionProcessor = new BooleanConversionProcessor(); -// } return conversionProcessor; } } \ No newline at end of file diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java new file mode 100644 index 000000000..dc4ada41f --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -0,0 +1,81 @@ +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Byte.valueOf; + +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a {@link Boolean}. + */ +public class BooleanConversionProcessor implements ConversionProcessor { + @Override + public Function convertByte() { + return val -> val != 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return val -> val != 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return val -> val != 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return val -> val != 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return val -> val != 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return val -> val != 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> val == 'T'; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Boolean::valueOf; + } +} From e987f8e720fd02b6608b2288fca647ad08071738 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 28 Jun 2019 09:41:36 +0200 Subject: [PATCH 0668/1786] Updated parent pom version --- bull-converter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 891353ce4..0c3c3a0dd 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -11,7 +11,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.6-SNAPSHOT + 1.4.7-SNAPSHOT From a9ecbae50519cefb5c7f142b5489284f05c08e8f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 28 Jun 2019 09:45:02 +0200 Subject: [PATCH 0669/1786] Fixed checkstyles --- .../hotels/beans/conversion/analyzer/ConversionAnalyzer.java | 1 + .../hotels/beans/conversion/function/ToBooleanFunction.java | 1 + .../com/hotels/beans/conversion/function/ToByteFunction.java | 1 + .../com/hotels/beans/conversion/function/ToCharFunction.java | 1 + .../com/hotels/beans/conversion/function/ToFloatFunction.java | 1 + .../com/hotels/beans/conversion/function/ToShortFunction.java | 1 + .../conversion/processor/impl/BooleanConversionProcessor.java | 4 +--- 7 files changed, 7 insertions(+), 3 deletions(-) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 5cabfc6c7..b4c7a582a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -65,6 +65,7 @@ public Optional getConversionFunction(final Class sourceFieldType, final Clas * @param destinationFieldType the destination field class * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @return an {@link Optional} containing the conversion function (if exists) + * @param the conversion function type */ @SuppressWarnings("unchecked") public Optional getConversionFunction(final Class sourceFieldType, final Class destinationFieldType, diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java index 8255f0c3a..5c919dd49 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion.function; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java index a73e58f76..89e4e3d2e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion.function; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java index 58f87c85d..e1fb54e5e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion.function; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java index a5bbb2cb9..2b21b26dc 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion.function; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java index f4ca99f1f..17b14a023 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion.function; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java index dc4ada41f..446caca50 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -1,7 +1,5 @@ package com.hotels.beans.conversion.processor.impl; -import static java.lang.Byte.valueOf; - import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -9,7 +7,7 @@ /** * Provides all method for converting any primitive type to a {@link Boolean}. */ -public class BooleanConversionProcessor implements ConversionProcessor { +public final class BooleanConversionProcessor implements ConversionProcessor { @Override public Function convertByte() { return val -> val != 0; From 77b334f2ea1ac9b5936c6327ed66ce6ed3fb9832 Mon Sep 17 00:00:00 2001 From: amarsiglia Date: Fri, 28 Jun 2019 17:57:17 +0200 Subject: [PATCH 0670/1786] Some improvement on the ConversionAnalyser class. Fixed checkstyle errors + removed unused functional interfaces --- .../com/hotels/beans/utils/ClassUtils.java | 9 ++++ .../analyzer/ConversionAnalyzer.java | 41 +++++++++++------- .../function/ToBooleanFunction.java | 43 ------------------- .../conversion/function/ToByteFunction.java | 43 ------------------- .../conversion/function/ToCharFunction.java | 43 ------------------- .../conversion/function/ToFloatFunction.java | 43 ------------------- .../conversion/function/ToShortFunction.java | 43 ------------------- .../processor/ConversionProcessorFactory.java | 30 ++++++++----- .../impl/BooleanConversionProcessor.java | 18 +++++++- .../impl/ByteConversionProcessor.java | 4 ++ .../impl/DoubleConversionProcessor.java | 18 +++++++- .../impl/FloatConversionProcessor.java | 19 +++++++- .../impl/IntegerConversionProcessor.java | 1 + .../impl/LongConversionProcessor.java | 1 + .../impl/ShortConversionProcessor.java | 1 + .../processor/impl/package-info.java | 20 +++++++++ 16 files changed, 132 insertions(+), 245 deletions(-) delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java delete mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java index 02a6026fb..decb18ba7 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -237,6 +237,15 @@ public static boolean isBoolean(final Class type) { return Boolean.class.isAssignableFrom(type) || type == boolean.class; } + /** + * Checks if the given type is a String. + * @param type the class to check + * @return true if is String + */ + public static boolean isString(final Class type) { + return String.class.isAssignableFrom(type); + } + /** * Return the private final fields of a class. * @param clazz class from which gets the field diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index b4c7a582a..278af1b5a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -21,8 +21,18 @@ import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.conversion.processor.ConversionProcessorFactory.getConversionProcessor; +import static com.hotels.beans.utils.ClassUtils.isBoolean; +import static com.hotels.beans.utils.ClassUtils.isByte; +import static com.hotels.beans.utils.ClassUtils.isChar; +import static com.hotels.beans.utils.ClassUtils.isDouble; +import static com.hotels.beans.utils.ClassUtils.isFloat; +import static com.hotels.beans.utils.ClassUtils.isInt; +import static com.hotels.beans.utils.ClassUtils.isLong; +import static com.hotels.beans.utils.ClassUtils.isShort; +import static com.hotels.beans.utils.ClassUtils.isString; import java.util.Optional; +import java.util.function.Function; import com.hotels.beans.cache.CacheManager; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -55,7 +65,7 @@ public ConversionAnalyzer() { * @param destinationFieldType the destination field class * @return an {@link Optional} containing the conversion function (if exists) */ - public Optional getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { + public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { return getConversionFunction(sourceFieldType, destinationFieldType, classUtils.isPrimitiveType(destinationFieldType)); } @@ -65,14 +75,13 @@ public Optional getConversionFunction(final Class sourceFieldType, final Clas * @param destinationFieldType the destination field class * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @return an {@link Optional} containing the conversion function (if exists) - * @param the conversion function type */ @SuppressWarnings("unchecked") - public Optional getConversionFunction(final Class sourceFieldType, final Class destinationFieldType, + public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType, final boolean isDestinationFieldPrimitiveType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional conversionFunction = empty(); + Optional> conversionFunction = empty(); if (destinationFieldType != sourceFieldType && isDestinationFieldPrimitiveType && classUtils.isPrimitiveType(sourceFieldType)) { conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); } @@ -88,7 +97,7 @@ public Optional getConversionFunction(final Class sourceFieldType, fin * @return the conversion function */ @SuppressWarnings("unchecked") - private Optional getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional conversionFunction = getTypeConversionFunction(conversionProcessor, sourceFieldType); @@ -104,25 +113,25 @@ private Optional getConversionFunction(final ConversionProcessor conversionProce * @param sourceFieldType he source field class * @return the conversion function */ - private Optional getTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { - final Optional conversionFunction; - if (sourceFieldType == String.class) { + private Optional> getTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { + final Optional> conversionFunction; + if (isString(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertString()); - } else if (sourceFieldType == Byte.class) { + } else if (isByte(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertByte()); - } else if (sourceFieldType == Short.class) { + } else if (isShort(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertShort()); - } else if (sourceFieldType == Integer.class) { + } else if (isInt(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertInteger()); - } else if (sourceFieldType == Long.class) { + } else if (isLong(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertLong()); - } else if (sourceFieldType == Float.class) { + } else if (isFloat(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertFloat()); - } else if (sourceFieldType == Double.class) { + } else if (isDouble(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertDouble()); - } else if (sourceFieldType == Character.class) { + } else if (isChar(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertCharacter()); - } else if (sourceFieldType == Boolean.class) { + } else if (isBoolean(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertBoolean()); } else { conversionFunction = empty(); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java deleted file mode 100644 index 5c919dd49..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToBooleanFunction.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion.function; - -import java.util.function.Function; - -/** - * Represents a function that produces a double-valued result. This is the - * {@code boolean}-producing primitive specialization for {@link Function}. - * - *

      This is a functional interface - * whose functional method is {@link #applyAsBoolean(Object)}. - * - * @param the type of the input to the function - * - * @see Function - * @since 1.8 - */ -@FunctionalInterface -public interface ToBooleanFunction { - - /** - * Applies this function to the given argument. - * - * @param value the function argument - * @return the function result - */ - boolean applyAsBoolean(T value); -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java deleted file mode 100644 index 89e4e3d2e..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToByteFunction.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion.function; - -import java.util.function.Function; - -/** - * Represents a function that produces a double-valued result. This is the - * {@code byte}-producing primitive specialization for {@link Function}. - * - *

      This is a functional interface - * whose functional method is {@link #applyAsByte(Object)}. - * - * @param the type of the input to the function - * - * @see Function - * @since 1.8 - */ -@FunctionalInterface -public interface ToByteFunction { - - /** - * Applies this function to the given argument. - * - * @param value the function argument - * @return the function result - */ - byte applyAsByte(T value); -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java deleted file mode 100644 index e1fb54e5e..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToCharFunction.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion.function; - -import java.util.function.Function; - -/** - * Represents a function that produces a double-valued result. This is the - * {@code char}-producing primitive specialization for {@link Function}. - * - *

      This is a functional interface - * whose functional method is {@link #applyAsChar(Object)}. - * - * @param the type of the input to the function - * - * @see Function - * @since 1.8 - */ -@FunctionalInterface -public interface ToCharFunction { - - /** - * Applies this function to the given argument. - * - * @param value the function argument - * @return the function result - */ - char applyAsChar(T value); -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java deleted file mode 100644 index 2b21b26dc..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToFloatFunction.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion.function; - -import java.util.function.Function; - -/** - * Represents a function that produces a double-valued result. This is the - * {@code float}-producing primitive specialization for {@link Function}. - * - *

      This is a functional interface - * whose functional method is {@link #applyAsFloat(Object)}. - * - * @param the type of the input to the function - * - * @see Function - * @since 1.8 - */ -@FunctionalInterface -public interface ToFloatFunction { - - /** - * Applies this function to the given argument. - * - * @param value the function argument - * @return the function result - */ - float applyAsFloat(T value); -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java b/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java deleted file mode 100644 index 17b14a023..000000000 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/function/ToShortFunction.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion.function; - -import java.util.function.Function; - -/** - * Represents a function that produces a double-valued result. This is the - * {@code short}-producing primitive specialization for {@link Function}. - * - *

      This is a functional interface - * whose functional method is {@link #applyAsShort(Object)}. - * - * @param the type of the input to the function - * - * @see Function - * @since 1.8 - */ -@FunctionalInterface -public interface ToShortFunction { - - /** - * Applies this function to the given argument. - * - * @param value the function argument - * @return the function result - */ - short applyAsShort(T value); -} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index f4920d930..5043139da 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -16,6 +16,16 @@ package com.hotels.beans.conversion.processor; +import static com.hotels.beans.utils.ClassUtils.isBoolean; +import static com.hotels.beans.utils.ClassUtils.isByte; +import static com.hotels.beans.utils.ClassUtils.isChar; +import static com.hotels.beans.utils.ClassUtils.isDouble; +import static com.hotels.beans.utils.ClassUtils.isFloat; +import static com.hotels.beans.utils.ClassUtils.isInt; +import static com.hotels.beans.utils.ClassUtils.isLong; +import static com.hotels.beans.utils.ClassUtils.isShort; +import static com.hotels.beans.utils.ClassUtils.isString; + import static lombok.AccessLevel.PRIVATE; import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; @@ -42,25 +52,25 @@ public final class ConversionProcessorFactory { */ public static ConversionProcessor getConversionProcessor(final Class clazz) { ConversionProcessor conversionProcessor = null; - if (clazz == Byte.class) { + if (isByte(clazz)) { conversionProcessor = new ByteConversionProcessor(); - } else if (clazz == Short.class) { + } else if (isShort(clazz)) { conversionProcessor = new ShortConversionProcessor(); - } else if (clazz == Integer.class) { + } else if (isInt(clazz)) { conversionProcessor = new IntegerConversionProcessor(); - } else if (clazz == Long.class) { + } else if (isLong(clazz)) { conversionProcessor = new LongConversionProcessor(); - } else if (clazz == Float.class) { + } else if (isFloat(clazz)) { conversionProcessor = new FloatConversionProcessor(); - } else if (clazz == Double.class) { + } else if (isDouble(clazz)) { conversionProcessor = new DoubleConversionProcessor(); - } else if (clazz == Character.class) { + } else if (isChar(clazz)) { conversionProcessor = new CharacterConversionProcessor(); - } else if (clazz == String.class) { + } else if (isString(clazz)) { conversionProcessor = new StringConversionProcessor(); - } else if (clazz == Boolean.class) { + } else if (isBoolean(clazz)) { conversionProcessor = new BooleanConversionProcessor(); } return conversionProcessor; } -} \ No newline at end of file +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java index 446caca50..1d99ea782 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -1,3 +1,19 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hotels.beans.conversion.processor.impl; import java.util.function.Function; @@ -58,7 +74,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return val -> val == 'T'; + return Character::isLetter; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index 47acbc71a..b931a5b45 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion.processor.impl; import static java.lang.Byte.valueOf; @@ -26,6 +27,9 @@ */ public final class ByteConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ @Override public Function convertByte() { return val -> val; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index abaa20b1a..a013595c6 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -1,3 +1,19 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hotels.beans.conversion.processor.impl; import static java.lang.Double.valueOf; @@ -9,7 +25,7 @@ /** * Provides all method for converting any primitive type to a {@link Double}. */ -public class DoubleConversionProcessor implements ConversionProcessor { +public final class DoubleConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index 57ec0685c..e71698ee2 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -1,5 +1,20 @@ -package com.hotels.beans.conversion.processor.impl; +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.hotels.beans.conversion.processor.impl; import static java.lang.Float.valueOf; @@ -10,7 +25,7 @@ /** * Provides all method for converting any primitive type to a {@link Float}. */ -public class FloatConversionProcessor implements ConversionProcessor { +public final class FloatConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index b59977110..eebadb929 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion.processor.impl; import static java.lang.Integer.valueOf; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index ccce93c07..4a71d235f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion.processor.impl; import static java.lang.Long.valueOf; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index 7941008cd..ed2b57171 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion.processor.impl; import static java.lang.Short.valueOf; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java new file mode 100644 index 000000000..5d5dfccd4 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Implementations of processors package. + */ +package com.hotels.beans.conversion.processor.impl; From 13f99916f06c2e6d54dca526f60e1cd5274251b2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 2 Jul 2019 12:11:10 +0200 Subject: [PATCH 0671/1786] Fixed problem that was preventing the automatic trasformation --- .../beans/populator/ArrayPopulator.java | 2 +- .../beans/transformer/TransformerImpl.java | 10 +++--- .../com/hotels/beans/utils/ClassUtils.java | 24 +++++++------- .../hotels/beans/utils/ClassUtilsTest.java | 32 +++++++++---------- .../analyzer/ConversionAnalyzer.java | 16 ++-------- 5 files changed, 37 insertions(+), 47 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index b74045d15..5ea3e38fb 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -49,7 +49,7 @@ public Object getPopulatedObject(final Field field, final Object fieldValue) { @Override public Object getPopulatedObject(final Class fieldType, final Class genericFieldType, final Object fieldValue, final Class nestedGenericClass) { final Object res; - if (classUtils.isPrimitiveTypeArray(fieldValue) || classUtils.isPrimitiveOrSpecialType(genericFieldType)) { + if (classUtils.isPrimitiveTypeArray(fieldValue.getClass()) || classUtils.isPrimitiveOrSpecialType(genericFieldType)) { res = fieldValue; } else { res = stream((Object[]) fieldValue) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 746f87d19..50fb542d8 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -312,8 +312,8 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN if (doSkipTransformation(fieldBreadcrumb)) { return defaultValue(fieldType); } - boolean primitiveType = classUtils.isPrimitiveType(fieldType); - List transformerFunction = getTransformerFunction(sourceObj.getClass(), field, primitiveType, fieldBreadcrumb); + boolean primitiveType = classUtils.isPrimitiveType(fieldType) || classUtils.isPrimitiveTypeArray(fieldType); + List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType, fieldBreadcrumb); boolean isTransformerFunctionDefined = !transformerFunction.isEmpty(); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { @@ -391,16 +391,18 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie * Retrieves the transformer function. If the field type is different and they are primitive * a conversion function is automatically added. * @param sourceObjectClass the source object class + * @param sourceFieldName the source field name * @param field The field on which the transformation should be applied. * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @param breadcrumb The full field path on which the transformation should be applied. * @return the transformer function. */ - private List getTransformerFunction(final Class sourceObjectClass, final Field field, + private List getTransformerFunction(final Class sourceObjectClass, final String sourceFieldName, final Field field, final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { List fieldTransformers = new ArrayList<>(); if (isDestinationFieldPrimitiveType) { - conversionAnalyzer.getConversionFunction(sourceObjectClass, field.getType(), isDestinationFieldPrimitiveType) + Class sourceFieldType = reflectionUtils.getDeclaredField(sourceFieldName, sourceObjectClass).getType(); + conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(field.getName(), conversionFunction))); } ofNullable(settings.getFieldsTransformers().get(settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb)) diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java index decb18ba7..4677edbbd 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -137,13 +137,13 @@ public boolean isPrimitiveType(final Class clazz) { /** * Checks if an object is a primitive type array. - * @param object the object to check + * @param clazz the class to check * @return true if is primitive type array, false otherwise */ - public boolean isPrimitiveTypeArray(final Object object) { - final String cacheKey = "isPrimitiveTypeArray-" + object.getClass().getName(); + public boolean isPrimitiveTypeArray(final Class clazz) { + final String cacheKey = "isPrimitiveTypeArray-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = isPrimitiveType(object.getClass().getComponentType()); + final Boolean res = isPrimitiveType(clazz.getComponentType()); CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); @@ -171,7 +171,7 @@ public boolean isSpecialType(final Class clazz) { * @return true if is Double */ public static boolean isDouble(final Class type) { - return Double.class.isAssignableFrom(type) || type == double.class; + return Double.class.isAssignableFrom(type) || type == double.class || type == double[].class; } /** @@ -180,7 +180,7 @@ public static boolean isDouble(final Class type) { * @return true if is Float */ public static boolean isFloat(final Class type) { - return Float.class.isAssignableFrom(type) || type == float.class; + return Float.class.isAssignableFrom(type) || type == float.class|| type == float[].class; } /** @@ -189,7 +189,7 @@ public static boolean isFloat(final Class type) { * @return true if is Long */ public static boolean isLong(final Class type) { - return Long.class.isAssignableFrom(type) || type == long.class; + return Long.class.isAssignableFrom(type) || type == long.class || type == long[].class; } /** @@ -198,7 +198,7 @@ public static boolean isLong(final Class type) { * @return true if is Short */ public static boolean isShort(final Class type) { - return Short.class.isAssignableFrom(type) || type == short.class; + return Short.class.isAssignableFrom(type) || type == short.class|| type == short[].class; } /** @@ -207,7 +207,7 @@ public static boolean isShort(final Class type) { * @return true if is Integer */ public static boolean isInt(final Class type) { - return Integer.class.isAssignableFrom(type) || type == int.class; + return Integer.class.isAssignableFrom(type) || type == int.class || type == int[].class; } /** @@ -216,7 +216,7 @@ public static boolean isInt(final Class type) { * @return true if is Byte */ public static boolean isByte(final Class type) { - return Byte.class.isAssignableFrom(type) || type == byte.class; + return Byte.class.isAssignableFrom(type) || type == byte.class || type == byte[].class; } /** @@ -225,7 +225,7 @@ public static boolean isByte(final Class type) { * @return true if is Character */ public static boolean isChar(final Class type) { - return Character.class.isAssignableFrom(type) || type == char.class; + return Character.class.isAssignableFrom(type) || type == char.class || type == char[].class; } /** @@ -234,7 +234,7 @@ public static boolean isChar(final Class type) { * @return true if is Boolean */ public static boolean isBoolean(final Class type) { - return Boolean.class.isAssignableFrom(type) || type == boolean.class; + return Boolean.class.isAssignableFrom(type) || type == boolean.class || type == int[].class; } /** diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index f4beef3a0..c48189639 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -215,7 +215,7 @@ public void testIsPrimitiveArrayTypeWorksAsExpected(final String testCaseDescrip // GIVEN // WHEN - boolean actual = underTest.isPrimitiveTypeArray(testArray); + boolean actual = underTest.isPrimitiveTypeArray(testArray.getClass()); // THEN assertEquals(expectedResult, actual); @@ -267,7 +267,7 @@ private Object[][] dataGetPrivateFinalFieldsTesting() { {"Tests that the method returns 0 if the given class has no private final fields", CLASS_WITHOUT_PRIVATE_FINAL_FIELDS, ZERO}, {"Tests that the method returns the expected value if the class has private final fields", CLASS_WITH_PRIVATE_FINAL_FIELDS, EXPECTED_PRIVATE_FINAL_FIELDS}, {"Tests that the method returns the expected value if the class has private final fields and extends another class", - CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS, EXPECTED_SUB_CLASS_PRIVATE_FIELDS} + CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS, EXPECTED_SUB_CLASS_PRIVATE_FIELDS} }; } @@ -297,7 +297,7 @@ private Object[][] dataGetNotFinalFieldsTesting() { return new Object[][] { {"Tests that the method returns 0 if the given class has only private fields", CLASS_WITH_PRIVATE_FINAL_FIELDS, ZERO}, {"Tests that the method returns the expected value if the class has private final fields", - CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, EXPECTED_MIXED_CLASS_TOTAL_NOT_FINAL_FIELDS} + CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, EXPECTED_MIXED_CLASS_TOTAL_NOT_FINAL_FIELDS} }; } @@ -328,7 +328,7 @@ private Object[][] dataGetTotalFieldsTesting() { return new Object[][] { {"Tests that the method returns 0 if the given class has no private final fields", CLASS_WITHOUT_PRIVATE_FINAL_FIELDS, IS_FINAL_FIELD_PREDICATE, ZERO}, {"Tests that the method returns the expected value if the class has private final fields", CLASS_WITH_PRIVATE_FINAL_FIELDS, IS_FINAL_FIELD_PREDICATE, - EXPECTED_PRIVATE_FINAL_FIELDS} + EXPECTED_PRIVATE_FINAL_FIELDS} }; } @@ -358,19 +358,19 @@ public void testGetPrivateFieldsWorksAsExpected(final String testCaseDescription private Object[][] dataGetPrivateFieldsTesting() { return new Object[][] { {"Tests that the method returns the expected value if the class has private and public fields", CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, false, - EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS}, + EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS}, {"Tests that the method returns the expected value if the class has private and public fields and skipFinal is not passed as param", - CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, null, EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS}, + CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, null, EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_FIELDS}, {"Tests that the method returns the expected value if the class has private final fields only", CLASS_WITH_PRIVATE_FINAL_FIELDS, false, - EXPECTED_PRIVATE_FINAL_FIELDS}, + EXPECTED_PRIVATE_FINAL_FIELDS}, {"Tests that the method returns the expected value if the class has private final fields only and skipFinal is not passed as param", - CLASS_WITH_PRIVATE_FINAL_FIELDS, null, EXPECTED_PRIVATE_FINAL_FIELDS}, + CLASS_WITH_PRIVATE_FINAL_FIELDS, null, EXPECTED_PRIVATE_FINAL_FIELDS}, {"Tests that the method returns the expected value if the class extends another class", ImmutableToFooSubClass.class, false, - EXPECTED_SUB_CLASS_PRIVATE_FIELDS}, + EXPECTED_SUB_CLASS_PRIVATE_FIELDS}, {"Tests that the method returns the expected value if the class extends another class and skipFinal is not passed as param", - ImmutableToFooSubClass.class, null, EXPECTED_SUB_CLASS_PRIVATE_FIELDS}, + ImmutableToFooSubClass.class, null, EXPECTED_SUB_CLASS_PRIVATE_FIELDS}, {"Tests that the method returns the expected value if the skipFinal is enabled", CLASS_WITH_PRIVATE_AND_PUBLIC_FIELDS, true, - EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_NOT_FINAL_FIELDS} + EXPECTED_MIXED_CLASS_TOTAL_PRIVATE_NOT_FINAL_FIELDS} }; } @@ -400,11 +400,11 @@ public void testGetDeclaredFieldsWorksAsExpected(final String testCaseDescriptio private Object[][] dataGetDeclaredFieldsTesting() { return new Object[][] { {"Tests that the method returns the expected total number of fields when the skipStatic param is true", CLASS_WITH_STATIC_FIELDS, true, - EXPECTED_NOT_STATIC_FIELDS}, + EXPECTED_NOT_STATIC_FIELDS}, {"Tests that the method returns the expected value if the class has private final fields only", CLASS_WITH_STATIC_FIELDS, false, - CLASS_WITH_STATIC_FIELDS.getDeclaredFields().length}, + CLASS_WITH_STATIC_FIELDS.getDeclaredFields().length}, {"Tests that the method returns the expected total number of fields when the skipStatic param is true and the class extends another class", - CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS, true, EXPECTED_SUB_CLASS_PRIVATE_FIELDS} + CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS, true, EXPECTED_SUB_CLASS_PRIVATE_FIELDS} }; } @@ -433,9 +433,9 @@ public void testGetDeclaredClassesWorksAsExpected(final String testCaseDescripti private Object[][] dataGetDeclaredClassesTesting() { return new Object[][] { {"Test that the a manual declared Builder is returned by method: {@code getDeclaredClasses}", MutableToFooWithBuilder.class, - MutableToFooWithBuilder.Builder.class}, + MutableToFooWithBuilder.Builder.class}, {"Test that the a Builder created by lombok is returned by method: {@code getDeclaredClasses}", MixedToFooWithBuilder.class, - MixedToFooWithBuilder.builder().getClass()} + MixedToFooWithBuilder.builder().getClass()} }; } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 278af1b5a..6d1580d7f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -65,24 +65,12 @@ public ConversionAnalyzer() { * @param destinationFieldType the destination field class * @return an {@link Optional} containing the conversion function (if exists) */ - public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { - return getConversionFunction(sourceFieldType, destinationFieldType, classUtils.isPrimitiveType(destinationFieldType)); - } - - /** - * Analyzes Fields given as input and returns the conversion processor. - * @param sourceFieldType source field class - * @param destinationFieldType the destination field class - * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not - * @return an {@link Optional} containing the conversion function (if exists) - */ @SuppressWarnings("unchecked") - public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType, - final boolean isDestinationFieldPrimitiveType) { + public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional> conversionFunction = empty(); - if (destinationFieldType != sourceFieldType && isDestinationFieldPrimitiveType && classUtils.isPrimitiveType(sourceFieldType)) { + if (destinationFieldType != sourceFieldType && classUtils.isPrimitiveType(sourceFieldType)) { conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); } CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); From fcb4bffe160dbedbca24b4ac3a41155239a613d6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 2 Jul 2019 14:06:11 +0200 Subject: [PATCH 0672/1786] Removed not working behaviour --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 50fb542d8..874b08491 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -312,8 +312,8 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN if (doSkipTransformation(fieldBreadcrumb)) { return defaultValue(fieldType); } - boolean primitiveType = classUtils.isPrimitiveType(fieldType) || classUtils.isPrimitiveTypeArray(fieldType); - List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType, fieldBreadcrumb); + boolean primitiveType = classUtils.isPrimitiveType(fieldType); + List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType || classUtils.isPrimitiveTypeArray(fieldType), fieldBreadcrumb); boolean isTransformerFunctionDefined = !transformerFunction.isEmpty(); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { From 81b41f1a434e27be313c165d913527b356ccc95a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 3 Jul 2019 10:46:55 +0200 Subject: [PATCH 0673/1786] Made test working --- .../beans/transformer/TransformerImpl.java | 3 ++- .../java/com/hotels/beans/utils/ClassUtils.java | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 874b08491..198b48f76 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -313,7 +313,8 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN return defaultValue(fieldType); } boolean primitiveType = classUtils.isPrimitiveType(fieldType); - List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType || classUtils.isPrimitiveTypeArray(fieldType), fieldBreadcrumb); +// List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType || classUtils.isPrimitiveTypeArray(fieldType), fieldBreadcrumb); + List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType, fieldBreadcrumb); boolean isTransformerFunctionDefined = !transformerFunction.isEmpty(); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java index 4677edbbd..d6f82a755 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -171,7 +171,7 @@ public boolean isSpecialType(final Class clazz) { * @return true if is Double */ public static boolean isDouble(final Class type) { - return Double.class.isAssignableFrom(type) || type == double.class || type == double[].class; + return Double.class.isAssignableFrom(type) || type == double.class; } /** @@ -180,7 +180,7 @@ public static boolean isDouble(final Class type) { * @return true if is Float */ public static boolean isFloat(final Class type) { - return Float.class.isAssignableFrom(type) || type == float.class|| type == float[].class; + return Float.class.isAssignableFrom(type) || type == float.class; } /** @@ -189,7 +189,7 @@ public static boolean isFloat(final Class type) { * @return true if is Long */ public static boolean isLong(final Class type) { - return Long.class.isAssignableFrom(type) || type == long.class || type == long[].class; + return Long.class.isAssignableFrom(type) || type == long.class; } /** @@ -198,7 +198,7 @@ public static boolean isLong(final Class type) { * @return true if is Short */ public static boolean isShort(final Class type) { - return Short.class.isAssignableFrom(type) || type == short.class|| type == short[].class; + return Short.class.isAssignableFrom(type) || type == short.class; } /** @@ -207,7 +207,7 @@ public static boolean isShort(final Class type) { * @return true if is Integer */ public static boolean isInt(final Class type) { - return Integer.class.isAssignableFrom(type) || type == int.class || type == int[].class; + return Integer.class.isAssignableFrom(type) || type == int.class; } /** @@ -216,7 +216,7 @@ public static boolean isInt(final Class type) { * @return true if is Byte */ public static boolean isByte(final Class type) { - return Byte.class.isAssignableFrom(type) || type == byte.class || type == byte[].class; + return Byte.class.isAssignableFrom(type) || type == byte.class; } /** @@ -225,7 +225,7 @@ public static boolean isByte(final Class type) { * @return true if is Character */ public static boolean isChar(final Class type) { - return Character.class.isAssignableFrom(type) || type == char.class || type == char[].class; + return Character.class.isAssignableFrom(type) || type == char.class; } /** @@ -234,7 +234,7 @@ public static boolean isChar(final Class type) { * @return true if is Boolean */ public static boolean isBoolean(final Class type) { - return Boolean.class.isAssignableFrom(type) || type == boolean.class || type == int[].class; + return Boolean.class.isAssignableFrom(type) || type == boolean.class; } /** From 9fc65ff79192db9a50098ae5e5c797d60c285968 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 3 Jul 2019 14:42:44 +0200 Subject: [PATCH 0674/1786] - Implemented a new method for disabling the automatic set - Test implementation - Updated documentation --- README.md | 27 +++++++++++++++++++ .../transformer/AbstractTransformer.java | 9 +++++++ .../hotels/beans/transformer/Transformer.java | 7 +++++ .../beans/transformer/TransformerImpl.java | 2 +- .../transformer/TransformerSettings.java | 7 +++++ .../MutableObjectTransformationTest.java | 17 ++++++++++++ docs/site/markdown/transformer/samples.md | 27 +++++++++++++++++++ 7 files changed, 95 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7183bffa5..a0001d08d 100644 --- a/README.md +++ b/README.md @@ -256,6 +256,33 @@ ToBean toBean = beanUtils.getTransformer() .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); ~~~ +### Disable the default value set for primitive types in case they are null: + +BULL by default sets the default value for all primitive types fields in case their value in the source object. +Given the following Java Bean: + +~~~Java +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final String name; + + // constructors... // constructors... + // getters... // getters and setters... + +} } +~~~ + +in case the field `id` in the `FromBean` object is `null`, the value assigned the correspondent field in the `ToBean` object will be `0`. +To disable this you can simply do: + +~~~Java +ToBean toBean = beanUtils.getTransformer() + .setDefaultValueSetEnabled(false).transform(fromBean, ToBean.class); +~~~ + +in this case the field `id` after the transformation will be `null` + ### Applying a transformation function in case of missing fields in the source object: Assign a default value in case of missing field in the source object: diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 5a2284283..184f1addb 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -157,6 +157,15 @@ public Transformer setValidationEnabled(final boolean validationEnabled) { return this; } + /** + * {@inheritDoc} + */ + @Override + public Transformer setDefaultValueSetEnabled(final boolean defaultValueSetEnabled) { + settings.setDefaultValueSetEnabled(defaultValueSetEnabled); + return this; + } + /** * {@inheritDoc} */ diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java index 56e2fa9df..4ec19aec7 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -117,4 +117,11 @@ public interface Transformer { * Removes all the configured fields to skip. */ void resetFieldsTransformationSkip(); + + /** + * It allows to enable/disable the set of the default value for primitive types in case they are null. + * @param defaultValueSetEnabled if true the default value for the primitive type is set. By default it's true. + * @return the {@link Transformer} instance + */ + Transformer setDefaultValueSetEnabled(boolean defaultValueSetEnabled); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 8447d42dc..77ec1d810 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -324,7 +324,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN && (notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass()))) { fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); } - } else if (primitiveType && !isTransformerFunctionDefined) { + } else if (primitiveType && settings.isDefaultValueSetEnabled() && !isTransformerFunctionDefined) { fieldValue = defaultValue(fieldType); // assign the default value } if (isTransformerFunctionDefined) { diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 31ba4b9ff..30255f922 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -75,4 +75,11 @@ final class TransformerSettings { */ @Setter private boolean validationEnabled; + + /** + * It allows to enable/disable the set of the default value for primitive types in case they are null. + * If set to true the default value is set. + */ + @Setter + private boolean defaultValueSetEnabled = true; } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index e49078bb2..0f0c00994 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -175,6 +175,23 @@ public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); } + /** + * Test that the transformer does not sets the default value for primitive type field in case it's disabled. + */ + @Test + public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeField() { + //GIVEN + FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, null, ACTIVE); + underTest.setDefaultValueSetEnabled(false); + + //WHEN + MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); + + //THEN + assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); + underTest.setDefaultValueSetEnabled(true); + } + /** * Test that the transformer is able to copy object even if the source object has no fields but has getter methods. */ diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index d102276c6..85bd1fd26 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -179,6 +179,33 @@ ToBean toBean = beanUtils.getTransformer() .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); ~~~ +### Disable the default value set for primitive types in case they are null: + +BULL by default sets the default value for all primitive types fields in case their value in the source object. +Given the following Java Bean: + +~~~Java +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final String name; + + // constructors... // constructors... + // getters... // getters and setters... + +} } +~~~ + +in case the field `id` in the `FromBean` object is `null`, the value assigned the correspondent field in the `ToBean` object will be `0`. +To disable this you can simply do: + +~~~Java +ToBean toBean = beanUtils.getTransformer() + .setDefaultValueSetEnabled(false).transform(fromBean, ToBean.class); +~~~ + +in this case the field `id` after the transformation will be `null` + ### Applying a transformation function in case of missing fields in the source object: Assign a default value in case of missing field in the source object: From b5628302f6c07354ecb426678bbf514e2103e18d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 3 Jul 2019 14:47:07 +0200 Subject: [PATCH 0675/1786] Updated changelog --- CHANGELOG-JDK8.md | 4 ++++ CHANGELOG.md | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index a93d8e4da..8ce33dbfb 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.1.22] 2019.07.03 +#### Added +* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/HotelsDotCom/bull/issues/73)). + ### [1.1.21] 2019.06.27 #### Changed * Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/HotelsDotCom/bull/issues/70)). diff --git a/CHANGELOG.md b/CHANGELOG.md index b29030c32..1f5c9ac5c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,16 @@ All notable changes to this project will be documented in this file. +### [1.4.7] 2019.07.03 +#### Added +* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/HotelsDotCom/bull/issues/73)). + ### [1.4.6] 2019.06.27 #### Changed * Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/HotelsDotCom/bull/issues/70)). ### [1.4.5] 2019.06.05 +#### Added * Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). * Added check during project build in order to prevent the add different versions of the same dependency. #### Changed From 661471a185992e3f09040641d33932be3064bae4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 3 Jul 2019 15:08:21 +0200 Subject: [PATCH 0676/1786] Removed redundant null check and default value assignation for primitive types field with null value --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 77ec1d810..f01f1146e 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -170,8 +170,7 @@ private Object[] getConstructorArgsValues(final T sourceObj, final Class< } else { String sourceFieldName = getSourceFieldName(destFieldName); constructorArgsValues[i] = - ofNullable(getFieldValue(sourceObj, sourceFieldName, targetClass, reflectionUtils.getDeclaredField(destFieldName, targetClass), breadcrumb)) - .orElse(classUtils.getDefaultTypeValue(constructorParameters[i].getType())); + getFieldValue(sourceObj, sourceFieldName, targetClass, reflectionUtils.getDeclaredField(destFieldName, targetClass), breadcrumb); } }); return constructorArgsValues; From c3e3c4877d38f0b42c0eead06fec6990164aa504 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 3 Jul 2019 15:36:09 +0200 Subject: [PATCH 0677/1786] [maven-release-plugin] prepare release 1.4.7 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 5989e4284..6557fb4b1 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7-SNAPSHOT + 1.4.7 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f576694b3..be21723af 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7-SNAPSHOT + 1.4.7 diff --git a/pom.xml b/pom.xml index 40da66207..58398b0eb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.7-SNAPSHOT + 1.4.7 pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.7 From d44887fa074f9661204add55fd0f219635bf58ec Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 3 Jul 2019 15:36:17 +0200 Subject: [PATCH 0678/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 6557fb4b1..c41d119ed 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7 + 1.4.8-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index be21723af..f06ebf24b 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7 + 1.4.8-SNAPSHOT diff --git a/pom.xml b/pom.xml index 58398b0eb..3d459da4f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.7 + 1.4.8-SNAPSHOT pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.7 + HEAD From c5d7c723de91f518aa1f8ebe58ac99ce94c61b98 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 10:23:07 +0200 Subject: [PATCH 0679/1786] Fixed conversionTransformer function retrival --- .../beans/transformer/TransformerImpl.java | 17 ++++++++--------- bull-converter/pom.xml | 2 +- .../conversion/analyzer/ConversionAnalyzer.java | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 21ef1a455..d7cd3345f 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -24,6 +24,7 @@ import static java.util.stream.IntStream.range; import static org.apache.commons.lang3.StringUtils.EMPTY; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; import static com.hotels.beans.constant.Punctuation.DOT; import static com.hotels.beans.constant.Punctuation.COMMA; @@ -312,8 +313,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN return defaultValue(fieldType); } boolean primitiveType = classUtils.isPrimitiveType(fieldType); -// List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType || classUtils.isPrimitiveTypeArray(fieldType), fieldBreadcrumb); - List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType, fieldBreadcrumb); + List transformerFunction = getTransformerFunction(sourceObj.getClass(), field, primitiveType, fieldBreadcrumb); boolean isTransformerFunctionDefined = !transformerFunction.isEmpty(); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { @@ -356,7 +356,7 @@ private Object getTransformedValue(final List transformerFunct * @return the updated breadcrumb */ private String evalBreadcrumb(final String fieldName, final String breadcrumb) { - return (nonNull(breadcrumb) ? breadcrumb + DOT.getSymbol() : EMPTY) + fieldName; + return (isNotEmpty(breadcrumb) ? breadcrumb + DOT.getSymbol() : EMPTY) + fieldName; } /** @@ -391,21 +391,20 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie * Retrieves the transformer function. If the field type is different and they are primitive * a conversion function is automatically added. * @param sourceObjectClass the source object class - * @param sourceFieldName the source field name * @param field The field on which the transformation should be applied. * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @param breadcrumb The full field path on which the transformation should be applied. * @return the transformer function. */ - private List getTransformerFunction(final Class sourceObjectClass, final String sourceFieldName, final Field field, + private List getTransformerFunction(final Class sourceObjectClass, final Field field, final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { List fieldTransformers = new ArrayList<>(); + String fieldTransformerKey = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; if (isDestinationFieldPrimitiveType) { - Class sourceFieldType = reflectionUtils.getDeclaredField(sourceFieldName, sourceObjectClass).getType(); - conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) - .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(field.getName(), conversionFunction))); + conversionAnalyzer.getConversionFunction(sourceObjectClass, field.getType()) + .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(fieldTransformerKey, conversionFunction))); } - ofNullable(settings.getFieldsTransformers().get(settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb)) + ofNullable(settings.getFieldsTransformers().get(fieldTransformerKey)) .ifPresent(fieldTransformers::add); return fieldTransformers; } diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 0c3c3a0dd..8992424ce 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -11,7 +11,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7-SNAPSHOT + 1.4.8-SNAPSHOT diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 6d1580d7f..fb588fcc4 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -70,7 +70,7 @@ public Optional> getConversionFunction(final Class s final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional> conversionFunction = empty(); - if (destinationFieldType != sourceFieldType && classUtils.isPrimitiveType(sourceFieldType)) { + if (!destinationFieldType.getSimpleName().equalsIgnoreCase(sourceFieldType.getSimpleName()) && classUtils.isPrimitiveType(sourceFieldType)) { conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); } CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); From 4ca9893a6359ef2d8fa676759f0a51f37163d900 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 11:50:59 +0200 Subject: [PATCH 0680/1786] Started UT implementation --- .../analyzer/ConversionAnalyzer.java | 2 +- .../conversion/analyzer/package-info.java | 5 +- .../hotels/beans/conversion/package-info.java | 2 +- .../conversion/processor/package-info.java | 2 +- .../analyzer/ConversionAnalyzerTest.java | 84 +++++++++++++++ .../conversion/analyzer/package-info.java | 20 ++++ .../ConversionProcessorFactoryTest.java | 101 ++++++++++++++++++ .../conversion/processor/package-info.java | 20 ++++ 8 files changed, 229 insertions(+), 7 deletions(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index fb588fcc4..d75248e8d 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -88,7 +88,7 @@ public Optional> getConversionFunction(final Class s private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional conversionFunction = getTypeConversionFunction(conversionProcessor, sourceFieldType); + Optional> conversionFunction = getTypeConversionFunction(conversionProcessor, sourceFieldType); CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); return conversionFunction; }); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java index f09de5ed2..590b04ade 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java @@ -13,11 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * Type conversion processor package. - */ /** - * Analyzer package. + * Type conversion Analyzer package. */ package com.hotels.beans.conversion.analyzer; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java index db3079203..5476195b3 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java @@ -15,6 +15,6 @@ */ /** - * Conversion package. + * Type Conversion package. */ package com.hotels.beans.conversion; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java index c14028c3f..54cd547b1 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java @@ -15,6 +15,6 @@ */ /** - * Processor package. + * Type conversion processor package. */ package com.hotels.beans.conversion.processor; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java new file mode 100644 index 000000000..636b2b304 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -0,0 +1,84 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.analyzer; + +import static java.util.Optional.empty; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.util.Optional; +import java.util.function.Function; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ConversionAnalyzer}. + */ +public class ConversionAnalyzerTest { + + /** + * The class to be tested. + */ + @InjectMocks + private ConversionAnalyzer underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + /** + * Tests that the method {@code getConversionFunction} returns the expected . + * @param testCaseDescription the test case description + * @param sourceFieldType source field class + * @param destinationFieldType the destination field class + */ + @SuppressWarnings("unchecked") + @Test(dataProvider = "dataGetConversionFunctionTesting") + public void testGetConversionFunctionWorksAsExpected(final String testCaseDescription, final Class sourceFieldType, + final Class destinationFieldType, final Optional> expectedResult) { + // GIVEN + + // WHEN + Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code getConversionFunction}. + * @return parameters to be used for testing the the method {@code getConversionFunction}. + */ + @DataProvider + private Object[][] dataGetConversionFunctionTesting() { + return new Object[][] { + {"Tests that the method returns an empty optional in case the source field type is equal to the destination field type", + int.class, int.class, empty()}, + {"Tests that the method returns an empty optional in case the source field type is equal to the source field type is not primitive", + ImmutablePair.class, int.class, empty()} + }; + } +} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java new file mode 100644 index 000000000..32b6624d5 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Type conversion Analyzer test package. + */ +package com.hotels.beans.conversion.analyzer; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java new file mode 100644 index 000000000..e95b57820 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -0,0 +1,101 @@ +package com.hotels.beans.conversion.processor; + +import static java.util.Optional.empty; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.apache.commons.lang3.tuple.Pair; +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; +import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; +import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; +import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; +import com.hotels.beans.conversion.processor.impl.FloatConversionProcessor; +import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; +import com.hotels.beans.conversion.processor.impl.LongConversionProcessor; +import com.hotels.beans.conversion.processor.impl.ShortConversionProcessor; +import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; + +/** + * Unit test for {@link ConversionProcessorFactory}. + */ +public class ConversionProcessorFactoryTest { + /** + * The class to be tested. + */ + @InjectMocks + private ConversionProcessorFactory underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + /** + * Tests that the method {@code getConversionProcessor} returns null in case there is no processor defined for the given type. + */ + @Test + public void testGetConversionProcessorReturnsNullInCaseNoProcessorExistsForTheGivenType() { + // GIVEN + + // WHEN + ConversionProcessor actual = underTest.getConversionProcessor(Pair.class); + + // THEN + assertNull(actual); + } + + /** + * Tests that the method {@code getConversionProcessor} returns the expected Conversion processor for the given type. + * @param testCaseDescription the test case description + * @param targetClass object type for which the conversion processor has to be retrieved + * @param expectedResult the expected {@link ConversionProcessor} class for the given object type + */ + @Test(dataProvider = "dataGetConversionProcessorTesting") + public void testGetConversionProcessorWorksAsExpected(final String testCaseDescription, final Class targetClass, + final Class expectedResult) { + // GIVEN + + // WHEN + ConversionProcessor actual = underTest.getConversionProcessor(targetClass); + + // THEN + assertEquals(expectedResult, actual.getClass()); + } + + /** + * Creates the parameters to be used for testing the method {@code getConversionProcessor}. + * @return parameters to be used for testing the the method {@code getConversionProcessor}. + */ + @DataProvider + private Object[][] dataGetConversionProcessorTesting() { + return new Object[][]{ + {"Tests that the method returns a ByteConversionProcessor is case the target class ia a byte", byte.class, ByteConversionProcessor.class}, + {"Tests that the method returns a ByteConversionProcessor is case the target class ia a Byte", Byte.class, ByteConversionProcessor.class}, + {"Tests that the method returns a ShortConversionProcessor is case the target class ia a Short", Short.class, ShortConversionProcessor.class}, + {"Tests that the method returns a ShortConversionProcessor is case the target class ia a short", short.class, ShortConversionProcessor.class}, + {"Tests that the method returns a IntegerConversionProcessor is case the target class is an Integer", Integer.class, IntegerConversionProcessor.class}, + {"Tests that the method returns a IntegerConversionProcessor is case the target class is an int", int.class, IntegerConversionProcessor.class}, + {"Tests that the method returns a LongConversionProcessor is case the target class is a Long", Long.class, LongConversionProcessor.class}, + {"Tests that the method returns a LongConversionProcessor is case the target class is a long", long.class, LongConversionProcessor.class}, + {"Tests that the method returns a FloatConversionProcessor is case the target class is a Float", Float.class, FloatConversionProcessor.class}, + {"Tests that the method returns a FloatConversionProcessor is case the target class is a float", float.class, FloatConversionProcessor.class}, + {"Tests that the method returns a DoubleConversionProcessor is case the target class is a Double", Double.class, DoubleConversionProcessor.class}, + {"Tests that the method returns a DoubleConversionProcessor is case the target class is a double", double.class, DoubleConversionProcessor.class}, + {"Tests that the method returns a CharacterConversionProcessor is case the target class is a Character", Character.class, CharacterConversionProcessor.class}, + {"Tests that the method returns a CharacterConversionProcessor is case the target class is a char", char.class, CharacterConversionProcessor.class}, + {"Tests that the method returns a StringConversionProcessor is case the target class is a String", String.class, StringConversionProcessor.class}, + {"Tests that the method returns a BooleanConversionProcessor is case the target class is a Boolean", Boolean.class, BooleanConversionProcessor.class}, + {"Tests that the method returns a BooleanConversionProcessor is case the target class is a boolean", boolean.class, BooleanConversionProcessor.class} + }; + } +} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java new file mode 100644 index 000000000..6a95f57c2 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Type conversion processor test package. + */ +package com.hotels.beans.conversion.processor; From a5d73f34ebb6e57bbe792dcaf7b21407c64386f5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 12:02:55 +0200 Subject: [PATCH 0681/1786] Added Expedia Group centralized credential for releases --- .travis.yml | 3 +++ config/travis/mvn-settings.xml | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index df568e821..eec903954 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,9 @@ env: # Sonatype jira info - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= + # EG OSS Sonatype jira info + - secure: MlOUNGzEfzf2M9nSPcJDcD/BWpYkz7lyiu91x5ITkUGD5Z3Bhi8PkDV6oekXChTxouPxK1JTKxn1dN1DUsJ/HKpTEcgmQL3GrSD0blYsolvQIJTpZR/Ox/ryTHjEwCo6u85ek49EF4ksV9jqCcOIsApsb4KwfI/X6Gju3TOlpp+ns+wvvbuL6/aHDyjuAcJEBnkAJdeKi/PMXd31W3YSKzvwwa5y1JPEU+k7cpKTyOERkyxHaiOyp02r4Ppi70Txc5k/U6qknNYqXSeSWkJJVXNgY5Emx0dNOjKV4hIZMpUOHxBJH/9bW+Hpj0EgTEBQWwaOcSStjBUwfVen4rVnd4Kd1MUU/1pQ8q783FpUGru+FygFLxOcQxzMA/NPUTmCNJj4G9dSBn+j5iZA0XfKE+hWUrZGRRvwXaD/MBqCNq0nn45UcQjUg8a9C7w3qFxgw6jgTmCjlwPphNE4s8zMMiVeZQeVkE7DvgYzWldP0xODKx7Avg4mOGpDTzB590plWMf2MfCl4ZUtOZFAIrnMroUurVRPh34l/zy9RGtyffIK46EGKsx3cmx630zBGZxDBXTYAgPkvUsW5UdN9IhlN/ZXt00VrBDLx+jWNzk9tB2tMuRBlBLeOKuj1O8jNiUNj0wZVtGhkn5pci5VsVn8da79MXTHyjAcoNhtkkMMnCA= + - secure: VUZIXu084sTbZzik7ukJlBE/hxeYYD6pOsyDmewhPjIdv0rGGWrc1UOqsFPZfYD3Hbk5j8BL4aLJWL48KI7+BEa2TylAk4MVbdbhfOOIG5Jk7GjnI3oGfmE84TQE59/Gkrg7pK6oTmlyxRkPcJLenk7fuBlBsuNchYzXnFfu3fXAbmrmSq543AXscbsl3EsYcXJVH2cwQJ/znU3GasreKCBEIGQubuwwZCyLcCkt4uBDS3O9LVE/vXAIqZGRpDYd8BkPLQHzvZKw1Vigre3ZvCTUzSyCrrxYw1ZwzkriY3xxVtbEBONhG7xOk+zIx09TUfrQ6lS0hXXNOVeQqBRyN/6ORClmhJw8K8RMLS5cs7eMpjlnJA6lUk/fGxyErW+mALQHa62YTAuYgaeycpHqSUxpL5UXDTbTA7HUc4RU+VKVFphARf1qLunWVjxvrLKPjdOhbDxya/MODpKjU7drlFCp2iRx0VJX6+v0noUtlJVv6M0N6wcscXJQivA4Czph7pSoD2j4h4fMohJa8sPcgx7Z7qYqsFOn1369rnbpETVZ9Nz2vVFt11Yj/T+Ep3KZIqdaktgqrAlFPU+c2Rp80lUOM0kVM1g2qmK6V2L+j3WLFI/5d0KK/ALz83LldEUJfC3eMTcxIh+RW7Te0ehye1zaqmdSSpnqyby9ZBn+c8I= # GPG_KEYNAME - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index c7dd98343..6a9ccc4e9 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -2,18 +2,18 @@ ossrh - ${env.OSSRH_USERNAME} - ${env.OSSRH_PASSWORD} + ${env.EG_OSSRH_USERNAME} + ${env.EG_OSSRH_PASSWORD} sonatype-nexus-staging - ${env.OSSRH_USERNAME} - ${env.OSSRH_PASSWORD} + ${env.EG_OSSRH_USERNAME} + ${env.EG_OSSRH_PASSWORD} sonatype-nexus-snapshots - ${env.OSSRH_USERNAME} - ${env.OSSRH_PASSWORD} + ${env.EG_OSSRH_USERNAME} + ${env.EG_OSSRH_PASSWORD} From 6745a56efd3db0692262982ef5d61304dcfb6842 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 14:31:40 +0200 Subject: [PATCH 0682/1786] Testing with news OSS credential --- .travis.yml | 78 ++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index eec903954..cd5f5a98c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,10 @@ env: - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= # EG OSS Sonatype jira info - - secure: MlOUNGzEfzf2M9nSPcJDcD/BWpYkz7lyiu91x5ITkUGD5Z3Bhi8PkDV6oekXChTxouPxK1JTKxn1dN1DUsJ/HKpTEcgmQL3GrSD0blYsolvQIJTpZR/Ox/ryTHjEwCo6u85ek49EF4ksV9jqCcOIsApsb4KwfI/X6Gju3TOlpp+ns+wvvbuL6/aHDyjuAcJEBnkAJdeKi/PMXd31W3YSKzvwwa5y1JPEU+k7cpKTyOERkyxHaiOyp02r4Ppi70Txc5k/U6qknNYqXSeSWkJJVXNgY5Emx0dNOjKV4hIZMpUOHxBJH/9bW+Hpj0EgTEBQWwaOcSStjBUwfVen4rVnd4Kd1MUU/1pQ8q783FpUGru+FygFLxOcQxzMA/NPUTmCNJj4G9dSBn+j5iZA0XfKE+hWUrZGRRvwXaD/MBqCNq0nn45UcQjUg8a9C7w3qFxgw6jgTmCjlwPphNE4s8zMMiVeZQeVkE7DvgYzWldP0xODKx7Avg4mOGpDTzB590plWMf2MfCl4ZUtOZFAIrnMroUurVRPh34l/zy9RGtyffIK46EGKsx3cmx630zBGZxDBXTYAgPkvUsW5UdN9IhlN/ZXt00VrBDLx+jWNzk9tB2tMuRBlBLeOKuj1O8jNiUNj0wZVtGhkn5pci5VsVn8da79MXTHyjAcoNhtkkMMnCA= - - secure: VUZIXu084sTbZzik7ukJlBE/hxeYYD6pOsyDmewhPjIdv0rGGWrc1UOqsFPZfYD3Hbk5j8BL4aLJWL48KI7+BEa2TylAk4MVbdbhfOOIG5Jk7GjnI3oGfmE84TQE59/Gkrg7pK6oTmlyxRkPcJLenk7fuBlBsuNchYzXnFfu3fXAbmrmSq543AXscbsl3EsYcXJVH2cwQJ/znU3GasreKCBEIGQubuwwZCyLcCkt4uBDS3O9LVE/vXAIqZGRpDYd8BkPLQHzvZKw1Vigre3ZvCTUzSyCrrxYw1ZwzkriY3xxVtbEBONhG7xOk+zIx09TUfrQ6lS0hXXNOVeQqBRyN/6ORClmhJw8K8RMLS5cs7eMpjlnJA6lUk/fGxyErW+mALQHa62YTAuYgaeycpHqSUxpL5UXDTbTA7HUc4RU+VKVFphARf1qLunWVjxvrLKPjdOhbDxya/MODpKjU7drlFCp2iRx0VJX6+v0noUtlJVv6M0N6wcscXJQivA4Czph7pSoD2j4h4fMohJa8sPcgx7Z7qYqsFOn1369rnbpETVZ9Nz2vVFt11Yj/T+Ep3KZIqdaktgqrAlFPU+c2Rp80lUOM0kVM1g2qmK6V2L+j3WLFI/5d0KK/ALz83LldEUJfC3eMTcxIh+RW7Te0ehye1zaqmdSSpnqyby9ZBn+c8I= +# - secure: MlOUNGzEfzf2M9nSPcJDcD/BWpYkz7lyiu91x5ITkUGD5Z3Bhi8PkDV6oekXChTxouPxK1JTKxn1dN1DUsJ/HKpTEcgmQL3GrSD0blYsolvQIJTpZR/Ox/ryTHjEwCo6u85ek49EF4ksV9jqCcOIsApsb4KwfI/X6Gju3TOlpp+ns+wvvbuL6/aHDyjuAcJEBnkAJdeKi/PMXd31W3YSKzvwwa5y1JPEU+k7cpKTyOERkyxHaiOyp02r4Ppi70Txc5k/U6qknNYqXSeSWkJJVXNgY5Emx0dNOjKV4hIZMpUOHxBJH/9bW+Hpj0EgTEBQWwaOcSStjBUwfVen4rVnd4Kd1MUU/1pQ8q783FpUGru+FygFLxOcQxzMA/NPUTmCNJj4G9dSBn+j5iZA0XfKE+hWUrZGRRvwXaD/MBqCNq0nn45UcQjUg8a9C7w3qFxgw6jgTmCjlwPphNE4s8zMMiVeZQeVkE7DvgYzWldP0xODKx7Avg4mOGpDTzB590plWMf2MfCl4ZUtOZFAIrnMroUurVRPh34l/zy9RGtyffIK46EGKsx3cmx630zBGZxDBXTYAgPkvUsW5UdN9IhlN/ZXt00VrBDLx+jWNzk9tB2tMuRBlBLeOKuj1O8jNiUNj0wZVtGhkn5pci5VsVn8da79MXTHyjAcoNhtkkMMnCA= +# - secure: VUZIXu084sTbZzik7ukJlBE/hxeYYD6pOsyDmewhPjIdv0rGGWrc1UOqsFPZfYD3Hbk5j8BL4aLJWL48KI7+BEa2TylAk4MVbdbhfOOIG5Jk7GjnI3oGfmE84TQE59/Gkrg7pK6oTmlyxRkPcJLenk7fuBlBsuNchYzXnFfu3fXAbmrmSq543AXscbsl3EsYcXJVH2cwQJ/znU3GasreKCBEIGQubuwwZCyLcCkt4uBDS3O9LVE/vXAIqZGRpDYd8BkPLQHzvZKw1Vigre3ZvCTUzSyCrrxYw1ZwzkriY3xxVtbEBONhG7xOk+zIx09TUfrQ6lS0hXXNOVeQqBRyN/6ORClmhJw8K8RMLS5cs7eMpjlnJA6lUk/fGxyErW+mALQHa62YTAuYgaeycpHqSUxpL5UXDTbTA7HUc4RU+VKVFphARf1qLunWVjxvrLKPjdOhbDxya/MODpKjU7drlFCp2iRx0VJX6+v0noUtlJVv6M0N6wcscXJQivA4Czph7pSoD2j4h4fMohJa8sPcgx7Z7qYqsFOn1369rnbpETVZ9Nz2vVFt11Yj/T+Ep3KZIqdaktgqrAlFPU+c2Rp80lUOM0kVM1g2qmK6V2L+j3WLFI/5d0KK/ALz83LldEUJfC3eMTcxIh+RW7Te0ehye1zaqmdSSpnqyby9ZBn+c8I= + - secure: NA1LDLSFPjfCJhv4aL4etZlvHKJ4vrqacu3aTVB81QFeMlTGnENRKXsmOhhUNkj6PAB0IfrStlud5EHuTM6LxOGcXov6aoj6grz1Cq9p7groaihFcRMizgp041wXAwl2FA7K8mLCpxP+NbgoaO6KhZYWso3JshKgzQ1THHDHNx423KkqNwyV8ddOzA0TynjGhEZPI40+ruuxgYS6dZk0ObwvdLdJUW2FLZeHKGxvKP7l4t4RseqmwAr47WK+pY7n6NjyWAaqPog/Wsd5XIiyo8AJA0WSdLtUjchE5gBKH7Bd5nw2zx/IqyQuSNZg73QYya1Pko0VW0YVq7fY9pN3D7cVkQVpmvLVAPFcMP32WWaMkzvEA4hFZRa2WShzdDCGA1uleD/v/YlFBKCmKyeIyeUYkd4/JsJOL9PLeFfx7ECpp3ZAFi8tGKiCTueFYLrIuLoOpOn5giB4/724Tkl54wRig5v3njaFFmeLhqW8Tox6KfFJ1qh3R8pEqwhFjOZFcWceURPkKNSOt19LFv7brT2dpFQuynX5I+CtcIqGBT4Jbqwmq7EyYhxx2508d6Gq9nNrOFvGukA1Q4JWyZLsCi+TuNHcxTLXN4AUPjeUmlRWT6hKBdjVxe/T5PLZPA6p9f6Gk+fO2wOS0+e5cwP8xS+osL/mLoG5U180YuKDTYU= + - secure: Fb2ffyOik4TrfXuCPJIbTmkdfy7W3/3nRawgctOO8YeOpUSg356U3tPYWJZeWhq0XzHsIsloYUjdOcYV33E6sau+lHQ67OJEDHbyAHYOIh5l1HrDJVEwXs3S5W+pvDHrxamNi6BRzWDqp78hv56SMLD9vLlP0HOPAvfOosHwdA1Fg8OBaFRWYKSKuq45VdXRx9DTzNQacGiH97V0efzUfDFbuN9AsqTZl3LHcTocS3KLPyo3j2c4YW3/T6RSQJibBjMI1ZbZOrVbQYxZ+zPSKwUv5ucLVSJ2YrNQ+cKTYmOaIka2dBtK9lArbKtRYxvTtXz/fiL1CdD0mEhyP47TFErIWm5GIK5iVehzU9cRzB5s0t6P+D1eUi9uUh7+j5kndYbQb+ksdz1jxkMFw7lI8L0EQi78p+pfV830H199iLFJ8zbyTyce8sb4LNFuKu80DCPm79kpYq4o6bVVmvtLt5etOamKnhB6uq4Ho0ObGVNB+rnnQp03f67MGWV6LF75ati/1v3CGZ9ogjPMM2Tvxa8BttCV/0dKdqxoEJgHCXl91Pf/83B+CK5t4B4lXun1sIGHuqWUGBj3Xt8Ps4tgD/tJ52iXNzKRwyqG3gy6bvKlslu4WfyVKS7BIHQKMowLaoKyQ/h7OQ2NCsPWw+Cws6FVpYZejRyVv3XzOzFEPHg= # GPG_KEYNAME - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE @@ -18,43 +20,45 @@ env: install: skip jobs: include: - # If the branch is not master it just builds the application - - stage: "Build" - name: "Build and Test" - install: travis_retry mvn clean install -DskipTests - - stage: "Site Build and Quality check" - name: "Publishing site and performing a code quality check" - if: type NOT IN (pull_request) AND tag IS present - before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release - deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true - on: - tags: true - - stage: "Release" - name: "Releasing artifacts" - if: type NOT IN (pull_request) AND tag IS present - install: skip - after_deploy: skip - before_script: - - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate - deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true + - stage: Build + name: Build and Test + install: travis_retry mvn clean install -DskipTests + - stage: Site Build and Quality check + name: Publishing site and performing a code quality check + if: type NOT IN (pull_request) AND tag IS present + before_deploy: + - mvn versions:set -D newVersion=${TRAVIS_TAG} + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} + -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} + -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: "${github_oauth_token}" + keep-history: true + on: + tags: true + - stage: Release + name: Releasing artifacts + if: type NOT IN (pull_request) AND tag IS present + install: skip + after_deploy: skip + before_script: + - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv + -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d + - mvn versions:set -D newVersion=${TRAVIS_TAG} + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate + deploy: + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true notifications: slack: rooms: - - bull-crew:hTuN6VsJod6aUOU6FWIFiQca + - bull-crew:hTuN6VsJod6aUOU6FWIFiQca on_failure: change on_success: change - on_pull_requests: true \ No newline at end of file + on_pull_requests: true From 871898c8f76b452cd0a9cb6fe6e5c9ce4fa85de1 Mon Sep 17 00:00:00 2001 From: amarsiglia Date: Fri, 5 Jul 2019 16:05:19 +0200 Subject: [PATCH 0683/1786] Added unit test for IntegerConversionProcessor class. Fixed function for conversion from Character to Integer. --- .../impl/IntegerConversionProcessor.java | 2 +- .../ConversionProcessorFactoryTest.java | 2 - .../impl/IntegerConversionProcessorTest.java | 162 ++++++++++++++++++ 3 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index eebadb929..64856ed52 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -77,7 +77,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return val -> valueOf((int) val); + return Character::getNumericValue; } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index e95b57820..e043f99f5 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -1,7 +1,5 @@ package com.hotels.beans.conversion.processor; -import static java.util.Optional.empty; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.mockito.MockitoAnnotations.initMocks; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java new file mode 100644 index 000000000..9069faf34 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java @@ -0,0 +1,162 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Character.getNumericValue; +import static java.lang.Integer.valueOf; +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.util.function.Function; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link IntegerConversionProcessor}. + */ +public class IntegerConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private IntegerConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + Byte actual = 10; + + // WHEN + Function function = underTest.convertByte(); + + // THEN + Integer expected = function.apply(actual); + assertEquals(expected, (Integer) actual.intValue()); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + Short actual = 10; + + // WHEN + Function function = underTest.convertShort(); + + // THEN + Integer expected = function.apply(actual); + assertEquals(expected, (Integer) actual.intValue()); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + Integer actual = 10; + + // WHEN + Function function = underTest.convertInteger(); + + // THEN + Integer expected = function.apply(actual); + assertEquals(expected, actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + Long actual = 10L; + + // WHEN + Function function = underTest.convertLong(); + + // THEN + Integer expected = function.apply(actual); + assertEquals(expected, (Integer) actual.intValue()); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + Float actual = 10f; + + // WHEN + Function function = underTest.convertFloat(); + + // THEN + Integer expected = function.apply(actual); + assertEquals(expected, (Integer) actual.intValue()); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + Double actual = 10.51; + + // WHEN + Function function = underTest.convertDouble(); + + // THEN + Integer expected = function.apply(actual); + assertEquals(expected, (Integer) actual.intValue()); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + Character expected = 'c'; + + // WHEN + Integer actual = underTest.convertCharacter().apply(expected); + + // THEN + assertEquals((Integer) getNumericValue(expected), actual); + } + + @Test + public void testConvertBooleanShouldReturnProperResult() { + // GIVEN + Boolean expected = true; + + // WHEN + Integer actual = underTest.convertBoolean().apply(expected); + + // THEN + assertEquals(expected, actual.equals(1)); + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + String expected = "140"; + + // WHEN + Integer actual = underTest.convertString().apply(expected); + + // THEN + assertEquals(valueOf(expected), actual); + } +} + From 73adc3c39ca1faa3fb167eefe6d3bfd8e1aa132c Mon Sep 17 00:00:00 2001 From: amarsiglia Date: Fri, 5 Jul 2019 16:14:14 +0200 Subject: [PATCH 0684/1786] Improvements on IntegerConversionProcessor unit test class. --- .../impl/IntegerConversionProcessorTest.java | 42 ++++++++----------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java index 9069faf34..962376245 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java @@ -21,8 +21,6 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; -import java.util.function.Function; - import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -48,79 +46,73 @@ public void beforeClass() { @Test public void testConvertByteShouldReturnProperResult() { // GIVEN - Byte actual = 10; + Byte expected = 10; // WHEN - Function function = underTest.convertByte(); + Integer actual = underTest.convertByte().apply(expected); // THEN - Integer expected = function.apply(actual); - assertEquals(expected, (Integer) actual.intValue()); + assertEquals((Integer) expected.intValue(), actual); } @Test public void testConvertShortShouldReturnProperResult() { // GIVEN - Short actual = 10; + Short expected = 10; // WHEN - Function function = underTest.convertShort(); + Integer actual = underTest.convertShort().apply(expected); // THEN - Integer expected = function.apply(actual); - assertEquals(expected, (Integer) actual.intValue()); + assertEquals((Integer) expected.intValue(), actual); } @Test public void testConvertIntegerShouldReturnProperResult() { // GIVEN - Integer actual = 10; + Integer expected = 10; // WHEN - Function function = underTest.convertInteger(); + Integer actual = underTest.convertInteger().apply(expected); // THEN - Integer expected = function.apply(actual); assertEquals(expected, actual); } @Test public void testConvertLongShouldReturnProperResult() { // GIVEN - Long actual = 10L; + Long expected = 10L; // WHEN - Function function = underTest.convertLong(); + Integer actual = underTest.convertLong().apply(expected); // THEN - Integer expected = function.apply(actual); - assertEquals(expected, (Integer) actual.intValue()); + assertEquals((Integer) expected.intValue(), actual); } @Test public void testConvertFloatShouldReturnProperResult() { // GIVEN - Float actual = 10f; + Float expected = 10f; // WHEN - Function function = underTest.convertFloat(); + Integer actual = underTest.convertFloat().apply(expected); // THEN - Integer expected = function.apply(actual); - assertEquals(expected, (Integer) actual.intValue()); + assertEquals((Integer) expected.intValue(), actual); } @Test public void testConvertDoubleShouldReturnProperResult() { // GIVEN - Double actual = 10.51; + Double expected = 10.51; // WHEN - Function function = underTest.convertDouble(); + Integer actual = underTest.convertDouble().apply(expected); // THEN - Integer expected = function.apply(actual); - assertEquals(expected, (Integer) actual.intValue()); + assertEquals((Integer) expected.intValue(), actual); } @Test From 598a260fad15f0317e70f8115326cfbc974afd17 Mon Sep 17 00:00:00 2001 From: massdosage Date: Fri, 5 Jul 2019 15:43:43 +0100 Subject: [PATCH 0685/1786] take 2 at using new shared sonatype creds --- .travis.yml | 12 ++++-------- config/travis/mvn-settings.xml | 12 ++++++------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index cd5f5a98c..c7e290784 100755 --- a/.travis.yml +++ b/.travis.yml @@ -5,14 +5,10 @@ cache: jdk: openjdk11 env: global: - # Sonatype jira info - - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= - - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= - # EG OSS Sonatype jira info -# - secure: MlOUNGzEfzf2M9nSPcJDcD/BWpYkz7lyiu91x5ITkUGD5Z3Bhi8PkDV6oekXChTxouPxK1JTKxn1dN1DUsJ/HKpTEcgmQL3GrSD0blYsolvQIJTpZR/Ox/ryTHjEwCo6u85ek49EF4ksV9jqCcOIsApsb4KwfI/X6Gju3TOlpp+ns+wvvbuL6/aHDyjuAcJEBnkAJdeKi/PMXd31W3YSKzvwwa5y1JPEU+k7cpKTyOERkyxHaiOyp02r4Ppi70Txc5k/U6qknNYqXSeSWkJJVXNgY5Emx0dNOjKV4hIZMpUOHxBJH/9bW+Hpj0EgTEBQWwaOcSStjBUwfVen4rVnd4Kd1MUU/1pQ8q783FpUGru+FygFLxOcQxzMA/NPUTmCNJj4G9dSBn+j5iZA0XfKE+hWUrZGRRvwXaD/MBqCNq0nn45UcQjUg8a9C7w3qFxgw6jgTmCjlwPphNE4s8zMMiVeZQeVkE7DvgYzWldP0xODKx7Avg4mOGpDTzB590plWMf2MfCl4ZUtOZFAIrnMroUurVRPh34l/zy9RGtyffIK46EGKsx3cmx630zBGZxDBXTYAgPkvUsW5UdN9IhlN/ZXt00VrBDLx+jWNzk9tB2tMuRBlBLeOKuj1O8jNiUNj0wZVtGhkn5pci5VsVn8da79MXTHyjAcoNhtkkMMnCA= -# - secure: VUZIXu084sTbZzik7ukJlBE/hxeYYD6pOsyDmewhPjIdv0rGGWrc1UOqsFPZfYD3Hbk5j8BL4aLJWL48KI7+BEa2TylAk4MVbdbhfOOIG5Jk7GjnI3oGfmE84TQE59/Gkrg7pK6oTmlyxRkPcJLenk7fuBlBsuNchYzXnFfu3fXAbmrmSq543AXscbsl3EsYcXJVH2cwQJ/znU3GasreKCBEIGQubuwwZCyLcCkt4uBDS3O9LVE/vXAIqZGRpDYd8BkPLQHzvZKw1Vigre3ZvCTUzSyCrrxYw1ZwzkriY3xxVtbEBONhG7xOk+zIx09TUfrQ6lS0hXXNOVeQqBRyN/6ORClmhJw8K8RMLS5cs7eMpjlnJA6lUk/fGxyErW+mALQHa62YTAuYgaeycpHqSUxpL5UXDTbTA7HUc4RU+VKVFphARf1qLunWVjxvrLKPjdOhbDxya/MODpKjU7drlFCp2iRx0VJX6+v0noUtlJVv6M0N6wcscXJQivA4Czph7pSoD2j4h4fMohJa8sPcgx7Z7qYqsFOn1369rnbpETVZ9Nz2vVFt11Yj/T+Ep3KZIqdaktgqrAlFPU+c2Rp80lUOM0kVM1g2qmK6V2L+j3WLFI/5d0KK/ALz83LldEUJfC3eMTcxIh+RW7Te0ehye1zaqmdSSpnqyby9ZBn+c8I= - - secure: NA1LDLSFPjfCJhv4aL4etZlvHKJ4vrqacu3aTVB81QFeMlTGnENRKXsmOhhUNkj6PAB0IfrStlud5EHuTM6LxOGcXov6aoj6grz1Cq9p7groaihFcRMizgp041wXAwl2FA7K8mLCpxP+NbgoaO6KhZYWso3JshKgzQ1THHDHNx423KkqNwyV8ddOzA0TynjGhEZPI40+ruuxgYS6dZk0ObwvdLdJUW2FLZeHKGxvKP7l4t4RseqmwAr47WK+pY7n6NjyWAaqPog/Wsd5XIiyo8AJA0WSdLtUjchE5gBKH7Bd5nw2zx/IqyQuSNZg73QYya1Pko0VW0YVq7fY9pN3D7cVkQVpmvLVAPFcMP32WWaMkzvEA4hFZRa2WShzdDCGA1uleD/v/YlFBKCmKyeIyeUYkd4/JsJOL9PLeFfx7ECpp3ZAFi8tGKiCTueFYLrIuLoOpOn5giB4/724Tkl54wRig5v3njaFFmeLhqW8Tox6KfFJ1qh3R8pEqwhFjOZFcWceURPkKNSOt19LFv7brT2dpFQuynX5I+CtcIqGBT4Jbqwmq7EyYhxx2508d6Gq9nNrOFvGukA1Q4JWyZLsCi+TuNHcxTLXN4AUPjeUmlRWT6hKBdjVxe/T5PLZPA6p9f6Gk+fO2wOS0+e5cwP8xS+osL/mLoG5U180YuKDTYU= - - secure: Fb2ffyOik4TrfXuCPJIbTmkdfy7W3/3nRawgctOO8YeOpUSg356U3tPYWJZeWhq0XzHsIsloYUjdOcYV33E6sau+lHQ67OJEDHbyAHYOIh5l1HrDJVEwXs3S5W+pvDHrxamNi6BRzWDqp78hv56SMLD9vLlP0HOPAvfOosHwdA1Fg8OBaFRWYKSKuq45VdXRx9DTzNQacGiH97V0efzUfDFbuN9AsqTZl3LHcTocS3KLPyo3j2c4YW3/T6RSQJibBjMI1ZbZOrVbQYxZ+zPSKwUv5ucLVSJ2YrNQ+cKTYmOaIka2dBtK9lArbKtRYxvTtXz/fiL1CdD0mEhyP47TFErIWm5GIK5iVehzU9cRzB5s0t6P+D1eUi9uUh7+j5kndYbQb+ksdz1jxkMFw7lI8L0EQi78p+pfV830H199iLFJ8zbyTyce8sb4LNFuKu80DCPm79kpYq4o6bVVmvtLt5etOamKnhB6uq4Ho0ObGVNB+rnnQp03f67MGWV6LF75ati/1v3CGZ9ogjPMM2Tvxa8BttCV/0dKdqxoEJgHCXl91Pf/83B+CK5t4B4lXun1sIGHuqWUGBj3Xt8Ps4tgD/tJ52iXNzKRwyqG3gy6bvKlslu4WfyVKS7BIHQKMowLaoKyQ/h7OQ2NCsPWw+Cws6FVpYZejRyVv3XzOzFEPHg= + # HCOM_OSSRH_USERNAME + - secure: A1THwDcKNrR/+nHj8Hu8aEjUeh1T1FKKg/sZ3CArAldt7U2IH/DndS5vi8+58B85eDFNByu6bOtqYls13Y9pKWyjY7nEBJtqQ79BFN22G85wZiiVHawFdsdOSN7gMSDQHfbZaJrayliAUuQAgsgqtHPTkgBG8dv3QIVE1G8ILiV0Ui6JYpE+FVysIdeYpcWnhKpjX95jpTLuKqiBfVqgpT6Y24P9No8N37YgtgnYOXwn2u1AdwZ6bbeSria/n+Napi2pTtgTc0zQ4PMaowFv1P6/LuSPCs/XNfuCB9EzfIpXYUtOvoF9KQ0OqtyKrldAlOHC/cGkBWOcA8GNpJ4ONr0oCarZUPI3mV/ecx6q0dpqYF/Smy1Hj5tpYgSiXpDGTGg2fgawmTsr0faU2XbSFp1IWEnib0uQ9PhXUHg01MmnMp2pqCvNzPBjai7Lhquf/ykLqXfgO0ntDsqsTxe24nBKN3Azz5CJrkgjwgNxZMH+DQmNhHWA7QEUYBO2+wIrDNc3vaItpGsU7VrtX2dNPmfDl865ODPJEqClyYFkO7h3E+Zzx1tW4hdDEW6ME5UM6opbI02luOcifC2WxcfCDDaBa/n2KzGIAvThC0N+bdRLQPPNT+Rs0eqOwH/+LrODT9HzpcGgCZ32Cqm59t4xJXrIlcd5pVEEg535HU26638= + # HCOM_OSSRH_PASSWORD + - secure: Bq043/gjNIWaP0t2cniKabnHSSB3LmDnYSBYBqdll/pp/wHTChs5OcW1UamXfVsBY9pF7GpYroLvkqkUV7k5lnA5aFWoJaU/Ehh/WvIwge8cJxF6ie/pxjdnVS5P5aSB39brm8IU97zOoyzT4cdPuMvQSSemwqC/rU5FD5CfO1sb2WRJkJHsY3oP3FHVW3aLldGC1MlsQ95wfIGeGUpx/LtUlZvxf+fNrs83YVW+v2Ibj6+YueTPzKLk5yAuzCh2qG97dkI5XTMRbjxBICCK7GsXaoUCx+Ix+Sa97MlASQzgEYZz77s4TU6h+oV5BLNR+/aW0bpFFXNIVe9m+ZBW4APbVq5tvDXsbEy/7qYrETT5F7ZasCGOGQUgmqqbWuIxB/fcxA4jMvBEniBSo6ifdQkjyoEjWLoQtApsbYCA7Mtg8cVyVHx1oWyQgg+9Q30KPMVkXP8GufPdl3dpAdpzHxYwghtPzVVAlxkAGjHTo/AzVGh4T8qLZwUY3WVtZie6ZYZ1WRpa9dlvLeQ+T42r4buI0/ndpbfQyT5OxrURllMwpk1XZPH7GgCQ+fRalhhsu+32wIVXE/jGTDst2+Z59kv8p8LaKp7H4IU3ZUsuQw3Q41vm3zqBY00t9kyJOVGAzAC/jyeNYEULYUgrkcGlVe+9Zug/F8RCpNsLD2bXtRk= # GPG_KEYNAME - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 6a9ccc4e9..84ca5c569 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -2,18 +2,18 @@ ossrh - ${env.EG_OSSRH_USERNAME} - ${env.EG_OSSRH_PASSWORD} + ${env.HCOM_OSSRH_USERNAME} + ${env.HCOM_OSSRH_PASSWORD} sonatype-nexus-staging - ${env.EG_OSSRH_USERNAME} - ${env.EG_OSSRH_PASSWORD} + ${env.HCOM_OSSRH_USERNAME} + ${env.HCOM_OSSRH_PASSWORD} sonatype-nexus-snapshots - ${env.EG_OSSRH_USERNAME} - ${env.EG_OSSRH_PASSWORD} + ${env.HCOM_OSSRH_USERNAME} + ${env.HCOM_OSSRH_PASSWORD} From 63fae7a8ac27a05d1f2c6d971185c399c11e4a85 Mon Sep 17 00:00:00 2001 From: amarsiglia Date: Fri, 5 Jul 2019 16:49:22 +0200 Subject: [PATCH 0686/1786] Added unit test class for LongConversionProcessor. --- .../impl/LongConversionProcessor.java | 3 +- .../impl/IntegerConversionProcessorTest.java | 1 + .../impl/LongConversionProcessorTest.java | 155 ++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index 4a71d235f..a296c583c 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Character.getNumericValue; import static java.lang.Long.valueOf; import java.util.function.Function; @@ -80,7 +81,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return val -> valueOf((long) val); + return val -> valueOf(getNumericValue(val)); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java index 962376245..ab64ddea1 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.lang.Integer.valueOf; + import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java new file mode 100644 index 000000000..00f369ca8 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java @@ -0,0 +1,155 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Character.getNumericValue; +import static java.lang.Long.valueOf; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link LongConversionProcessor}. + */ +public class LongConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private LongConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + Byte expected = 10; + + // WHEN + Long actual = underTest.convertByte().apply(expected); + + // THEN + assertEquals((Long) expected.longValue(), actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + Short expected = 10; + + // WHEN + Long actual = underTest.convertShort().apply(expected); + + // THEN + assertEquals((Long) expected.longValue(), actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + Integer expected = 10; + + // WHEN + Long actual = underTest.convertInteger().apply(expected); + + // THEN + assertEquals((Long) expected.longValue(), actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + Long expected = 10L; + + // WHEN + Long actual = underTest.convertLong().apply(expected); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + Float expected = 10f; + + // WHEN + Long actual = underTest.convertFloat().apply(expected); + + // THEN + assertEquals((Long) expected.longValue(), actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + Double expected = 10.51; + + // WHEN + Long actual = underTest.convertDouble().apply(expected); + + // THEN + assertEquals((Long) expected.longValue(), actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + char expected = 'c'; + + // WHEN + Long actual = underTest.convertCharacter().apply(expected); + + // THEN + assertEquals(valueOf(getNumericValue(expected)), actual); + } + + @Test + public void testConvertBooleanShouldReturnProperResult() { + // GIVEN + Boolean expected = true; + + // WHEN + Long actual = underTest.convertBoolean().apply(expected); + + // THEN + assertEquals(expected, actual.equals(1L)); + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + String expected = "140"; + + // WHEN + Long actual = underTest.convertString().apply(expected); + + // THEN + assertEquals(valueOf(expected), actual); + } +} + From e846ddafb99c5f025cf6f33e3191bf4664c1cad0 Mon Sep 17 00:00:00 2001 From: massdosage Date: Fri, 5 Jul 2019 16:09:08 +0100 Subject: [PATCH 0687/1786] attempt at debugging the snapshot deploy stage --- config/travis/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index d73d5bc16..b273de385 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -10,6 +10,6 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + mvn -X deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true fi fi \ No newline at end of file From f509e1fed8b6d8acb3d63b3aacdb83e8539c990c Mon Sep 17 00:00:00 2001 From: amarsiglia Date: Fri, 5 Jul 2019 17:24:32 +0200 Subject: [PATCH 0688/1786] Added unit test class for FloatConversionProcessor. --- .../impl/FloatConversionProcessor.java | 3 +- .../impl/FloatConversionProcessorTest.java | 154 ++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index e71698ee2..63b34537f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Character.getNumericValue; import static java.lang.Float.valueOf; import java.util.function.Function; @@ -79,7 +80,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return val -> valueOf((float) val); + return val -> valueOf(getNumericValue(val)); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java new file mode 100644 index 000000000..6a78d2f71 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java @@ -0,0 +1,154 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Character.getNumericValue; +import static java.lang.Float.valueOf; +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link FloatConversionProcessor}. + */ +public class FloatConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private FloatConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + Byte expected = 10; + + // WHEN + Float actual = underTest.convertByte().apply(expected); + + // THEN + assertEquals((Float) expected.floatValue(), actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + Short expected = 10; + + // WHEN + Float actual = underTest.convertShort().apply(expected); + + // THEN + assertEquals((Float) expected.floatValue(), actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + Integer expected = 10; + + // WHEN + Float actual = underTest.convertInteger().apply(expected); + + // THEN + assertEquals((Float) expected.floatValue(), actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + Long expected = 10L; + + // WHEN + Float actual = underTest.convertLong().apply(expected); + + // THEN + assertEquals((Float) expected.floatValue(), actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + Float expected = 10f; + + // WHEN + Float actual = underTest.convertFloat().apply(expected); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + Double expected = 10.51; + + // WHEN + Float actual = underTest.convertDouble().apply(expected); + + // THEN + assertEquals((Float) expected.floatValue(), actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + char expected = 'c'; + + // WHEN + Float actual = underTest.convertCharacter().apply(expected); + + // THEN + assertEquals(Float.valueOf(getNumericValue(expected)), actual); + } + + @Test + public void testConvertBooleanShouldReturnProperResult() { + // GIVEN + Boolean expected = true; + + // WHEN + Float actual = underTest.convertBoolean().apply(expected); + + // THEN + assertEquals(expected, actual.equals(1f)); + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + String expected = "140"; + + // WHEN + Float actual = underTest.convertString().apply(expected); + + // THEN + assertEquals(valueOf(expected), actual); + } +} + From 22b66b80c2aae7ebb3e03a8802c47fd1ceb68cbf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 17:39:19 +0200 Subject: [PATCH 0689/1786] Completed tests for: ConversionAnalyzer class --- .../analyzer/ConversionAnalyzer.java | 26 ++----- .../analyzer/ConversionAnalyzerTest.java | 77 ++++++++++++++++--- .../ConversionProcessorFactoryTest.java | 16 ++++ .../impl/IntegerConversionProcessorTest.java | 56 +++++++------- .../processor/impl/package-info.java | 20 +++++ 5 files changed, 136 insertions(+), 59 deletions(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index d75248e8d..46f850190 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -18,6 +18,7 @@ import static java.util.Optional.empty; import static java.util.Optional.of; +import static java.util.Optional.ofNullable; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.conversion.processor.ConversionProcessorFactory.getConversionProcessor; @@ -69,31 +70,16 @@ public ConversionAnalyzer() { public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional> conversionFunction = empty(); + Optional conversionFunction = empty(); if (!destinationFieldType.getSimpleName().equalsIgnoreCase(sourceFieldType.getSimpleName()) && classUtils.isPrimitiveType(sourceFieldType)) { - conversionFunction = getConversionFunction(getConversionProcessor(destinationFieldType), sourceFieldType); + conversionFunction = ofNullable(getConversionProcessor(destinationFieldType)) + .flatMap(cp -> getTypeConversionFunction(cp, sourceFieldType)); } CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); return conversionFunction; }); } - /** - * Returns the type transformer function for the given type. - * @param conversionProcessor the {@link ConversionProcessor} for the given type - * @param sourceFieldType the source field class - * @return the conversion function - */ - @SuppressWarnings("unchecked") - private Optional> getConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { - final String cacheKey = "ConversionFunction-" + sourceFieldType.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional> conversionFunction = getTypeConversionFunction(conversionProcessor, sourceFieldType); - CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); - return conversionFunction; - }); - } - /** * Returns a function that converts to a primitive type: {@link Byte}, {@link Short}, {@link Integer}, {@link Long}, * {@link Float}, {@link Double}, {@link Character} and {@link Boolean}. @@ -102,7 +88,7 @@ private Optional> getConversionFunction(final Conversio * @return the conversion function */ private Optional> getTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { - final Optional> conversionFunction; + Optional> conversionFunction = null; if (isString(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertString()); } else if (isByte(sourceFieldType)) { @@ -121,8 +107,6 @@ private Optional> getConversionFunction(final Conversio conversionFunction = of(conversionProcessor.convertCharacter()); } else if (isBoolean(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertBoolean()); - } else { - conversionFunction = empty(); } return conversionFunction; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index 636b2b304..f8951b9a3 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -24,12 +24,19 @@ import java.util.Optional; import java.util.function.Function; -import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; +import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; +import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; +import com.hotels.beans.conversion.processor.impl.FloatConversionProcessor; +import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; +import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; + /** * Unit test for {@link ConversionAnalyzer}. */ @@ -50,35 +57,83 @@ public void beforeClass() { } /** - * Tests that the method {@code getConversionFunction} returns the expected . + * Tests that the method {@code getConversionFunction} returns an empty optional. * @param testCaseDescription the test case description * @param sourceFieldType source field class * @param destinationFieldType the destination field class */ - @SuppressWarnings("unchecked") + @Test(dataProvider = "dataGetConversionFunctionEmptyCaseTesting") + public void testGetConversionFunctionReturnsAnEmptyOptional(final String testCaseDescription, final Class sourceFieldType, + final Class destinationFieldType) { + // GIVEN + + // WHEN + Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); + + // THEN + assertEquals(empty(), actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code getConversionFunction} returns an empty Optional. + * @return parameters to be used for testing that the method {@code getConversionFunction} returns an empty Optional. + */ + @DataProvider + private Object[][] dataGetConversionFunctionEmptyCaseTesting() { + return new Object[][] { + {"Tests that the method returns an empty optional in case the source field type is equal to the destination field type", + int.class, int.class}, + {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type but it's not primitive", + Pair.class, int.class}, + {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type and the destination type is void", + int.class, Void.class} + }; + } + + /** + * Tests that the method {@code getConversionFunction} returns the expected conversion function. + * @param testCaseDescription the test case description + * @param sourceFieldType source field class + * @param destinationFieldType the destination field class + * @param expectedConversionFunction the expected {@link com.hotels.beans.conversion.processor.ConversionProcessor} instance + */ @Test(dataProvider = "dataGetConversionFunctionTesting") - public void testGetConversionFunctionWorksAsExpected(final String testCaseDescription, final Class sourceFieldType, - final Class destinationFieldType, final Optional> expectedResult) { + public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final String testCaseDescription, final Class sourceFieldType, + final Class destinationFieldType, final Function expectedConversionFunction) { // GIVEN // WHEN Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN - assertEquals(expectedResult, actual); + assertEquals(expectedConversionFunction, actual.get()); } /** * Creates the parameters to be used for testing the method {@code getConversionFunction}. - * @return parameters to be used for testing the the method {@code getConversionFunction}. + * @return parameters to be used for testing the method {@code getConversionFunction}. */ @DataProvider private Object[][] dataGetConversionFunctionTesting() { return new Object[][] { - {"Tests that the method returns an empty optional in case the source field type is equal to the destination field type", - int.class, int.class, empty()}, - {"Tests that the method returns an empty optional in case the source field type is equal to the source field type is not primitive", - ImmutablePair.class, int.class, empty()} + {"Tests that the method returns a IntegerConversionProcessor that converts from String to int", + String.class, int.class, new IntegerConversionProcessor().convertString()}, + {"Tests that the method returns a StringConversionProcessor that converts from byte to String", + byte.class, String.class, new StringConversionProcessor().convertByte()}, + {"Tests that the method returns a ShortConversionProcessor that converts from short to byte", + short.class, byte.class, new ByteConversionProcessor().convertShort()}, + {"Tests that the method returns a StringConversionProcessor that converts from int to String", + int.class, String.class, new StringConversionProcessor().convertInteger()}, + {"Tests that the method returns a IntegerConversionProcessor that converts from long to int", + long.class, int.class, new IntegerConversionProcessor().convertLong()}, + {"Tests that the method returns a DoubleConversionProcessor that converts from float to double", + float.class, double.class, new DoubleConversionProcessor().convertFloat()}, + {"Tests that the method returns a FloatConversionProcessor that converts from double to float", + double.class, float.class, new FloatConversionProcessor().convertDouble()}, + {"Tests that the method returns a StringConversionProcessor that converts from char to String", + char.class, String.class, new StringConversionProcessor().convertCharacter()}, + {"Tests that the method returns a CharacterConversionProcessor that converts from char to boolean", + boolean.class, char.class, new CharacterConversionProcessor().convertBoolean()} }; } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index e043f99f5..927e6cb5a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -1,3 +1,19 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hotels.beans.conversion.processor; import static org.junit.Assert.assertEquals; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java index 962376245..74fad0d28 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.lang.Integer.valueOf; + import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -29,6 +30,16 @@ * Unit test for {@link IntegerConversionProcessor}. */ public class IntegerConversionProcessorTest { + private static final Byte BYTE_VALUE = 10; + private static final Short SHORT_VALUE = 10; + private static final Integer INTEGER_VALUE = 10; + private static final Long LONG_VALUE = 10L; + private static final Float FLOAT_VALUE = 10f; + private static final Double DOUBLE_VALUE = 10.51; + private static final char CHAR_VALUE = 'c'; + private static final Boolean BOOLEAN_VALUE = Boolean.TRUE; + private static final String STRING_VALUE = "140"; + /** * The class to be tested. */ @@ -46,109 +57,100 @@ public void beforeClass() { @Test public void testConvertByteShouldReturnProperResult() { // GIVEN - Byte expected = 10; // WHEN - Integer actual = underTest.convertByte().apply(expected); + Integer actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals((Integer) expected.intValue(), actual); + assertEquals((Integer) BYTE_VALUE.intValue(), actual); } @Test public void testConvertShortShouldReturnProperResult() { // GIVEN - Short expected = 10; // WHEN - Integer actual = underTest.convertShort().apply(expected); + Integer actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals((Integer) expected.intValue(), actual); + assertEquals((Integer) SHORT_VALUE.intValue(), actual); } @Test public void testConvertIntegerShouldReturnProperResult() { // GIVEN - Integer expected = 10; // WHEN - Integer actual = underTest.convertInteger().apply(expected); + Integer actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals(expected, actual); + assertEquals(INTEGER_VALUE, actual); } @Test public void testConvertLongShouldReturnProperResult() { // GIVEN - Long expected = 10L; // WHEN - Integer actual = underTest.convertLong().apply(expected); + Integer actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals((Integer) expected.intValue(), actual); + assertEquals((Integer) LONG_VALUE.intValue(), actual); } @Test public void testConvertFloatShouldReturnProperResult() { // GIVEN - Float expected = 10f; // WHEN - Integer actual = underTest.convertFloat().apply(expected); + Integer actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals((Integer) expected.intValue(), actual); + assertEquals((Integer) FLOAT_VALUE.intValue(), actual); } @Test public void testConvertDoubleShouldReturnProperResult() { // GIVEN - Double expected = 10.51; // WHEN - Integer actual = underTest.convertDouble().apply(expected); + Integer actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals((Integer) expected.intValue(), actual); + assertEquals((Integer) DOUBLE_VALUE.intValue(), actual); } @Test public void testConvertCharacterShouldReturnProperResult() { // GIVEN - Character expected = 'c'; // WHEN - Integer actual = underTest.convertCharacter().apply(expected); + Integer actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals((Integer) getNumericValue(expected), actual); + assertEquals((Integer) getNumericValue(CHAR_VALUE), actual); } @Test public void testConvertBooleanShouldReturnProperResult() { // GIVEN - Boolean expected = true; // WHEN - Integer actual = underTest.convertBoolean().apply(expected); + Integer actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); // THEN - assertEquals(expected, actual.equals(1)); + assertEquals(BOOLEAN_VALUE, actual.equals(1)); } @Test public void testConvertStringShouldReturnProperResult() { // GIVEN - String expected = "140"; // WHEN - Integer actual = underTest.convertString().apply(expected); + Integer actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(valueOf(expected), actual); + assertEquals(valueOf(STRING_VALUE), actual); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java new file mode 100644 index 000000000..24ebc01da --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Type conversion processor implementation test package. + */ +package com.hotels.beans.conversion.processor.impl; From b70816cca2f553c0fafdb7697304e77392fbf1d6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 17:45:05 +0200 Subject: [PATCH 0690/1786] Adding the new credential --- .travis.yml | 80 +++++++++++++++++----------------- config/travis/deploy.sh | 2 +- config/travis/mvn-settings.xml | 12 ++--- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/.travis.yml b/.travis.yml index c7e290784..d724154b8 100755 --- a/.travis.yml +++ b/.travis.yml @@ -5,10 +5,12 @@ cache: jdk: openjdk11 env: global: - # HCOM_OSSRH_USERNAME - - secure: A1THwDcKNrR/+nHj8Hu8aEjUeh1T1FKKg/sZ3CArAldt7U2IH/DndS5vi8+58B85eDFNByu6bOtqYls13Y9pKWyjY7nEBJtqQ79BFN22G85wZiiVHawFdsdOSN7gMSDQHfbZaJrayliAUuQAgsgqtHPTkgBG8dv3QIVE1G8ILiV0Ui6JYpE+FVysIdeYpcWnhKpjX95jpTLuKqiBfVqgpT6Y24P9No8N37YgtgnYOXwn2u1AdwZ6bbeSria/n+Napi2pTtgTc0zQ4PMaowFv1P6/LuSPCs/XNfuCB9EzfIpXYUtOvoF9KQ0OqtyKrldAlOHC/cGkBWOcA8GNpJ4ONr0oCarZUPI3mV/ecx6q0dpqYF/Smy1Hj5tpYgSiXpDGTGg2fgawmTsr0faU2XbSFp1IWEnib0uQ9PhXUHg01MmnMp2pqCvNzPBjai7Lhquf/ykLqXfgO0ntDsqsTxe24nBKN3Azz5CJrkgjwgNxZMH+DQmNhHWA7QEUYBO2+wIrDNc3vaItpGsU7VrtX2dNPmfDl865ODPJEqClyYFkO7h3E+Zzx1tW4hdDEW6ME5UM6opbI02luOcifC2WxcfCDDaBa/n2KzGIAvThC0N+bdRLQPPNT+Rs0eqOwH/+LrODT9HzpcGgCZ32Cqm59t4xJXrIlcd5pVEEg535HU26638= - # HCOM_OSSRH_PASSWORD - - secure: Bq043/gjNIWaP0t2cniKabnHSSB3LmDnYSBYBqdll/pp/wHTChs5OcW1UamXfVsBY9pF7GpYroLvkqkUV7k5lnA5aFWoJaU/Ehh/WvIwge8cJxF6ie/pxjdnVS5P5aSB39brm8IU97zOoyzT4cdPuMvQSSemwqC/rU5FD5CfO1sb2WRJkJHsY3oP3FHVW3aLldGC1MlsQ95wfIGeGUpx/LtUlZvxf+fNrs83YVW+v2Ibj6+YueTPzKLk5yAuzCh2qG97dkI5XTMRbjxBICCK7GsXaoUCx+Ix+Sa97MlASQzgEYZz77s4TU6h+oV5BLNR+/aW0bpFFXNIVe9m+ZBW4APbVq5tvDXsbEy/7qYrETT5F7ZasCGOGQUgmqqbWuIxB/fcxA4jMvBEniBSo6ifdQkjyoEjWLoQtApsbYCA7Mtg8cVyVHx1oWyQgg+9Q30KPMVkXP8GufPdl3dpAdpzHxYwghtPzVVAlxkAGjHTo/AzVGh4T8qLZwUY3WVtZie6ZYZ1WRpa9dlvLeQ+T42r4buI0/ndpbfQyT5OxrURllMwpk1XZPH7GgCQ+fRalhhsu+32wIVXE/jGTDst2+Z59kv8p8LaKp7H4IU3ZUsuQw3Q41vm3zqBY00t9kyJOVGAzAC/jyeNYEULYUgrkcGlVe+9Zug/F8RCpNsLD2bXtRk= + # Sonatype jira info + - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= + - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= + # EG OSS Sonatype jira info + - secure: NA1LDLSFPjfCJhv4aL4etZlvHKJ4vrqacu3aTVB81QFeMlTGnENRKXsmOhhUNkj6PAB0IfrStlud5EHuTM6LxOGcXov6aoj6grz1Cq9p7groaihFcRMizgp041wXAwl2FA7K8mLCpxP+NbgoaO6KhZYWso3JshKgzQ1THHDHNx423KkqNwyV8ddOzA0TynjGhEZPI40+ruuxgYS6dZk0ObwvdLdJUW2FLZeHKGxvKP7l4t4RseqmwAr47WK+pY7n6NjyWAaqPog/Wsd5XIiyo8AJA0WSdLtUjchE5gBKH7Bd5nw2zx/IqyQuSNZg73QYya1Pko0VW0YVq7fY9pN3D7cVkQVpmvLVAPFcMP32WWaMkzvEA4hFZRa2WShzdDCGA1uleD/v/YlFBKCmKyeIyeUYkd4/JsJOL9PLeFfx7ECpp3ZAFi8tGKiCTueFYLrIuLoOpOn5giB4/724Tkl54wRig5v3njaFFmeLhqW8Tox6KfFJ1qh3R8pEqwhFjOZFcWceURPkKNSOt19LFv7brT2dpFQuynX5I+CtcIqGBT4Jbqwmq7EyYhxx2508d6Gq9nNrOFvGukA1Q4JWyZLsCi+TuNHcxTLXN4AUPjeUmlRWT6hKBdjVxe/T5PLZPA6p9f6Gk+fO2wOS0+e5cwP8xS+osL/mLoG5U180YuKDTYU= + - secure: Fb2ffyOik4TrfXuCPJIbTmkdfy7W3/3nRawgctOO8YeOpUSg356U3tPYWJZeWhq0XzHsIsloYUjdOcYV33E6sau+lHQ67OJEDHbyAHYOIh5l1HrDJVEwXs3S5W+pvDHrxamNi6BRzWDqp78hv56SMLD9vLlP0HOPAvfOosHwdA1Fg8OBaFRWYKSKuq45VdXRx9DTzNQacGiH97V0efzUfDFbuN9AsqTZl3LHcTocS3KLPyo3j2c4YW3/T6RSQJibBjMI1ZbZOrVbQYxZ+zPSKwUv5ucLVSJ2YrNQ+cKTYmOaIka2dBtK9lArbKtRYxvTtXz/fiL1CdD0mEhyP47TFErIWm5GIK5iVehzU9cRzB5s0t6P+D1eUi9uUh7+j5kndYbQb+ksdz1jxkMFw7lI8L0EQi78p+pfV830H199iLFJ8zbyTyce8sb4LNFuKu80DCPm79kpYq4o6bVVmvtLt5etOamKnhB6uq4Ho0ObGVNB+rnnQp03f67MGWV6LF75ati/1v3CGZ9ogjPMM2Tvxa8BttCV/0dKdqxoEJgHCXl91Pf/83B+CK5t4B4lXun1sIGHuqWUGBj3Xt8Ps4tgD/tJ52iXNzKRwyqG3gy6bvKlslu4WfyVKS7BIHQKMowLaoKyQ/h7OQ2NCsPWw+Cws6FVpYZejRyVv3XzOzFEPHg= # GPG_KEYNAME - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE @@ -16,45 +18,43 @@ env: install: skip jobs: include: - - stage: Build - name: Build and Test - install: travis_retry mvn clean install -DskipTests - - stage: Site Build and Quality check - name: Publishing site and performing a code quality check - if: type NOT IN (pull_request) AND tag IS present - before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} - -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} - -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release - deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: "${github_oauth_token}" - keep-history: true - on: - tags: true - - stage: Release - name: Releasing artifacts - if: type NOT IN (pull_request) AND tag IS present - install: skip - after_deploy: skip - before_script: - - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv - -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate - deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true + # If the branch is not master it just builds the application + - stage: "Build" + name: "Build and Test" + install: travis_retry mvn clean install -DskipTests + - stage: "Site Build and Quality check" + name: "Publishing site and performing a code quality check" + if: type NOT IN (pull_request) AND tag IS present + before_deploy: + - mvn versions:set -D newVersion=${TRAVIS_TAG} + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + tags: true + - stage: "Release" + name: "Releasing artifacts" + if: type NOT IN (pull_request) AND tag IS present + install: skip + after_deploy: skip + before_script: + - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d + - mvn versions:set -D newVersion=${TRAVIS_TAG} + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate + deploy: + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true notifications: slack: rooms: - - bull-crew:hTuN6VsJod6aUOU6FWIFiQca + - bull-crew:hTuN6VsJod6aUOU6FWIFiQca on_failure: change on_success: change on_pull_requests: true diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index b273de385..d73d5bc16 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -10,6 +10,6 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn -X deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true fi fi \ No newline at end of file diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 84ca5c569..6a9ccc4e9 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -2,18 +2,18 @@ ossrh - ${env.HCOM_OSSRH_USERNAME} - ${env.HCOM_OSSRH_PASSWORD} + ${env.EG_OSSRH_USERNAME} + ${env.EG_OSSRH_PASSWORD} sonatype-nexus-staging - ${env.HCOM_OSSRH_USERNAME} - ${env.HCOM_OSSRH_PASSWORD} + ${env.EG_OSSRH_USERNAME} + ${env.EG_OSSRH_PASSWORD} sonatype-nexus-snapshots - ${env.HCOM_OSSRH_USERNAME} - ${env.HCOM_OSSRH_PASSWORD} + ${env.EG_OSSRH_USERNAME} + ${env.EG_OSSRH_PASSWORD} From 636c321e94e84e2b8a0d9a570e2cd049a4271f3b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 17:45:53 +0200 Subject: [PATCH 0691/1786] Changed version for release --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index c41d119ed..2c2fd3eda 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8-SNAPSHOT + 1.4.7.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f06ebf24b..a483b5386 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8-SNAPSHOT + 1.4.7.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 3d459da4f..f8cd5e98b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.8-SNAPSHOT + 1.4.7.1-SNAPSHOT pom 2019 From fc227aa834eca2c76ad95be966ddfbd0f937127e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 17:47:45 +0200 Subject: [PATCH 0692/1786] [maven-release-plugin] prepare release 1.4.7.1 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 2c2fd3eda..83e14c321 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7.1-SNAPSHOT + 1.4.7.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index a483b5386..e74306c9c 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7.1-SNAPSHOT + 1.4.7.1 diff --git a/pom.xml b/pom.xml index f8cd5e98b..3811da63c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.7.1-SNAPSHOT + 1.4.7.1 pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.7.1 From 37baf475bf6015b4d961751719e82b8d557c4a37 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 17:47:54 +0200 Subject: [PATCH 0693/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 83e14c321..c41d119ed 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7.1 + 1.4.8-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e74306c9c..f06ebf24b 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7.1 + 1.4.8-SNAPSHOT diff --git a/pom.xml b/pom.xml index 3811da63c..3d459da4f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.7.1 + 1.4.8-SNAPSHOT pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.7.1 + HEAD From 80212a1fcf8a972a364edaa9df4da1909a7bb9c1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Jul 2019 18:05:02 +0200 Subject: [PATCH 0694/1786] Modified changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f5c9ac5c..e6c61e29b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.4.7.1] 2019.07.05 +#### Changed +* Changed sonatype credential + ### [1.4.7] 2019.07.03 #### Added * Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/HotelsDotCom/bull/issues/73)). From a263bb11155ffa492ffd0b357f9d429e69e617df Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Jul 2019 06:34:55 +0200 Subject: [PATCH 0695/1786] modified profiles in order to have one dedicated for signing artifacts --- config/travis/deploy.sh | 3 +-- pom.xml | 42 +++++++++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index d73d5bc16..7b42ff5e6 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,9 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease,sign -DskipTests=true else echo "Deploying snapshot" - gpg --import config/travis/private-key.gpg mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true fi fi \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3d459da4f..0cdb6e549 100644 --- a/pom.xml +++ b/pom.xml @@ -244,20 +244,6 @@ - - org.apache.maven.plugins - maven-gpg-plugin - ${maven.gpg.plugin.version} - - - sign-artifacts - verify - - sign - - - - org.apache.maven.plugins @@ -290,6 +276,34 @@ + + + sign + + true + false + true + true + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven.gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + + + + + check-for-updates From f5c2e7cd6df9493720e46586c4f1f0bc33802173 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Jul 2019 06:55:43 +0200 Subject: [PATCH 0696/1786] modified gpg sign always actvie --- config/travis/mvn-settings.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 6a9ccc4e9..64bc15406 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -24,10 +24,7 @@ - release - - true - + sign gpg ${env.GPG_KEYNAME} From b21a3e0217852566780fcb47c6e5d3943f5514e6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Jul 2019 12:06:48 +0200 Subject: [PATCH 0697/1786] Fixed snapshot deploy release --- config/travis/deploy.sh | 3 +- config/travis/mvn-settings.xml | 5 +++- pom.xml | 52 +++++++++------------------------- 3 files changed, 20 insertions(+), 40 deletions(-) diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 7b42ff5e6..d73d5bc16 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,9 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease,sign -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true else echo "Deploying snapshot" + gpg --import config/travis/private-key.gpg mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true fi fi \ No newline at end of file diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 64bc15406..6a9ccc4e9 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -24,7 +24,10 @@ - sign + release + + true + gpg ${env.GPG_KEYNAME} diff --git a/pom.xml b/pom.xml index 0cdb6e549..9609653d9 100644 --- a/pom.xml +++ b/pom.xml @@ -70,16 +70,6 @@ https://github.com/HotelsDotCom/bull HEAD - - - sonatype-nexus-snapshot - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - @@ -244,6 +234,20 @@ + + org.apache.maven.plugins + maven-gpg-plugin + ${maven.gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + + org.apache.maven.plugins @@ -276,34 +280,6 @@ - - - sign - - true - false - true - true - - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven.gpg.plugin.version} - - - sign-artifacts - verify - - sign - - - - - - - check-for-updates From 498ceb3eb299773f161032a88a819ec62dd6e812 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Jul 2019 12:17:48 +0200 Subject: [PATCH 0698/1786] [maven-release-plugin] prepare release 1.4.7.2 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index c41d119ed..c27ddab4c 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8-SNAPSHOT + 1.4.7.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f06ebf24b..eae8077e4 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8-SNAPSHOT + 1.4.7.2 diff --git a/pom.xml b/pom.xml index 9609653d9..cafb5fc1e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.8-SNAPSHOT + 1.4.7.2 pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.7.2 From d8f5a0fa5fbbc87184fe392b8e32a85c022083d9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Jul 2019 12:17:55 +0200 Subject: [PATCH 0699/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index c27ddab4c..c41d119ed 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7.2 + 1.4.8-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index eae8077e4..f06ebf24b 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7.2 + 1.4.8-SNAPSHOT diff --git a/pom.xml b/pom.xml index cafb5fc1e..9609653d9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.7.2 + 1.4.8-SNAPSHOT pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.7.2 + HEAD From fab0c7840336334a77da59fe56a2e38bbfb860f6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Jul 2019 18:12:23 +0200 Subject: [PATCH 0700/1786] Minor: removed no longer needed settings --- .travis.yml | 3 --- pom.xml | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d724154b8..8e6f704ff 100755 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,6 @@ cache: jdk: openjdk11 env: global: - # Sonatype jira info - - secure: nawOdRhJ1DX86SZhcS5JeHncU049DVvlG3m7OHkHrldwbL+jOIHCzjl7wBL0LnqdwqFXbntfPLnigLQFZ1eFNgXVesZKDQbyzazGF3nZoJWSIGtuAt0GbORxyzW96TwowE1AP4og0FLpdCCwQJ1cRjTiaPnZFl6yJ2gwdaQBmf50IH+WrEWvkphd2feB8uqSv0GgKtVCwJnBwhHrPQrE2DAuA98lSDGhWJYASdRRVJ8NXJ+1CtvCTUacaEiiRev7JK15Wz7HS3GGyDdcxg9mBoYFs2HhOn0nXMiZqa66VbVSJWGroCve4qngri7DnBzeeJUguuBKQzHOYtfbyNgxyxlQrT6PKxs7YBcfMCcszR6vTlI3qb6tsMS6BWyLvGOgJNRoGa1iw/+Uc1hKBOf+Wtq4q4EeJ27c6i4pv4aVCTEP26rvT/CYXi05wTYkH0PtZaPuKpCqZgp+kIAo2LpdrhMXf6QbsBCWP0431T7r+d79f//D/IBr4S00iQBukPxU4shujCdbsKIet7hBcAhjbGUkx1odMNiaSn2JTs3KJTYq2adK5zC5ufkK+rTDCAgaYeuMIgZwuSopNpXTAV17OavJQ2v+iP/3+lINpKI7kHuT3qYF0rFyTX0ZBApZE9XMscozuLWKW3aIlqvuiPPULPY1mZHBPBHc/LPG3GlNXeg= - - secure: OqOKGAvbqC1uQurrPAVknHxSZKzgcXoKPXvgJMPcito2PFe3jRZuCXWWDAPnEPNjtH/O/jC37Ne07VQBq3KJ3d83WPniC+d6MXwsh4cP9tvIGT0cwAB+iEv+BkAkTHAGVDqdDYUJCJfvq+XMDujpR7ijNKt9HbSu3BPMUZlNovmY7WL+4Ei+KTj2bi/5jb8SkBKqGEpvL245r5w9+/NUPY7ifY0F+c8elvtJ44U65BSvBBw9LFrzYvcS812e1L5iRswTDGbqcXCaqVsP21S+SsjXBmtFsy2IVutmGnTEfLSZ5Y9JbR96ux/49YfBp3FRDwqIwztm4Y4cTij1J5dC/bpCAElOPhFaRk/luGHr44Sz90ZxqsqDH1XSmjDNNlpxUHSg9bhuZRqdseomokFHR9mGKxGBQYe5+MyciyGM/9AmTW87FdqNuNKNpJvhBuaPoJR1IqVmCgPYfOEyKHbPNapr42NgrmnXnDQvGjCcuEbk1WSTHe0Mp8n+0FVlk2cRSwd5juniOz4k9FKeTp8CCqQz3XR+x811z7HUMROSg6IKIA/XC35HIqfAGYfqUXktWobGiTbyngoBE4feTqtCHtoZAEcuzlWtGmTlVGm4ELJJ8pf6hhjWCihFeY62XNAcPeAUg8o5WE9MQV32rjCHVE2AW0iV6UWRh8XJwUFCX/I= # EG OSS Sonatype jira info - secure: NA1LDLSFPjfCJhv4aL4etZlvHKJ4vrqacu3aTVB81QFeMlTGnENRKXsmOhhUNkj6PAB0IfrStlud5EHuTM6LxOGcXov6aoj6grz1Cq9p7groaihFcRMizgp041wXAwl2FA7K8mLCpxP+NbgoaO6KhZYWso3JshKgzQ1THHDHNx423KkqNwyV8ddOzA0TynjGhEZPI40+ruuxgYS6dZk0ObwvdLdJUW2FLZeHKGxvKP7l4t4RseqmwAr47WK+pY7n6NjyWAaqPog/Wsd5XIiyo8AJA0WSdLtUjchE5gBKH7Bd5nw2zx/IqyQuSNZg73QYya1Pko0VW0YVq7fY9pN3D7cVkQVpmvLVAPFcMP32WWaMkzvEA4hFZRa2WShzdDCGA1uleD/v/YlFBKCmKyeIyeUYkd4/JsJOL9PLeFfx7ECpp3ZAFi8tGKiCTueFYLrIuLoOpOn5giB4/724Tkl54wRig5v3njaFFmeLhqW8Tox6KfFJ1qh3R8pEqwhFjOZFcWceURPkKNSOt19LFv7brT2dpFQuynX5I+CtcIqGBT4Jbqwmq7EyYhxx2508d6Gq9nNrOFvGukA1Q4JWyZLsCi+TuNHcxTLXN4AUPjeUmlRWT6hKBdjVxe/T5PLZPA6p9f6Gk+fO2wOS0+e5cwP8xS+osL/mLoG5U180YuKDTYU= - secure: Fb2ffyOik4TrfXuCPJIbTmkdfy7W3/3nRawgctOO8YeOpUSg356U3tPYWJZeWhq0XzHsIsloYUjdOcYV33E6sau+lHQ67OJEDHbyAHYOIh5l1HrDJVEwXs3S5W+pvDHrxamNi6BRzWDqp78hv56SMLD9vLlP0HOPAvfOosHwdA1Fg8OBaFRWYKSKuq45VdXRx9DTzNQacGiH97V0efzUfDFbuN9AsqTZl3LHcTocS3KLPyo3j2c4YW3/T6RSQJibBjMI1ZbZOrVbQYxZ+zPSKwUv5ucLVSJ2YrNQ+cKTYmOaIka2dBtK9lArbKtRYxvTtXz/fiL1CdD0mEhyP47TFErIWm5GIK5iVehzU9cRzB5s0t6P+D1eUi9uUh7+j5kndYbQb+ksdz1jxkMFw7lI8L0EQi78p+pfV830H199iLFJ8zbyTyce8sb4LNFuKu80DCPm79kpYq4o6bVVmvtLt5etOamKnhB6uq4Ho0ObGVNB+rnnQp03f67MGWV6LF75ati/1v3CGZ9ogjPMM2Tvxa8BttCV/0dKdqxoEJgHCXl91Pf/83B+CK5t4B4lXun1sIGHuqWUGBj3Xt8Ps4tgD/tJ52iXNzKRwyqG3gy6bvKlslu4WfyVKS7BIHQKMowLaoKyQ/h7OQ2NCsPWw+Cws6FVpYZejRyVv3XzOzFEPHg= diff --git a/pom.xml b/pom.xml index 9609653d9..6526e156f 100644 --- a/pom.xml +++ b/pom.xml @@ -540,6 +540,7 @@ org.codehaus.mojo versions-maven-plugin + ${maven.versions.plugin.version} file:///${project.basedir}/config/maven/versions-plugin-rules.xml From a0c3594129855afe026e8837c3aa415263951ef3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Jul 2019 18:43:15 +0200 Subject: [PATCH 0701/1786] Updated changelog file with the new release --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c61e29b..43a835782 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.4.7.1] 2019.07.05 +### [1.4.7.1]git status [1.4.7.2] 2019.07.05 #### Changed * Changed sonatype credential From 220cd75d92871b904928a9730ee0f24a2a8d9fe2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 7 Jul 2019 17:54:49 +0200 Subject: [PATCH 0702/1786] * Added all modules required for the transformation project: - bull-transformer-generator-parent - transformer-generator-core - transformer-bytecode-adapter - transformer-generator-registry - transformer-source-adapter * Created new profile: transformer-generator for build the transformer modules --- .../transformer-bytecode-adapter/pom.xml | 30 ++++++++++++++++ .../config/logging/logback-appenders.xml | 30 ++++++++++++++++ .../config/logging/logback-properties.xml | 5 +++ .../src/test/resources/logback-test.xml | 36 +++++++++++++++++++ .../org.mockito.plugins.MockMaker | 1 + .../transformer-generator-registry/pom.xml | 30 ++++++++++++++++ .../config/logging/logback-appenders.xml | 30 ++++++++++++++++ .../config/logging/logback-properties.xml | 5 +++ .../src/test/resources/logback-test.xml | 36 +++++++++++++++++++ .../org.mockito.plugins.MockMaker | 1 + .../transformer-source-adapter/pom.xml | 30 ++++++++++++++++ .../config/logging/logback-appenders.xml | 30 ++++++++++++++++ .../config/logging/logback-properties.xml | 5 +++ .../src/test/resources/logback-test.xml | 36 +++++++++++++++++++ .../org.mockito.plugins.MockMaker | 1 + pom.xml | 7 ++++ 16 files changed, 313 insertions(+) create mode 100644 bull-transformation-generator/transformer-bytecode-adapter/pom.xml create mode 100644 bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-appenders.xml create mode 100644 bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-properties.xml create mode 100644 bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/logback-test.xml create mode 100644 bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker create mode 100644 bull-transformation-generator/transformer-generator-registry/pom.xml create mode 100644 bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-appenders.xml create mode 100644 bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-properties.xml create mode 100644 bull-transformation-generator/transformer-generator-registry/src/test/resources/logback-test.xml create mode 100644 bull-transformation-generator/transformer-generator-registry/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker create mode 100644 bull-transformation-generator/transformer-source-adapter/pom.xml create mode 100644 bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-appenders.xml create mode 100644 bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-properties.xml create mode 100644 bull-transformation-generator/transformer-source-adapter/src/test/resources/logback-test.xml create mode 100644 bull-transformation-generator/transformer-source-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bull-transformation-generator/transformer-bytecode-adapter/pom.xml b/bull-transformation-generator/transformer-bytecode-adapter/pom.xml new file mode 100644 index 000000000..6008b5d1b --- /dev/null +++ b/bull-transformation-generator/transformer-bytecode-adapter/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + BULL - Transformer Bytecode Adapter + transformer-bytecode-adapter + jar + Transformer Bytecode Adapter + + + com.hotels.beans + bull-transformer-generator-parent + 1.4.8-SNAPSHOT + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-appenders.xml b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-appenders.xml new file mode 100644 index 000000000..3bfd17005 --- /dev/null +++ b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-appenders.xml @@ -0,0 +1,30 @@ + + + + + + + + + ${LOG_PATTERN} + + + + + + ${ROOT_LOG_DIR}/bean-utils-library.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip + + 30 + + 5MB + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-properties.xml b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-properties.xml new file mode 100644 index 000000000..934b4e88b --- /dev/null +++ b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-properties.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/logback-test.xml b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/logback-test.xml new file mode 100644 index 000000000..4da7aad36 --- /dev/null +++ b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/logback-test.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-registry/pom.xml b/bull-transformation-generator/transformer-generator-registry/pom.xml new file mode 100644 index 000000000..4ab86e7a2 --- /dev/null +++ b/bull-transformation-generator/transformer-generator-registry/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + BULL - Transformer Generator Registry + transformer-generator-registry + jar + Transformer Generator Registry + + + com.hotels.beans + bull-transformer-generator-parent + 1.4.8-SNAPSHOT + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-appenders.xml b/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-appenders.xml new file mode 100644 index 000000000..3bfd17005 --- /dev/null +++ b/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-appenders.xml @@ -0,0 +1,30 @@ + + + + + + + + + ${LOG_PATTERN} + + + + + + ${ROOT_LOG_DIR}/bean-utils-library.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip + + 30 + + 5MB + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-properties.xml b/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-properties.xml new file mode 100644 index 000000000..934b4e88b --- /dev/null +++ b/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-properties.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/bull-transformation-generator/transformer-generator-registry/src/test/resources/logback-test.xml b/bull-transformation-generator/transformer-generator-registry/src/test/resources/logback-test.xml new file mode 100644 index 000000000..4da7aad36 --- /dev/null +++ b/bull-transformation-generator/transformer-generator-registry/src/test/resources/logback-test.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-registry/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-transformation-generator/transformer-generator-registry/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/bull-transformation-generator/transformer-generator-registry/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/bull-transformation-generator/transformer-source-adapter/pom.xml b/bull-transformation-generator/transformer-source-adapter/pom.xml new file mode 100644 index 000000000..d8c7a0bcf --- /dev/null +++ b/bull-transformation-generator/transformer-source-adapter/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + BULL - Transformer Source Adapter + transformer-source-adapter + jar + Transformer Source Adapter + + + com.hotels.beans + bull-transformer-generator-parent + 1.4.8-SNAPSHOT + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-appenders.xml b/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-appenders.xml new file mode 100644 index 000000000..3bfd17005 --- /dev/null +++ b/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-appenders.xml @@ -0,0 +1,30 @@ + + + + + + + + + ${LOG_PATTERN} + + + + + + ${ROOT_LOG_DIR}/bean-utils-library.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip + + 30 + + 5MB + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-properties.xml b/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-properties.xml new file mode 100644 index 000000000..934b4e88b --- /dev/null +++ b/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-properties.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/bull-transformation-generator/transformer-source-adapter/src/test/resources/logback-test.xml b/bull-transformation-generator/transformer-source-adapter/src/test/resources/logback-test.xml new file mode 100644 index 000000000..4da7aad36 --- /dev/null +++ b/bull-transformation-generator/transformer-source-adapter/src/test/resources/logback-test.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-source-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-transformation-generator/transformer-source-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/bull-transformation-generator/transformer-source-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3d459da4f..87a32ccf1 100644 --- a/pom.xml +++ b/pom.xml @@ -303,6 +303,13 @@ + + + transformer-generator + + bull-transformation-generator + + From acb389da3e8af99e719a738d05207fb8967d0728 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 7 Jul 2019 17:56:01 +0200 Subject: [PATCH 0703/1786] Added poms --- bull-transformation-generator/pom.xml | 24 +++++++++++++ .../transformer-generator-core/pom.xml | 30 ++++++++++++++++ .../config/logging/logback-appenders.xml | 30 ++++++++++++++++ .../config/logging/logback-properties.xml | 5 +++ .../src/test/resources/logback-test.xml | 36 +++++++++++++++++++ .../org.mockito.plugins.MockMaker | 1 + 6 files changed, 126 insertions(+) create mode 100644 bull-transformation-generator/pom.xml create mode 100644 bull-transformation-generator/transformer-generator-core/pom.xml create mode 100644 bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-appenders.xml create mode 100644 bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-properties.xml create mode 100644 bull-transformation-generator/transformer-generator-core/src/test/resources/logback-test.xml create mode 100644 bull-transformation-generator/transformer-generator-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bull-transformation-generator/pom.xml b/bull-transformation-generator/pom.xml new file mode 100644 index 000000000..693fddc7c --- /dev/null +++ b/bull-transformation-generator/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + BULL - Transformer Generator + bull-transformer-generator-parent + pom + 2019 + TODO: description + + + com.hotels.beans + bean-utils-library-parent + 1.4.8-SNAPSHOT + + + + transformer-bytecode-adapter + transformer-source-adapter + transformer-generator-registry + transformer-generator-core + + + + diff --git a/bull-transformation-generator/transformer-generator-core/pom.xml b/bull-transformation-generator/transformer-generator-core/pom.xml new file mode 100644 index 000000000..b6dda23a5 --- /dev/null +++ b/bull-transformation-generator/transformer-generator-core/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + BULL - Transformer Generator Core + transformer-generator-core + jar + Contains the core functions required for the transformer generation + + + com.hotels.beans + bull-transformer-generator-parent + 1.4.8-SNAPSHOT + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-appenders.xml b/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-appenders.xml new file mode 100644 index 000000000..3bfd17005 --- /dev/null +++ b/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-appenders.xml @@ -0,0 +1,30 @@ + + + + + + + + + ${LOG_PATTERN} + + + + + + ${ROOT_LOG_DIR}/bean-utils-library.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip + + 30 + + 5MB + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-properties.xml b/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-properties.xml new file mode 100644 index 000000000..934b4e88b --- /dev/null +++ b/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-properties.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/bull-transformation-generator/transformer-generator-core/src/test/resources/logback-test.xml b/bull-transformation-generator/transformer-generator-core/src/test/resources/logback-test.xml new file mode 100644 index 000000000..4da7aad36 --- /dev/null +++ b/bull-transformation-generator/transformer-generator-core/src/test/resources/logback-test.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-transformation-generator/transformer-generator-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/bull-transformation-generator/transformer-generator-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file From 9cd5abb5350ad3295be809e950b714fda67230a8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Jul 2019 10:39:18 +0200 Subject: [PATCH 0704/1786] - Added new class for providing conversion function as additional feature - Added possibility to disable the automatic primitive types conversion --- .../main/java/com/hotels/beans/BeanUtils.java | 12 +++- .../transformer/AbstractTransformer.java | 9 +++ .../hotels/beans/transformer/Transformer.java | 7 ++ .../beans/transformer/TransformerImpl.java | 2 +- .../transformer/TransformerSettings.java | 7 ++ .../java/com/hotels/beans/BeanUtilsTest.java | 15 +++++ .../beans/transformer/TransformerTest.java | 30 +++++++++ .../hotels/beans/conversion/Converter.java | 46 +++++++++++++ .../beans/conversion/ConverterImpl.java | 66 +++++++++++++++++++ .../analyzer/ConversionAnalyzer.java | 16 ++--- .../error/NoConverterAvailableException.java | 32 +++++++++ .../beans/conversion/error/package-info.java | 20 ++++++ .../impl/AbstractConversionProcessorTest.java | 32 +++++++++ .../impl/FloatConversionProcessorTest.java | 48 ++++++-------- .../impl/IntegerConversionProcessorTest.java | 12 +--- .../impl/LongConversionProcessorTest.java | 47 ++++++------- 16 files changed, 324 insertions(+), 77 deletions(-) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/error/NoConverterAvailableException.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java b/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java index 78d46ce7f..ac41b0162 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java @@ -20,6 +20,8 @@ import java.util.function.Function; +import com.hotels.beans.conversion.Converter; +import com.hotels.beans.conversion.ConverterImpl; import com.hotels.beans.transformer.Transformer; import com.hotels.beans.transformer.TransformerImpl; import com.hotels.beans.validator.Validator; @@ -58,7 +60,7 @@ public static Function getTransformer(final Transformer beanTransfo /** * Returns a Bean Transformer. - * @return a Bean Transformer instance. + * @return a {@link Transformer} instance. */ public final Transformer getTransformer() { return new TransformerImpl(); @@ -72,4 +74,12 @@ public final Validator getValidator() { return new ValidatorImpl(); } + /** + * Returns a primitive type converter. + * @return a {@link Converter} instance. + */ + public final Converter getPrimitiveTypeConverter() { + return new ConverterImpl(); + } + } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 69bac897e..5a9a2f45d 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -173,6 +173,15 @@ public Transformer setDefaultValueSetEnabled(final boolean defaultValueSetEnable return this; } + /** + * {@inheritDoc} + */ + @Override + public Transformer setDefaultPrimitiveTypeConversionEnabled(final boolean defaultPrimitiveTypeConversionEnabled) { + settings.setDefaultPrimitiveTypeConversionEnabled(defaultPrimitiveTypeConversionEnabled); + return this; + } + /** * {@inheritDoc} */ diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java index 4ec19aec7..8e1632288 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -124,4 +124,11 @@ public interface Transformer { * @return the {@link Transformer} instance */ Transformer setDefaultValueSetEnabled(boolean defaultValueSetEnabled); + + /** + * It allows to enable/disable the automatic conversion of primitive types. + * @param defaultPrimitiveTypeConversionEnabled if true primitive types are transformed automatically. By default it's false. + * @return the {@link Transformer} instance + */ + Transformer setDefaultPrimitiveTypeConversionEnabled(boolean defaultPrimitiveTypeConversionEnabled); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index d7cd3345f..37a8209f6 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -400,7 +400,7 @@ private List getTransformerFunction(final Class sourceObjec final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { List fieldTransformers = new ArrayList<>(); String fieldTransformerKey = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - if (isDestinationFieldPrimitiveType) { + if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType) { conversionAnalyzer.getConversionFunction(sourceObjectClass, field.getType()) .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(fieldTransformerKey, conversionFunction))); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 30255f922..1a9c15c36 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -82,4 +82,11 @@ final class TransformerSettings { */ @Setter private boolean defaultValueSetEnabled = true; + + /** + * It allows to enable/disable the automatic conversion of primitive types. + * If set to true primitive types are transformed automatically. + */ + @Setter + private boolean defaultPrimitiveTypeConversionEnabled = true; } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java index 58e8ea26a..8fd3b0f7f 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -34,6 +34,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.Converter; import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.immutable.ImmutableToFoo; @@ -151,6 +152,20 @@ public void testValidateThrowsExceptionIfTheGivenBeanIsInvalid() { underTest.getValidator().validate(immutableToFoo); } + /** + * Test that a {@link com.hotels.beans.conversion.Converter} is correctly returned. + */ + @Test + public void testGetPrimitiveTypeConverterWorksProperly() { + //GIVEN + + //WHEN + Converter actual = underTest.getPrimitiveTypeConverter(); + + //THEN + assertNotNull(actual); + } + /** * Creates a {@link FromFooSimple} instance. * @return the {@link FromFooSimple} instance. diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 05f1b1240..00b4f9048 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -157,4 +157,34 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro //WHEN getSourceFieldValueMethod.invoke(underTest, null, null, null, false); } + + /** + * Test that by default the primitive type conversion is disabled. + */ + @Test + public void testThatDefaultPrimitiveTypeConversionIsDisabledByDefault() { + //GIVEN + + //WHEN + boolean actual = underTest.settings.isDefaultPrimitiveTypeConversionEnabled(); + + //THEN + assertFalse(actual); + } + + /** + * Test that the primitive type conversion is correctly enabled. + */ + @Test + public void testThatDefaultPrimitiveTypeConversionIsCorrectlyEnabled() { + //GIVEN + underTest.setDefaultPrimitiveTypeConversionEnabled(true); + + //WHEN + boolean actual = underTest.settings.isDefaultPrimitiveTypeConversionEnabled(); + + //THEN + assertTrue(actual); + underTest.setDefaultPrimitiveTypeConversionEnabled(false); + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java new file mode 100644 index 000000000..de7735646 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import java.util.Optional; +import java.util.function.Function; + +/** + * It allows to convert any primitive type into another. + */ +public interface Converter { + /** + * It provides a conversion function for the given primitive type into the other. + * @param sourceClass source field class + * @param targetClass the destination field class + * @return an {@link Optional} containing the conversion function (if exists) + */ + Optional> getConversionFunction(Class sourceClass, Class targetClass); + + + /** + * Converts a given primitive value into the given type. + * @param valueToConvert the value to be converted + * @param targetClass the destination field class + * @return the converted value + * @param the value to convert type + * @param the target object type + * @throws com.hotels.beans.conversion.error.NoConverterAvailableException in case there is no converter for the given class + * @throws IllegalArgumentException in case the destination field type is null. + */ + K convertValue(T valueToConvert, Class targetClass); +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java new file mode 100644 index 000000000..65c337dc0 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +import static java.util.Objects.isNull; + +import java.util.Optional; +import java.util.function.Function; + +import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; +import com.hotels.beans.conversion.error.NoConverterAvailableException; +import com.hotels.beans.validator.Validator; + +/** + * This class provides method for converting a primitive input into another. + */ +public class ConverterImpl implements Converter { + /** + * Conversion analyzer. It allows to automatically convert common field types. + */ + private final ConversionAnalyzer conversionAnalyzer; + + /** + * Default constructor. + */ + public ConverterImpl() { + conversionAnalyzer = new ConversionAnalyzer(); + } + + /** + * {@inheritDoc} + */ + @Override + public Optional> getConversionFunction(final Class sourceClass, final Class targetClass) { + return conversionAnalyzer.getConversionFunction(sourceClass, targetClass); + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public K convertValue(final T valueToConvert, final Class targetClass) { + Validator.notNull(targetClass, "The destination field type cannot be null."); + if (isNull(valueToConvert)) { + return null; + } + return (K) getConversionFunction(valueToConvert.getClass(), targetClass) + .map(processor -> processor.apply(targetClass)) + .orElseThrow(() -> new NoConverterAvailableException("No converter available for type: " + targetClass.getName())); + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 46f850190..402f29043 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -40,7 +40,7 @@ import com.hotels.beans.utils.ClassUtils; /** - * This class analyzes the two classes received in input, and returns the conversion processor to be used. + * This class provides method for converting a primitive input into another. */ public final class ConversionAnalyzer { /** @@ -62,18 +62,18 @@ public ConversionAnalyzer() { /** * Analyzes Fields given as input and returns the conversion processor. - * @param sourceFieldType source field class - * @param destinationFieldType the destination field class + * @param sourceClass source field class + * @param targetClass the destination field class * @return an {@link Optional} containing the conversion function (if exists) */ @SuppressWarnings("unchecked") - public Optional> getConversionFunction(final Class sourceFieldType, final Class destinationFieldType) { - final String cacheKey = "ConversionFunction-" + sourceFieldType.getName() + "-" + destinationFieldType.getName(); + public Optional> getConversionFunction(final Class sourceClass, final Class targetClass) { + final String cacheKey = "ConversionFunction-" + sourceClass.getName() + "-" + targetClass.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional conversionFunction = empty(); - if (!destinationFieldType.getSimpleName().equalsIgnoreCase(sourceFieldType.getSimpleName()) && classUtils.isPrimitiveType(sourceFieldType)) { - conversionFunction = ofNullable(getConversionProcessor(destinationFieldType)) - .flatMap(cp -> getTypeConversionFunction(cp, sourceFieldType)); + if (!targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName()) && classUtils.isPrimitiveType(sourceClass)) { + conversionFunction = ofNullable(getConversionProcessor(targetClass)) + .flatMap(cp -> getTypeConversionFunction(cp, sourceClass)); } CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); return conversionFunction; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/error/NoConverterAvailableException.java b/bull-converter/src/main/java/com/hotels/beans/conversion/error/NoConverterAvailableException.java new file mode 100644 index 000000000..67b4a2445 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/error/NoConverterAvailableException.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.error; + +/** + * Converter not available exception class. + */ +public class NoConverterAvailableException extends RuntimeException { + /** + * Constructs a new {@link NoConverterAvailableException} with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a call to {@link #initCause}. + * @param message the detail message. The detail message is saved for later + * retrieval by the {@link #getMessage()} method. + */ + public NoConverterAvailableException(final String message) { + super(message); + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java new file mode 100644 index 000000000..2b79dbaa4 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Converter module exceptions. + */ +package com.hotels.beans.conversion.error; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java new file mode 100644 index 000000000..1a601c60f --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +/** + * Abstract class containing all methods/fields common to all Conversion Processor test classes. + */ +public abstract class AbstractConversionProcessorTest { + static final Byte BYTE_VALUE = 10; + static final Short SHORT_VALUE = 10; + static final Integer INTEGER_VALUE = 10; + static final Long LONG_VALUE = 10L; + static final Float FLOAT_VALUE = 10f; + static final Double DOUBLE_VALUE = 10.51; + static final char CHAR_VALUE = 'c'; + static final Boolean BOOLEAN_VALUE = Boolean.TRUE; + static final String STRING_VALUE = "140"; +} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java index 6a78d2f71..d700e600c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.lang.Float.valueOf; + import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -28,7 +29,7 @@ /** * Unit test for {@link FloatConversionProcessor}. */ -public class FloatConversionProcessorTest { +public class FloatConversionProcessorTest extends AbstractConversionProcessorTest { /** * The class to be tested. */ @@ -46,109 +47,100 @@ public void beforeClass() { @Test public void testConvertByteShouldReturnProperResult() { // GIVEN - Byte expected = 10; // WHEN - Float actual = underTest.convertByte().apply(expected); + Float actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals((Float) expected.floatValue(), actual); + assertEquals((Float) BYTE_VALUE.floatValue(), actual); } @Test public void testConvertShortShouldReturnProperResult() { // GIVEN - Short expected = 10; // WHEN - Float actual = underTest.convertShort().apply(expected); + Float actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals((Float) expected.floatValue(), actual); + assertEquals((Float) SHORT_VALUE.floatValue(), actual); } @Test public void testConvertIntegerShouldReturnProperResult() { // GIVEN - Integer expected = 10; // WHEN - Float actual = underTest.convertInteger().apply(expected); + Float actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals((Float) expected.floatValue(), actual); + assertEquals((Float) INTEGER_VALUE.floatValue(), actual); } @Test public void testConvertLongShouldReturnProperResult() { // GIVEN - Long expected = 10L; // WHEN - Float actual = underTest.convertLong().apply(expected); + Float actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals((Float) expected.floatValue(), actual); + assertEquals((Float) LONG_VALUE.floatValue(), actual); } @Test public void testConvertFloatShouldReturnProperResult() { // GIVEN - Float expected = 10f; // WHEN - Float actual = underTest.convertFloat().apply(expected); + Float actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals(expected, actual); + assertEquals(FLOAT_VALUE, actual); } @Test public void testConvertDoubleShouldReturnProperResult() { // GIVEN - Double expected = 10.51; // WHEN - Float actual = underTest.convertDouble().apply(expected); + Float actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals((Float) expected.floatValue(), actual); + assertEquals((Float) DOUBLE_VALUE.floatValue(), actual); } @Test public void testConvertCharacterShouldReturnProperResult() { // GIVEN - char expected = 'c'; // WHEN - Float actual = underTest.convertCharacter().apply(expected); + Float actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(Float.valueOf(getNumericValue(expected)), actual); + assertEquals(Float.valueOf(getNumericValue(CHAR_VALUE)), actual); } @Test public void testConvertBooleanShouldReturnProperResult() { // GIVEN - Boolean expected = true; // WHEN - Float actual = underTest.convertBoolean().apply(expected); + Float actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); // THEN - assertEquals(expected, actual.equals(1f)); + assertEquals(BOOLEAN_VALUE, actual.equals(1f)); } @Test public void testConvertStringShouldReturnProperResult() { // GIVEN - String expected = "140"; // WHEN - Float actual = underTest.convertString().apply(expected); + Float actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(valueOf(expected), actual); + assertEquals(valueOf(STRING_VALUE), actual); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java index 74fad0d28..825d983ae 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java @@ -29,17 +29,7 @@ /** * Unit test for {@link IntegerConversionProcessor}. */ -public class IntegerConversionProcessorTest { - private static final Byte BYTE_VALUE = 10; - private static final Short SHORT_VALUE = 10; - private static final Integer INTEGER_VALUE = 10; - private static final Long LONG_VALUE = 10L; - private static final Float FLOAT_VALUE = 10f; - private static final Double DOUBLE_VALUE = 10.51; - private static final char CHAR_VALUE = 'c'; - private static final Boolean BOOLEAN_VALUE = Boolean.TRUE; - private static final String STRING_VALUE = "140"; - +public class IntegerConversionProcessorTest extends AbstractConversionProcessorTest { /** * The class to be tested. */ diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java index 00f369ca8..346f24b82 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java @@ -29,7 +29,7 @@ /** * Unit test for {@link LongConversionProcessor}. */ -public class LongConversionProcessorTest { +public class LongConversionProcessorTest extends AbstractConversionProcessorTest { /** * The class to be tested. */ @@ -47,109 +47,100 @@ public void beforeClass() { @Test public void testConvertByteShouldReturnProperResult() { // GIVEN - Byte expected = 10; // WHEN - Long actual = underTest.convertByte().apply(expected); + Long actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals((Long) expected.longValue(), actual); + assertEquals((Long) BYTE_VALUE.longValue(), actual); } @Test public void testConvertShortShouldReturnProperResult() { // GIVEN - Short expected = 10; // WHEN - Long actual = underTest.convertShort().apply(expected); + Long actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals((Long) expected.longValue(), actual); + assertEquals((Long) SHORT_VALUE.longValue(), actual); } @Test public void testConvertIntegerShouldReturnProperResult() { // GIVEN - Integer expected = 10; // WHEN - Long actual = underTest.convertInteger().apply(expected); + Long actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals((Long) expected.longValue(), actual); + assertEquals((Long) INTEGER_VALUE.longValue(), actual); } @Test public void testConvertLongShouldReturnProperResult() { // GIVEN - Long expected = 10L; // WHEN - Long actual = underTest.convertLong().apply(expected); + Long actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals(expected, actual); + assertEquals(LONG_VALUE, actual); } @Test public void testConvertFloatShouldReturnProperResult() { // GIVEN - Float expected = 10f; // WHEN - Long actual = underTest.convertFloat().apply(expected); + Long actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals((Long) expected.longValue(), actual); + assertEquals((Long) FLOAT_VALUE.longValue(), actual); } @Test public void testConvertDoubleShouldReturnProperResult() { // GIVEN - Double expected = 10.51; // WHEN - Long actual = underTest.convertDouble().apply(expected); + Long actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals((Long) expected.longValue(), actual); + assertEquals((Long) DOUBLE_VALUE.longValue(), actual); } @Test public void testConvertCharacterShouldReturnProperResult() { // GIVEN - char expected = 'c'; // WHEN - Long actual = underTest.convertCharacter().apply(expected); + Long actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(valueOf(getNumericValue(expected)), actual); + assertEquals(valueOf(getNumericValue(CHAR_VALUE)), actual); } @Test public void testConvertBooleanShouldReturnProperResult() { // GIVEN - Boolean expected = true; // WHEN - Long actual = underTest.convertBoolean().apply(expected); + Long actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); // THEN - assertEquals(expected, actual.equals(1L)); + assertEquals(BOOLEAN_VALUE, actual.equals(1L)); } @Test public void testConvertStringShouldReturnProperResult() { // GIVEN - String expected = "140"; // WHEN - Long actual = underTest.convertString().apply(expected); + Long actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(valueOf(expected), actual); + assertEquals(valueOf(STRING_VALUE), actual); } } From d9bd6f340af4dda03cd615e2f3adb89258384980 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Jul 2019 10:46:12 +0200 Subject: [PATCH 0705/1786] Changed sonatype credential var names as per PR --- .travis.yml | 6 +++--- config/travis/mvn-settings.xml | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8e6f704ff..20c7e144a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,9 @@ cache: jdk: openjdk11 env: global: - # EG OSS Sonatype jira info - - secure: NA1LDLSFPjfCJhv4aL4etZlvHKJ4vrqacu3aTVB81QFeMlTGnENRKXsmOhhUNkj6PAB0IfrStlud5EHuTM6LxOGcXov6aoj6grz1Cq9p7groaihFcRMizgp041wXAwl2FA7K8mLCpxP+NbgoaO6KhZYWso3JshKgzQ1THHDHNx423KkqNwyV8ddOzA0TynjGhEZPI40+ruuxgYS6dZk0ObwvdLdJUW2FLZeHKGxvKP7l4t4RseqmwAr47WK+pY7n6NjyWAaqPog/Wsd5XIiyo8AJA0WSdLtUjchE5gBKH7Bd5nw2zx/IqyQuSNZg73QYya1Pko0VW0YVq7fY9pN3D7cVkQVpmvLVAPFcMP32WWaMkzvEA4hFZRa2WShzdDCGA1uleD/v/YlFBKCmKyeIyeUYkd4/JsJOL9PLeFfx7ECpp3ZAFi8tGKiCTueFYLrIuLoOpOn5giB4/724Tkl54wRig5v3njaFFmeLhqW8Tox6KfFJ1qh3R8pEqwhFjOZFcWceURPkKNSOt19LFv7brT2dpFQuynX5I+CtcIqGBT4Jbqwmq7EyYhxx2508d6Gq9nNrOFvGukA1Q4JWyZLsCi+TuNHcxTLXN4AUPjeUmlRWT6hKBdjVxe/T5PLZPA6p9f6Gk+fO2wOS0+e5cwP8xS+osL/mLoG5U180YuKDTYU= - - secure: Fb2ffyOik4TrfXuCPJIbTmkdfy7W3/3nRawgctOO8YeOpUSg356U3tPYWJZeWhq0XzHsIsloYUjdOcYV33E6sau+lHQ67OJEDHbyAHYOIh5l1HrDJVEwXs3S5W+pvDHrxamNi6BRzWDqp78hv56SMLD9vLlP0HOPAvfOosHwdA1Fg8OBaFRWYKSKuq45VdXRx9DTzNQacGiH97V0efzUfDFbuN9AsqTZl3LHcTocS3KLPyo3j2c4YW3/T6RSQJibBjMI1ZbZOrVbQYxZ+zPSKwUv5ucLVSJ2YrNQ+cKTYmOaIka2dBtK9lArbKtRYxvTtXz/fiL1CdD0mEhyP47TFErIWm5GIK5iVehzU9cRzB5s0t6P+D1eUi9uUh7+j5kndYbQb+ksdz1jxkMFw7lI8L0EQi78p+pfV830H199iLFJ8zbyTyce8sb4LNFuKu80DCPm79kpYq4o6bVVmvtLt5etOamKnhB6uq4Ho0ObGVNB+rnnQp03f67MGWV6LF75ati/1v3CGZ9ogjPMM2Tvxa8BttCV/0dKdqxoEJgHCXl91Pf/83B+CK5t4B4lXun1sIGHuqWUGBj3Xt8Ps4tgD/tJ52iXNzKRwyqG3gy6bvKlslu4WfyVKS7BIHQKMowLaoKyQ/h7OQ2NCsPWw+Cws6FVpYZejRyVv3XzOzFEPHg= + # HCOM OSS Sonatype jira info + - secure: W40tXg80XoNy8L3GujgF4PzuiWqY4q5o+XVqppj1atLS7dFa/KuSjJ6bBWF0ootVjmXpRofUF5/Tg2zwcwtOKm9wSjCdgmoGht2CFryieoNVuwJ7MFBLheMvpKp940vHpXDMxb5mc/lff1yM/XNLd5aUa5ITw8GE7qowc3Irc2tUTZKQem+o3mwnuj0dBsRUQt2eGIEkqDWn/pQ5SfjUWSQp3YUVv0iPjIvwV+lHSEB9Mod8Am/5TYuFxINgo6R3MX5K7rwaXjvErSUz6gAP2kqoA+EZDUotmdhFr8zVVpB8e33bPwxNlTYJ5fePKIkLz3TjEb1UVpav2/Ie/jpD0QbfCL/hukEPV/JKye+4fOIJeRZGwBXOQQsscyfcNf9utHittG4ZEzOXwYutbSf4qjoI5V48/hC8hs0OL3RJGE6e4v9tQwvIxY/IopqreACVrHIRK34fOoABQpFUPsmcGTuLrAGJqjDn9UiXJqb9Qlgav1Ly0KKH5YnKQoxyc5RvQDC8NvafSDgex0udGwTVGDNYgQeGVmrOy/C6iDIyEe5hn5gXwDFWFMxETjHcYka7gCngCbDiGIOMxiOeHbnO2dG7HbNME6p9nRovdD/n5cnp4sj3ttysyMNRt8NE2IkZRfJ+LQUqcavpkeVRvN5O/drNBtYnTOXC+lGCV0XGL2E= + - secure: cniGJvvR9/RcmRAp0F+iLvqQGH3zlvDYUb1GqZpX2ZKgqJ9syidk/Xy456HdR9WM9gTHZdQLNXYQFx9Dt41pa3Ft9nEi9LvmoLp/3rh/Siogx2X/madDxqHOXshCMYUg9ndSk8KKvjYSb+ztxT8j1qDW553Fax2YPWQiGRT5FXaEg1vl6znR362AhXaU1MgB8Wq+tDzTYJZugGj13u0S/vkNuTd30IQ5sW9YoQ4QwYPJIaG6ix1EUo0P3u96edakQjIAdciMLkggsfQkZr2MF5vAHjUI4+qW5wyAV2mzauc2MKhvKkJnF6WcNYOsXBOyDCAPJNo5YM4ODJM9ot7CcfKllecBaFUs4Uqh2U0lIe6opRtMdYPwV/GAAXwanSKgM1dNxgmPHnUWffWjaUJAbN94E/EH9JtGK2FAuxWqhbsPuMbpGK3XXuojU1fYj3oGGYFmSE3xWmhtSU89xiDrmrooGxxkaRt00eWtK+qCuiR8KGkN//i3+3x2F0ysVoOJL5WSSzNyfbtfp6laHTZv/LSAFgjSEmJF04L4m4Yhm/EDKaUXZjR/TAK2NZDTxlOxaOGVhwPA8Xj5YSwDMTd5k+cPntpYn/NbWtRr4fwk6VxI4XOOtksdiSk4Eiiaco2qEyd3X1tW/B9bPaAAFk8jHD35GNZAazgvNq7+kpMOg1s= # GPG_KEYNAME - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE diff --git a/config/travis/mvn-settings.xml b/config/travis/mvn-settings.xml index 6a9ccc4e9..84ca5c569 100755 --- a/config/travis/mvn-settings.xml +++ b/config/travis/mvn-settings.xml @@ -2,18 +2,18 @@ ossrh - ${env.EG_OSSRH_USERNAME} - ${env.EG_OSSRH_PASSWORD} + ${env.HCOM_OSSRH_USERNAME} + ${env.HCOM_OSSRH_PASSWORD} sonatype-nexus-staging - ${env.EG_OSSRH_USERNAME} - ${env.EG_OSSRH_PASSWORD} + ${env.HCOM_OSSRH_USERNAME} + ${env.HCOM_OSSRH_PASSWORD} sonatype-nexus-snapshots - ${env.EG_OSSRH_USERNAME} - ${env.EG_OSSRH_PASSWORD} + ${env.HCOM_OSSRH_USERNAME} + ${env.HCOM_OSSRH_PASSWORD} From c37bcb50180bcc97b1a5848c251740e1559f3b17 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Jul 2019 10:49:29 +0200 Subject: [PATCH 0706/1786] Testing snapshot release --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index c41d119ed..ccc1db1d6 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8-SNAPSHOT + 1.4.8.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f06ebf24b..6ff3e0bb8 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8-SNAPSHOT + 1.4.8.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 6526e156f..70331451f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.8-SNAPSHOT + 1.4.8.1-SNAPSHOT pom 2019 From 785eab69b790a52286d7b57f471b0a84a1ac950b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Jul 2019 10:52:18 +0200 Subject: [PATCH 0707/1786] Modified changelog as per the new releases --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43a835782..d15d272c8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.4.7.1]git status [1.4.7.2] 2019.07.05 +### [1.4.7.1] [1.4.7.2] [1.4.7.3] 2019.07.05 #### Changed * Changed sonatype credential From 5760ac87ebd1fcce915baa1737638217e562963a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Jul 2019 10:53:40 +0200 Subject: [PATCH 0708/1786] [maven-release-plugin] prepare release 1.4.7.3 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index ccc1db1d6..431a7a9ab 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8.1-SNAPSHOT + 1.4.7.3 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 6ff3e0bb8..6211260b7 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8.1-SNAPSHOT + 1.4.7.3 diff --git a/pom.xml b/pom.xml index 70331451f..6d9737ead 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.8.1-SNAPSHOT + 1.4.7.3 pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.4.7.3 From c177e2018ff6188100a816e709b220817cf5b1d3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Jul 2019 10:53:48 +0200 Subject: [PATCH 0709/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 431a7a9ab..c41d119ed 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7.3 + 1.4.8-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 6211260b7..f06ebf24b 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.7.3 + 1.4.8-SNAPSHOT diff --git a/pom.xml b/pom.xml index 6d9737ead..6526e156f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.7.3 + 1.4.8-SNAPSHOT pom 2019 @@ -68,7 +68,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.4.7.3 + HEAD From 66855ceb13fda67d11738c44e5bd4ddf6a840ca8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jul 2019 15:07:35 +0200 Subject: [PATCH 0710/1786] - Modified method that retrieves the field type in order to go in deep in case of dote notation - Added possibility to disable the field automatic conversion --- .../beans/transformer/TransformerImpl.java | 52 +++++++++++++++---- .../transformer/TransformerSettings.java | 2 +- .../transformer/AbstractTransformerTest.java | 12 ++++- .../ImmutableObjectTransformationTest.java | 2 +- .../MutableObjectTransformationTest.java | 24 +++++++++ .../hotels/beans/utils/ReflectionUtils.java | 41 ++++++++------- .../sample/FromFooOnlyPrimitiveTypes.java | 36 +++++++++++++ .../mixed/MutableToFooOnlyPrimitiveTypes.java | 32 ++++++++++++ .../beans/utils/ReflectionUtilsTest.java | 19 +++++-- .../analyzer/ConversionAnalyzer.java | 5 +- 10 files changed, 188 insertions(+), 37 deletions(-) create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 37a8209f6..7861a6702 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -16,6 +16,7 @@ package com.hotels.beans.transformer; +import static java.util.Arrays.asList; import static java.util.Arrays.stream; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; @@ -26,13 +27,13 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.base.Defaults.defaultValue; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; import static com.hotels.beans.constant.Punctuation.COMMA; +import static com.hotels.beans.constant.Punctuation.DOT; import static com.hotels.beans.constant.Punctuation.LPAREN; import static com.hotels.beans.constant.Punctuation.RPAREN; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; @@ -313,7 +314,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN return defaultValue(fieldType); } boolean primitiveType = classUtils.isPrimitiveType(fieldType); - List transformerFunction = getTransformerFunction(sourceObj.getClass(), field, primitiveType, fieldBreadcrumb); + List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType, fieldBreadcrumb); boolean isTransformerFunctionDefined = !transformerFunction.isEmpty(); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { @@ -388,21 +389,52 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie } /** - * Retrieves the transformer function. If the field type is different and they are primitive + * Gets the source field type. + * @param sourceObjectClass the source object class + * @param sourceFieldName sourceFieldName the field name in the source object (if different from the target one) + * @return the source field type + */ + private Class getSourceFieldType(final Class sourceObjectClass, final String sourceFieldName) { + String cacheKey = "SourceFieldType-" + sourceObjectClass.getName() + "-" + sourceFieldName; + return cacheManager.getFromCache(cacheKey, Class.class) + .orElseGet(() -> { + Class classType = null; + try { + classType = reflectionUtils.getDeclaredFieldType(sourceFieldName, sourceObjectClass); + } catch (MissingFieldException e) { + // in case the source field is a primitive type and the destination one is composite, + // the source field type is returned without going in deep + if (classUtils.isPrimitiveType(sourceObjectClass)) { + classType = sourceObjectClass; + } else if (!settings.isSetDefaultValue()) { + throw e; + } + } + cacheManager.cacheObject(cacheKey, classType); + return classType; + }); + } + + /** + * Retrieves the transformer functions. If the field type is different and they are primitive * a conversion function is automatically added. * @param sourceObjectClass the source object class + * @param sourceFieldName the source field name * @param field The field on which the transformation should be applied. * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @param breadcrumb The full field path on which the transformation should be applied. * @return the transformer function. */ - private List getTransformerFunction(final Class sourceObjectClass, final Field field, + private List getTransformerFunction(final Class sourceObjectClass, final String sourceFieldName, final Field field, final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { List fieldTransformers = new ArrayList<>(); String fieldTransformerKey = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType) { - conversionAnalyzer.getConversionFunction(sourceObjectClass, field.getType()) - .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(fieldTransformerKey, conversionFunction))); + if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && !settings.getFieldsTransformers().containsKey(fieldTransformerKey)) { + Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); + if (nonNull(sourceFieldType)) { + conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) + .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(fieldTransformerKey, conversionFunction))); + } } ofNullable(settings.getFieldsTransformers().get(fieldTransformerKey)) .ifPresent(fieldTransformers::add); diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 1a9c15c36..f2bf56dde 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -88,5 +88,5 @@ final class TransformerSettings { * If set to true primitive types are transformed automatically. */ @Setter - private boolean defaultPrimitiveTypeConversionEnabled = true; + private boolean defaultPrimitiveTypeConversionEnabled; } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index 3f40e2d1e..2b6188248 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -34,6 +34,7 @@ import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooAdvFields; import com.hotels.beans.sample.FromFooMap; +import com.hotels.beans.sample.FromFooOnlyPrimitiveTypes; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.FromFooWithPrimitiveFields; @@ -52,6 +53,7 @@ public abstract class AbstractTransformerTest { static FromFooSubClass fromFooSubClass; static FromFooAdvFields fromFooAdvFields; static FromFooMap fromFooMap; + static FromFooOnlyPrimitiveTypes fromFooPrimitiveTypes; static final int AGE = 34; static final String AGE_FIELD_NAME = "age"; static final String DEST_FIELD_NAME = "destFieldName"; @@ -107,6 +109,7 @@ private void initObjects() { fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); fromFooSubClass = createFromFooSubClass(); fromFooAdvFields = createFromFooAdvFields(); + fromFooPrimitiveTypes = createFromFooPrimitiveTypes(); EXTREME_COMPLEX_MAP.put(fromFooSimple, SAMPLE_MAP); fromFooMap = new FromFooMap(SAMPLE_MAP, COMPLEX_MAP, VERY_COMPLEX_MAP, EXTREME_COMPLEX_MAP); } @@ -128,7 +131,6 @@ private FromFooSimple createFromFooSimple() { return new FromFooSimple(NAME, ID, ACTIVE); } - /** * Creates a {@link FromFooWithPrimitiveFields} instance. * @return the {@link FromFooWithPrimitiveFields} instance. @@ -152,4 +154,12 @@ private FromFooSubClass createFromFooSubClass() { private FromFooAdvFields createFromFooAdvFields() { return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage(), PRICE); } + + /** + * Creates a {@link FromFooOnlyPrimitiveTypes} instance. + * @return the {@link FromFooOnlyPrimitiveTypes} instance. + */ + private FromFooOnlyPrimitiveTypes createFromFooPrimitiveTypes() { + return new FromFooOnlyPrimitiveTypes(ID.toString(), ID.intValue(), PRICE, String.valueOf(ACTIVE)); + } } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 060b923db..e21ca682a 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -383,7 +383,7 @@ public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNot @Test public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { //GIVEN - underTest.withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); + underTest.setDefaultPrimitiveTypeConversionEnabled(true).withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); //WHEN final Method getConstructorValuesFromFieldsMethod = diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 0f0c00994..d4887c0a5 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -16,6 +16,8 @@ package com.hotels.beans.transformer; +import static java.lang.Integer.parseInt; + import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; @@ -35,6 +37,7 @@ import com.hotels.beans.sample.FromFooNoField; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSimpleNoGetters; +import com.hotels.beans.sample.mixed.MutableToFooOnlyPrimitiveTypes; import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooInvalid; import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; @@ -47,6 +50,7 @@ */ public class MutableObjectTransformationTest extends AbstractTransformerTest { private static final boolean ACTIVE = true; + /** * The class to be tested. */ @@ -278,4 +282,24 @@ public void testFieldTransformationSkipWorksProperly() { assertNull(actual.getNestedObject().getPhoneNumbers()); underTest.resetFieldsTransformationSkip(); } + + /** + * Test that the automatic primitive type conversion works properly. + */ + @Test + public void testAutomaticPrimitiveTypeTransformationWorksProperly() { + //GIVEN + double delta = 0d; + underTest.setDefaultPrimitiveTypeConversionEnabled(true); + + //WHEN + MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); + + //THEN + assertEquals(parseInt(fromFooPrimitiveTypes.getCode()), actual.getCode()); + assertEquals(String.valueOf(fromFooPrimitiveTypes.getId()), actual.getId()); + assertEquals(Float.valueOf(fromFooPrimitiveTypes.getPrice()).doubleValue(), actual.getPrice(), delta); + assertEquals(ACTIVE, actual.isActive()); + underTest.setDefaultPrimitiveTypeConversionEnabled(false); + } } diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java index 565a95b3a..b5a25d958 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java @@ -266,7 +266,7 @@ private Object getFieldValueDirectAccess(final Object target, final String field * @param targetClass the field's class * @return the field corresponding to the given name. */ - public Field getDeclaredField(final String fieldName, final Class targetClass) { + private Field getClassDeclaredField(final String fieldName, final Class targetClass) { final String cacheKey = "ClassDeclaredField-" + targetClass.getName() + "-" + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, Field.class).orElseGet(() -> { Field field; @@ -276,7 +276,7 @@ public Field getDeclaredField(final String fieldName, final Class targetClass } catch (NoSuchFieldException e) { Class superclass = targetClass.getSuperclass(); if (!superclass.equals(Object.class)) { - field = getDeclaredField(fieldName, superclass); + field = getClassDeclaredField(fieldName, superclass); } else { throw new MissingFieldException(targetClass.getName() + " does not contain field: " + fieldName); } @@ -289,6 +289,26 @@ public Field getDeclaredField(final String fieldName, final Class targetClass }); } + /** + * Return the field of the given class. + * @param fieldName the name of the field to retrieve. + * @param targetClass the field's class + * @return the field corresponding to the given name. + */ + public Field getDeclaredField(final String fieldName, final Class targetClass) { + final String cacheKey = "ClassDeclaredFieldDotNotation-" + targetClass.getName() + "-" + fieldName; + return CACHE_MANAGER.getFromCache(cacheKey, Field.class).orElseGet(() -> { + Field field = null; + Class currentClass = targetClass; + for (String currFieldName : fieldName.split(DOT_SPLIT_REGEX)) { + field = getClassDeclaredField(currFieldName, currentClass); + currentClass = field.getType(); + } + CACHE_MANAGER.cacheObject(cacheKey, field); + return field; + }); + } + /** * Return the class of the given field. * @param fieldName the name of the filed to retrieve. @@ -298,22 +318,7 @@ public Field getDeclaredField(final String fieldName, final Class targetClass public Class getDeclaredFieldType(final String fieldName, final Class clazz) { final String cacheKey = "FieldType-" + clazz.getName() + "-" + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, Class.class).orElseGet(() -> { - Class fieldType; - Field field; - try { - field = clazz.getDeclaredField(fieldName); - } catch (NoSuchFieldException e) { - Class superclass = clazz.getSuperclass(); - if (!superclass.equals(Object.class)) { - field = getDeclaredField(fieldName, superclass); - } else { - throw new MissingFieldException(clazz.getName() + " does not contain field: " + fieldName); - } - } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); - } - fieldType = field.getType(); + Class fieldType = getDeclaredField(fieldName, clazz).getType(); CACHE_MANAGER.cacheObject(cacheKey, fieldType); return fieldType; }); diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java new file mode 100644 index 000000000..76fa6a023 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Sample class containing only primitive types. + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class FromFooOnlyPrimitiveTypes { + private String code; + private int id; + private float price; + private String active; +} diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java new file mode 100644 index 000000000..6e457bb6d --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mixed; + +import lombok.Getter; +import lombok.Setter; + +/** + * Sample class containing only primitive types. + */ +@Getter +@Setter +public class MutableToFooOnlyPrimitiveTypes { + private int code; + private String id; + private double price; + private boolean active; +} diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index 56c4b3ce6..f6fe8585f 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -79,7 +79,6 @@ public class ReflectionUtilsTest { private static final String INVOKE_METHOD_NAME = "invokeMethod"; private static final String VERY_COMPLEX_MAP_FIELD_NAME = "veryComplexMap"; private static final String GET_GETTER_METHOD_NAME = "getGetterMethod"; - private static final String NAME = "Donald Duck"; private static final String SET_NAME_METHOD_NAME = "setName"; private static final String SET_INDEX_METHOD_NAME = "setIndex"; private static final String INDEX_NUMBER = "123"; @@ -444,17 +443,29 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong /** * Tests that the method {@code getDeclaredField} works properly. */ - @Test - public void testGetDeclaredFieldWorksProperly() { + @Test(dataProvider = "dataGetDeclaredFieldTesting") + public void testGetDeclaredFieldWorksProperly(final String testDescription, final String fieldName, final Class targetClass) { // GIVEN // WHEN - Field actual = underTest.getDeclaredField(ID_FIELD_NAME, FromFooSubClass.class); + Field actual = underTest.getDeclaredField(fieldName, targetClass); // THEN assertNotNull(actual); } + /** + * Creates the parameters to be used for testing the method {@code getDeclaredField}. + * @return parameters to be used for testing the the method {@code getDeclaredField}. + */ + @DataProvider + private Object[][] dataGetDeclaredFieldTesting() { + return new Object[][] { + {"Tests that the method returns the class field from first object", ID_FIELD_NAME, FromFooSubClass.class}, + {"Tests that the method returns the class field from a nested object", NESTED_OBJECT_FIELD_NAME, MutableToFoo.class} + }; + } + /** * Tests that the method {@code getDeclaredField} throws a {@link MissingFieldException} if the field does not exists. */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 402f29043..4fbae4b2d 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -72,7 +72,8 @@ public Optional> getConversionFunction(final Class s return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional conversionFunction = empty(); if (!targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName()) && classUtils.isPrimitiveType(sourceClass)) { - conversionFunction = ofNullable(getConversionProcessor(targetClass)) + conversionFunction = + ofNullable(getConversionProcessor(targetClass)) .flatMap(cp -> getTypeConversionFunction(cp, sourceClass)); } CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); @@ -88,7 +89,7 @@ public Optional> getConversionFunction(final Class s * @return the conversion function */ private Optional> getTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { - Optional> conversionFunction = null; + Optional> conversionFunction = empty(); if (isString(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertString()); } else if (isByte(sourceFieldType)) { From 755d9ddc3735a95f3947c67be330b04f36af453d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jul 2019 16:48:16 +0200 Subject: [PATCH 0711/1786] Fixed bug into class ConverterImpl. Added UT --- .../beans/transformer/TransformerImpl.java | 9 +- .../ImmutableObjectTransformationTest.java | 2 +- .../hotels/beans/utils/ClassUtilsTest.java | 10 +- .../beans/utils/ReflectionUtilsTest.java | 5 +- .../beans/conversion/ConverterImpl.java | 6 +- .../analyzer/ConversionAnalyzer.java | 4 +- .../processor/ConversionProcessorFactory.java | 29 +-- .../beans/conversion/ConverterTest.java | 174 ++++++++++++++++++ .../ConversionProcessorFactoryTest.java | 11 +- docs/site/markdown/index.md | 9 +- 10 files changed, 224 insertions(+), 35 deletions(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 7861a6702..b495c912b 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -16,7 +16,6 @@ package com.hotels.beans.transformer; -import static java.util.Arrays.asList; import static java.util.Arrays.stream; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; @@ -27,13 +26,13 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static com.hotels.beans.base.Defaults.defaultValue; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.Punctuation.COMMA; import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.constant.Punctuation.COMMA; import static com.hotels.beans.constant.Punctuation.LPAREN; import static com.hotels.beans.constant.Punctuation.RPAREN; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; +import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index e21ca682a..060b923db 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -383,7 +383,7 @@ public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNot @Test public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { //GIVEN - underTest.setDefaultPrimitiveTypeConversionEnabled(true).withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); + underTest.withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); //WHEN final Method getConstructorValuesFromFieldsMethod = diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index c48189639..dd1afb2c5 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -136,11 +136,11 @@ private Object[][] dataIsPrimitiveTypeObjectTesting() { return new Object[][] { {"Tests that the method returns true if the class is a primitive type object", BigDecimal.class, true}, {"Tests that the method returns false if the class is not a primitive type object", FromFoo.class, false}, - {"Tests that the method returns true if the class is not a Boolean", Boolean.class, true}, - {"Tests that the method returns true if the class is not a Character", Character.class, true}, - {"Tests that the method returns true if the class is not a Byte", Byte.class, true}, - {"Tests that the method returns true if the class is not a Void", Void.class, true}, - {"Tests that the method returns true if the class is not a String", String.class, true}, + {"Tests that the method returns true if the class is a Boolean", Boolean.class, true}, + {"Tests that the method returns true if the class is a Character", Character.class, true}, + {"Tests that the method returns true if the class is a Byte", Byte.class, true}, + {"Tests that the method returns true if the class is a Void", Void.class, true}, + {"Tests that the method returns true if the class is a String", String.class, true}, }; } diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index f6fe8585f..e92d20217 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -442,9 +442,12 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong /** * Tests that the method {@code getDeclaredField} works properly. + * @param testCaseDescription the test case description + * @param fieldName the field to retrieve + * @param targetClass the class where the field has to be searched */ @Test(dataProvider = "dataGetDeclaredFieldTesting") - public void testGetDeclaredFieldWorksProperly(final String testDescription, final String fieldName, final Class targetClass) { + public void testGetDeclaredFieldWorksProperly(final String testCaseDescription, final String fieldName, final Class targetClass) { // GIVEN // WHEN diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java index 65c337dc0..fe4ca7cce 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java @@ -18,6 +18,8 @@ import static java.util.Objects.isNull; +import static com.hotels.beans.validator.Validator.notNull; + import java.util.Optional; import java.util.function.Function; @@ -55,12 +57,12 @@ public Optional> getConversionFunction(final Class s @Override @SuppressWarnings("unchecked") public K convertValue(final T valueToConvert, final Class targetClass) { - Validator.notNull(targetClass, "The destination field type cannot be null."); + notNull(targetClass, "The destination field type cannot be null."); if (isNull(valueToConvert)) { return null; } return (K) getConversionFunction(valueToConvert.getClass(), targetClass) - .map(processor -> processor.apply(targetClass)) + .map(processor -> processor.apply(valueToConvert)) .orElseThrow(() -> new NoConverterAvailableException("No converter available for type: " + targetClass.getName())); } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 4fbae4b2d..75081e3e6 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -18,7 +18,6 @@ import static java.util.Optional.empty; import static java.util.Optional.of; -import static java.util.Optional.ofNullable; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.conversion.processor.ConversionProcessorFactory.getConversionProcessor; @@ -72,8 +71,7 @@ public Optional> getConversionFunction(final Class s return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional conversionFunction = empty(); if (!targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName()) && classUtils.isPrimitiveType(sourceClass)) { - conversionFunction = - ofNullable(getConversionProcessor(targetClass)) + conversionFunction = getConversionProcessor(targetClass) .flatMap(cp -> getTypeConversionFunction(cp, sourceClass)); } CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index 5043139da..25c24730c 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -16,6 +16,9 @@ package com.hotels.beans.conversion.processor; +import static java.util.Optional.empty; +import static java.util.Optional.of; + import static com.hotels.beans.utils.ClassUtils.isBoolean; import static com.hotels.beans.utils.ClassUtils.isByte; import static com.hotels.beans.utils.ClassUtils.isChar; @@ -28,6 +31,8 @@ import static lombok.AccessLevel.PRIVATE; +import java.util.Optional; + import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; @@ -48,28 +53,28 @@ public final class ConversionProcessorFactory { /** * Returns a conversion processor for the given type. * @param clazz the class for which the conversion processor has to be retrieved. - * @return a conversion processor for the given type + * @return a conversion processor for the given type wrapped into {@link Optional} */ - public static ConversionProcessor getConversionProcessor(final Class clazz) { - ConversionProcessor conversionProcessor = null; + public static Optional getConversionProcessor(final Class clazz) { + Optional conversionProcessor = empty(); if (isByte(clazz)) { - conversionProcessor = new ByteConversionProcessor(); + conversionProcessor = of(new ByteConversionProcessor()); } else if (isShort(clazz)) { - conversionProcessor = new ShortConversionProcessor(); + conversionProcessor = of(new ShortConversionProcessor()); } else if (isInt(clazz)) { - conversionProcessor = new IntegerConversionProcessor(); + conversionProcessor = of(new IntegerConversionProcessor()); } else if (isLong(clazz)) { - conversionProcessor = new LongConversionProcessor(); + conversionProcessor = of(new LongConversionProcessor()); } else if (isFloat(clazz)) { - conversionProcessor = new FloatConversionProcessor(); + conversionProcessor = of(new FloatConversionProcessor()); } else if (isDouble(clazz)) { - conversionProcessor = new DoubleConversionProcessor(); + conversionProcessor = of(new DoubleConversionProcessor()); } else if (isChar(clazz)) { - conversionProcessor = new CharacterConversionProcessor(); + conversionProcessor = of(new CharacterConversionProcessor()); } else if (isString(clazz)) { - conversionProcessor = new StringConversionProcessor(); + conversionProcessor = of(new StringConversionProcessor()); } else if (isBoolean(clazz)) { - conversionProcessor = new BooleanConversionProcessor(); + conversionProcessor = of(new BooleanConversionProcessor()); } return conversionProcessor; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java new file mode 100644 index 000000000..f066e700c --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -0,0 +1,174 @@ +package com.hotels.beans.conversion; + +import static java.math.BigInteger.ZERO; +import static java.math.BigInteger.valueOf; +import static java.util.Optional.empty; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.math.BigInteger; +import java.util.Optional; +import java.util.function.Function; + +import org.apache.commons.lang3.tuple.Pair; +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; +import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; +import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; +import com.hotels.beans.conversion.processor.impl.FloatConversionProcessor; +import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; +import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; + +/** + * Unit test for {@link Converter}. + */ +public class ConverterTest { + private static final String ONE_AS_STRING = "1"; + private static final int ONE_AS_INT = 1; + private static final byte ONE_AS_BYTE = 1; + /** + * The class to be tested. + */ + @InjectMocks + private ConverterImpl underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + /** + * Tests that the method {@code getConversionFunction} returns an empty optional. + * @param testCaseDescription the test case description + * @param sourceFieldType source field class + * @param destinationFieldType the destination field class + */ + @Test(dataProvider = "dataGetConversionFunctionEmptyCaseTesting") + public void testGetConversionFunctionReturnsAnEmptyOptional(final String testCaseDescription, final Class sourceFieldType, + final Class destinationFieldType) { + // GIVEN + + // WHEN + Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); + + // THEN + assertEquals(empty(), actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code getConversionFunction} returns an empty Optional. + * @return parameters to be used for testing that the method {@code getConversionFunction} returns an empty Optional. + */ + @DataProvider + private Object[][] dataGetConversionFunctionEmptyCaseTesting() { + return new Object[][]{ + {"Tests that the method returns an empty optional in case the source field type is equal to the destination field type", + int.class, int.class}, + {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type but it's not primitive", + Pair.class, int.class}, + {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type and the destination type is void", + int.class, Void.class} + }; + } + + /** + * Tests that the method {@code getConversionFunction} returns the expected conversion function. + * @param testCaseDescription the test case description + * @param sourceFieldType source field class + * @param destinationFieldType the destination field class + * @param expectedConversionFunction the expected {@link com.hotels.beans.conversion.processor.ConversionProcessor} instance + */ + @Test(dataProvider = "dataGetConversionFunctionTesting") + public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final String testCaseDescription, final Class sourceFieldType, + final Class destinationFieldType, final Function expectedConversionFunction) { + // GIVEN + + // WHEN + Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); + + // THEN + assertEquals(expectedConversionFunction, actual.get()); + } + + /** + * Creates the parameters to be used for testing the method {@code getConversionFunction}. + * @return parameters to be used for testing the method {@code getConversionFunction}. + */ + @DataProvider + private Object[][] dataGetConversionFunctionTesting() { + return new Object[][] { + {"Tests that the method returns a IntegerConversionProcessor that converts from String to int", + String.class, int.class, new IntegerConversionProcessor().convertString()}, + {"Tests that the method returns a StringConversionProcessor that converts from byte to String", + byte.class, String.class, new StringConversionProcessor().convertByte()}, + {"Tests that the method returns a ShortConversionProcessor that converts from short to byte", + short.class, byte.class, new ByteConversionProcessor().convertShort()}, + {"Tests that the method returns a StringConversionProcessor that converts from int to String", + int.class, String.class, new StringConversionProcessor().convertInteger()}, + {"Tests that the method returns a IntegerConversionProcessor that converts from long to int", + long.class, int.class, new IntegerConversionProcessor().convertLong()}, + {"Tests that the method returns a DoubleConversionProcessor that converts from float to double", + float.class, double.class, new DoubleConversionProcessor().convertFloat()}, + {"Tests that the method returns a FloatConversionProcessor that converts from double to float", + double.class, float.class, new FloatConversionProcessor().convertDouble()}, + {"Tests that the method returns a StringConversionProcessor that converts from char to String", + char.class, String.class, new StringConversionProcessor().convertCharacter()}, + {"Tests that the method returns a CharacterConversionProcessor that converts from char to boolean", + boolean.class, char.class, new CharacterConversionProcessor().convertBoolean()} + }; + } + + /** + * Test that the method {@code convertValue} raises an {@link IllegalArgumentException} if the target class parameter is null. + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testConvertValueRaisesExceptionIfItsCalledWithNullTargetClassParam() { + //GIVEN + + //WHEN + underTest.convertValue(ZERO, null); + } + + + /** + * Tests that the method {@code convertValue} returns the expected converted value. + * @param testCaseDescription the test case description + * @param valueToConvert the value to convert + * @param targetClass the destination class + * @param expectedValue the expected result + * @param the value to convert class type + */ + @Test(dataProvider = "dataConvertValueTesting") + public void testConvertValueWorksProperly(final String testCaseDescription, final T valueToConvert, + final Class targetClass, final Object expectedValue) { + // GIVEN + + // WHEN + Object actual = underTest.convertValue(valueToConvert, targetClass); + + // THEN + assertEquals(expectedValue, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result. + */ + @DataProvider + private Object[][] dataConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns a null value in case the value to convert is null", null, BigInteger.class, null}, + {"Tests that the method returns a boolean value from a byte", ONE_AS_BYTE, boolean.class, Boolean.TRUE}, + {"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.parseInt(ONE_AS_STRING)}, + {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.parseByte(ONE_AS_STRING)} + }; + } +} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index 927e6cb5a..7585c9787 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -18,8 +18,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; +import java.util.Optional; + import org.apache.commons.lang3.tuple.Pair; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; @@ -62,10 +65,10 @@ public void testGetConversionProcessorReturnsNullInCaseNoProcessorExistsForTheGi // GIVEN // WHEN - ConversionProcessor actual = underTest.getConversionProcessor(Pair.class); + Optional actual = underTest.getConversionProcessor(Pair.class); // THEN - assertNull(actual); + assertTrue(actual.isEmpty()); } /** @@ -80,10 +83,10 @@ public void testGetConversionProcessorWorksAsExpected(final String testCaseDescr // GIVEN // WHEN - ConversionProcessor actual = underTest.getConversionProcessor(targetClass); + Optional actual = underTest.getConversionProcessor(targetClass); // THEN - assertEquals(expectedResult, actual.getClass()); + assertEquals(expectedResult, actual.get().getClass()); } /** diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 46cf37c61..5eb5c6439 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -32,7 +32,8 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. * allows to skip transformation for a given set of fields. -* supports the values retrieval from getters if a field does not exists in the source object +* supports the values retrieval from getters if a field does not exists in the source object. +* supports the automatic conversion of primitive types. #### Bean Validation: @@ -41,7 +42,11 @@ The validation works with both the default `javax.constraints` provided by Java ##### Features: * Java Bean validation -* retrieve the violated constraints +* Retrieve the violated constraints + +#### Primitive object automatic conversion: + +Transforms any primitive type value into another one. #### Related articles From 8443583427077526cf6f576e7477a3d82b2ec758 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jul 2019 17:58:46 +0200 Subject: [PATCH 0712/1786] Added test cases --- .../analyzer/ConversionAnalyzer.java | 4 ++- .../beans/conversion/ConverterTest.java | 29 +++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 75081e3e6..14acad91f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -70,7 +70,9 @@ public Optional> getConversionFunction(final Class s final String cacheKey = "ConversionFunction-" + sourceClass.getName() + "-" + targetClass.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional conversionFunction = empty(); - if (!targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName()) && classUtils.isPrimitiveType(sourceClass)) { + if (targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName())) { + conversionFunction = of((Function) val -> val); + } else if (classUtils.isPrimitiveType(sourceClass)) { conversionFunction = getConversionProcessor(targetClass) .flatMap(cp -> getTypeConversionFunction(cp, sourceClass)); } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index f066e700c..902d32147 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -29,8 +29,8 @@ */ public class ConverterTest { private static final String ONE_AS_STRING = "1"; - private static final int ONE_AS_INT = 1; - private static final byte ONE_AS_BYTE = 1; + private static final char CHAR_VALUE = 'x'; + private static final byte TRUE_AS_BYTE = 1; /** * The class to be tested. */ @@ -70,8 +70,6 @@ public void testGetConversionFunctionReturnsAnEmptyOptional(final String testCas @DataProvider private Object[][] dataGetConversionFunctionEmptyCaseTesting() { return new Object[][]{ - {"Tests that the method returns an empty optional in case the source field type is equal to the destination field type", - int.class, int.class}, {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type but it's not primitive", Pair.class, int.class}, {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type and the destination type is void", @@ -166,7 +164,28 @@ public void testConvertValueWorksProperly(final String testCaseDescription, private Object[][] dataConvertValueTesting() { return new Object[][]{ {"Tests that the method returns a null value in case the value to convert is null", null, BigInteger.class, null}, - {"Tests that the method returns a boolean value from a byte", ONE_AS_BYTE, boolean.class, Boolean.TRUE}, + // boolean conversion test cases + {"Tests that the method returns a boolean value from a byte", Byte.MIN_VALUE, boolean.class, Boolean.TRUE}, + {"Tests that the method returns a boolean value from a short", Short.MIN_VALUE, boolean.class, Boolean.TRUE}, + {"Tests that the method returns a boolean value from an Integer", Integer.MIN_VALUE, boolean.class, Boolean.TRUE}, + {"Tests that the method returns a boolean value from a Long", Long.MIN_VALUE, boolean.class, Boolean.TRUE}, + {"Tests that the method returns a boolean value from a Float", Float.MIN_VALUE, boolean.class, Boolean.TRUE}, + {"Tests that the method returns a boolean value from a Double", Double.MIN_VALUE, boolean.class, Boolean.TRUE}, + {"Tests that the method returns a boolean value from a char", CHAR_VALUE, boolean.class, Boolean.TRUE}, + {"Tests that the method returns a boolean value from a Boolean", Boolean.TRUE, boolean.class, Boolean.TRUE}, + {"Tests that the method returns a boolean value from a String", String.valueOf(Boolean.FALSE), boolean.class, Boolean.FALSE}, + // byte conversion test cases + {"Tests that the method returns a byte value from a byte", Byte.MIN_VALUE, byte.class, Byte.MIN_VALUE}, + {"Tests that the method returns a byte value from a short", Short.MIN_VALUE, byte.class, Short.valueOf(Short.MIN_VALUE).byteValue()}, + {"Tests that the method returns a byte value from an Integer", Integer.MIN_VALUE, byte.class, Integer.valueOf(Integer.MIN_VALUE).byteValue()}, + {"Tests that the method returns a byte value from a Long", Long.MIN_VALUE, byte.class, Long.valueOf(Long.MIN_VALUE).byteValue()}, + {"Tests that the method returns a byte value from a Float", Float.MIN_VALUE, byte.class, Float.valueOf(Float.MIN_VALUE).byteValue()}, + {"Tests that the method returns a byte value from a Double", Double.MIN_VALUE, byte.class, Double.valueOf(Double.MIN_VALUE).byteValue()}, + {"Tests that the method returns a byte value from a char", CHAR_VALUE, byte.class, (byte) Character.valueOf(CHAR_VALUE).charValue()}, + {"Tests that the method returns a byte value from a Boolean", Boolean.TRUE, byte.class, TRUE_AS_BYTE}, + {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, + + {"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.parseInt(ONE_AS_STRING)}, {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.parseByte(ONE_AS_STRING)} }; From 2a19399191d696858741a2dbcfe7f1ed385f956a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jul 2019 18:04:33 +0200 Subject: [PATCH 0713/1786] Added test cases for converter --- .../com/hotels/beans/conversion/ConverterTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 902d32147..3c5b115d4 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -17,6 +17,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.error.NoConverterAvailableException; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; @@ -190,4 +191,15 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.parseByte(ONE_AS_STRING)} }; } + + /** + * Tests that the method {@code convertValue} raises a {@link NoConverterAvailableException}. + */ + @Test(expectedExceptions = NoConverterAvailableException.class) + public void testConvertValueRaisesExpectionInCaseNoConverterIsDefined() { + // GIVEN + + // WHEN + underTest.convertValue(ONE_AS_STRING, Void.class); + } } From e148464bba0320283743ca43c908902741fa15fd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 10 Jul 2019 10:23:55 +0200 Subject: [PATCH 0714/1786] Added test cases to ConverterImpl class --- .../hotels/beans/conversion/Converter.java | 4 +- .../beans/conversion/ConverterImpl.java | 7 +- .../analyzer/ConversionAnalyzer.java | 4 +- ...tion.java => TypeConversionException.java} | 8 +-- .../impl/DoubleConversionProcessor.java | 3 +- .../impl/FloatConversionProcessor.java | 2 +- .../beans/conversion/ConverterTest.java | 65 ++++++++++++++++--- 7 files changed, 71 insertions(+), 22 deletions(-) rename bull-converter/src/main/java/com/hotels/beans/conversion/error/{NoConverterAvailableException.java => TypeConversionException.java} (77%) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java index de7735646..c988cca8b 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java @@ -19,6 +19,8 @@ import java.util.Optional; import java.util.function.Function; +import com.hotels.beans.conversion.error.TypeConversionException; + /** * It allows to convert any primitive type into another. */ @@ -39,7 +41,7 @@ public interface Converter { * @return the converted value * @param the value to convert type * @param the target object type - * @throws com.hotels.beans.conversion.error.NoConverterAvailableException in case there is no converter for the given class + * @throws TypeConversionException in case there is no converter for the given class * @throws IllegalArgumentException in case the destination field type is null. */ K convertValue(T valueToConvert, Class targetClass); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java index fe4ca7cce..b22ef0c3e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java @@ -24,8 +24,7 @@ import java.util.function.Function; import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; -import com.hotels.beans.conversion.error.NoConverterAvailableException; -import com.hotels.beans.validator.Validator; +import com.hotels.beans.conversion.error.TypeConversionException; /** * This class provides method for converting a primitive input into another. @@ -60,9 +59,11 @@ public K convertValue(final T valueToConvert, final Class targetClass) notNull(targetClass, "The destination field type cannot be null."); if (isNull(valueToConvert)) { return null; + } else if (targetClass.getSimpleName().equalsIgnoreCase(valueToConvert.getClass().getSimpleName())) { + return (K) valueToConvert; } return (K) getConversionFunction(valueToConvert.getClass(), targetClass) .map(processor -> processor.apply(valueToConvert)) - .orElseThrow(() -> new NoConverterAvailableException("No converter available for type: " + targetClass.getName())); + .orElseThrow(() -> new TypeConversionException("No converter available for type: " + targetClass.getName())); } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 14acad91f..75081e3e6 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -70,9 +70,7 @@ public Optional> getConversionFunction(final Class s final String cacheKey = "ConversionFunction-" + sourceClass.getName() + "-" + targetClass.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional conversionFunction = empty(); - if (targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName())) { - conversionFunction = of((Function) val -> val); - } else if (classUtils.isPrimitiveType(sourceClass)) { + if (!targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName()) && classUtils.isPrimitiveType(sourceClass)) { conversionFunction = getConversionProcessor(targetClass) .flatMap(cp -> getTypeConversionFunction(cp, sourceClass)); } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/error/NoConverterAvailableException.java b/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java similarity index 77% rename from bull-converter/src/main/java/com/hotels/beans/conversion/error/NoConverterAvailableException.java rename to bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java index 67b4a2445..a77a801f0 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/error/NoConverterAvailableException.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java @@ -17,16 +17,16 @@ package com.hotels.beans.conversion.error; /** - * Converter not available exception class. + * Automatic type conversion exception class. */ -public class NoConverterAvailableException extends RuntimeException { +public class TypeConversionException extends RuntimeException { /** - * Constructs a new {@link NoConverterAvailableException} with the specified detail message. + * Constructs a new {@link TypeConversionException} with the specified detail message. * The cause is not initialized, and may subsequently be initialized by a call to {@link #initCause}. * @param message the detail message. The detail message is saved for later * retrieval by the {@link #getMessage()} method. */ - public NoConverterAvailableException(final String message) { + public TypeConversionException(final String message) { super(message); } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index a013595c6..bb00e2067 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Character.getNumericValue; import static java.lang.Double.valueOf; import java.util.function.Function; @@ -79,7 +80,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return Double::valueOf; + return val -> (double) getNumericValue(val); } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index 63b34537f..1af32b61d 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -32,7 +32,7 @@ public final class FloatConversionProcessor implements ConversionProcessor { */ @Override public Function convertByte() { - return Float::valueOf; + return Byte::floatValue; } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 3c5b115d4..1081d2b95 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -1,7 +1,22 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.hotels.beans.conversion; +import static java.lang.Character.getNumericValue; import static java.math.BigInteger.ZERO; -import static java.math.BigInteger.valueOf; import static java.util.Optional.empty; import static org.junit.Assert.assertEquals; @@ -17,7 +32,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.error.NoConverterAvailableException; +import com.hotels.beans.conversion.error.TypeConversionException; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; @@ -31,7 +46,9 @@ public class ConverterTest { private static final String ONE_AS_STRING = "1"; private static final char CHAR_VALUE = 'x'; + private static final char CHAR_INT_VALUE = '1'; private static final byte TRUE_AS_BYTE = 1; + private static final int TRUE_AS_INT = 1; /** * The class to be tested. */ @@ -185,18 +202,48 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a byte value from a char", CHAR_VALUE, byte.class, (byte) Character.valueOf(CHAR_VALUE).charValue()}, {"Tests that the method returns a byte value from a Boolean", Boolean.TRUE, byte.class, TRUE_AS_BYTE}, {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, - - - {"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.parseInt(ONE_AS_STRING)}, - {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.parseByte(ONE_AS_STRING)} + // char conversion test cases + {"Tests that the method returns a char value from a byte", Byte.MIN_VALUE, char.class, Byte.valueOf(Byte.MIN_VALUE).toString().charAt(0)}, + {"Tests that the method returns a char value from a short", Short.MIN_VALUE, char.class, Short.valueOf(Short.MIN_VALUE).toString().charAt(0)}, + {"Tests that the method returns a char value from an Integer", Integer.MIN_VALUE, char.class, Integer.valueOf(Integer.MIN_VALUE).toString().charAt(0)}, + {"Tests that the method returns a char value from a Long", Long.MIN_VALUE, char.class, Long.valueOf(Long.MIN_VALUE).toString().charAt(0)}, + {"Tests that the method returns a char value from a Float", Float.MIN_VALUE, char.class, Float.valueOf(Float.MIN_VALUE).toString().charAt(0)}, + {"Tests that the method returns a char value from a Double", Double.MIN_VALUE, char.class, Double.valueOf(Double.MIN_VALUE).toString().charAt(0)}, + {"Tests that the method returns a char value from a char", CHAR_VALUE, char.class, CHAR_VALUE}, + {"Tests that the method returns a char value from a Boolean", Boolean.TRUE, char.class, Boolean.TRUE.toString().charAt(0)}, + {"Tests that the method returns a char value from a String", ONE_AS_STRING, char.class, ONE_AS_STRING.charAt(0)}, + // double conversion test cases + {"Tests that the method returns a double value from a byte", Byte.MIN_VALUE, double.class, Byte.valueOf(Byte.MIN_VALUE).doubleValue()}, + {"Tests that the method returns a double value from a short", Short.MIN_VALUE, double.class, Short.valueOf(Short.MIN_VALUE).doubleValue()}, + {"Tests that the method returns a double value from an Integer", Integer.MIN_VALUE, double.class, Integer.valueOf(Integer.MIN_VALUE).doubleValue()}, + {"Tests that the method returns a double value from a Long", Long.MIN_VALUE, double.class, Long.valueOf(Long.MIN_VALUE).doubleValue()}, + {"Tests that the method returns a double value from a Float", Float.MIN_VALUE, double.class, Float.valueOf(Float.MIN_VALUE).doubleValue()}, + {"Tests that the method returns a double value from a Double", Double.MIN_VALUE, double.class, Double.MIN_VALUE}, + {"Tests that the method returns a double value from a char", CHAR_INT_VALUE, double.class, Double.valueOf(String.valueOf(CHAR_INT_VALUE))}, + {"Tests that the method returns a double value from a Boolean", Boolean.TRUE, double.class, (double) TRUE_AS_INT}, + {"Tests that the method returns a double value from a String", ONE_AS_STRING, double.class, Double.valueOf(ONE_AS_STRING)}, + // float conversion test cases + {"Tests that the method returns a float value from a byte", Byte.MIN_VALUE, float.class, Byte.valueOf(Byte.MIN_VALUE).floatValue()}, + {"Tests that the method returns a float value from a short", Short.MIN_VALUE, float.class, Short.valueOf(Short.MIN_VALUE).floatValue()}, + {"Tests that the method returns a float value from an Integer", Integer.MIN_VALUE, float.class, Integer.valueOf(Integer.MIN_VALUE).floatValue()}, + {"Tests that the method returns a float value from a Long", Long.MIN_VALUE, float.class, Long.valueOf(Long.MIN_VALUE).floatValue()}, + {"Tests that the method returns a float value from a Float", Float.MIN_VALUE, float.class, Float.MIN_VALUE}, + {"Tests that the method returns a float value from a Double", Double.MIN_VALUE, float.class, Double.valueOf(Double.MIN_VALUE).floatValue()}, + {"Tests that the method returns a float value from a char", CHAR_INT_VALUE, float.class, (float) getNumericValue(CHAR_INT_VALUE)}, + {"Tests that the method returns a float value from a Boolean", Boolean.TRUE, float.class, (float) TRUE_AS_INT}, + {"Tests that the method returns a float value from a String", ONE_AS_STRING, float.class, Float.valueOf(ONE_AS_STRING)}, + // integer conversion test cases + // long conversion test cases + // short conversion test cases + // string conversion test cases }; } /** - * Tests that the method {@code convertValue} raises a {@link NoConverterAvailableException}. + * Tests that the method {@code convertValue} raises a {@link TypeConversionException}. */ - @Test(expectedExceptions = NoConverterAvailableException.class) - public void testConvertValueRaisesExpectionInCaseNoConverterIsDefined() { + @Test(expectedExceptions = TypeConversionException.class) + public void testConvertValueRaisesExceptionInCaseNoConverterIsDefined() { // GIVEN // WHEN From 540669bf7e5225223134028f4838795b5a54cfd9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 10 Jul 2019 12:13:35 +0200 Subject: [PATCH 0715/1786] Completed Converter class test and fixed checkstyle issues --- .../hotels/beans/conversion/Converter.java | 4 +- .../impl/ShortConversionProcessor.java | 3 +- .../impl/StringConversionProcessor.java | 12 +++--- .../beans/conversion/ConverterTest.java | 37 +++++++++++++++++++ .../hotels/beans/conversion/package-info.java | 20 ++++++++++ .../ConversionProcessorFactoryTest.java | 1 - 6 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java index c988cca8b..30fa9c39c 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java @@ -19,8 +19,6 @@ import java.util.Optional; import java.util.function.Function; -import com.hotels.beans.conversion.error.TypeConversionException; - /** * It allows to convert any primitive type into another. */ @@ -41,7 +39,7 @@ public interface Converter { * @return the converted value * @param the value to convert type * @param the target object type - * @throws TypeConversionException in case there is no converter for the given class + * @throws com.hotels.beans.conversion.error.TypeConversionException in case there is no converter for the given class * @throws IllegalArgumentException in case the destination field type is null. */ K convertValue(T valueToConvert, Class targetClass); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index ed2b57171..a22ae4799 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Character.getNumericValue; import static java.lang.Short.valueOf; import java.util.function.Function; @@ -77,7 +78,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return val -> valueOf((short) val.charValue()); + return val -> (short) getNumericValue(val); } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index 91be53248..30015704d 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -46,7 +46,7 @@ public Function convertShort() { */ @Override public Function convertInteger() { - return Object::toString; + return String::valueOf; } /** @@ -54,7 +54,7 @@ public Function convertInteger() { */ @Override public Function convertLong() { - return Object::toString; + return String::valueOf; } /** @@ -62,7 +62,7 @@ public Function convertLong() { */ @Override public Function convertFloat() { - return Object::toString; + return String::valueOf; } /** @@ -70,7 +70,7 @@ public Function convertFloat() { */ @Override public Function convertDouble() { - return Object::toString; + return String::valueOf; } /** @@ -78,7 +78,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return Object::toString; + return String::valueOf; } /** @@ -86,7 +86,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return Object::toString; + return String::valueOf; } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 1081d2b95..c32157fef 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.hotels.beans.conversion; import static java.lang.Character.getNumericValue; @@ -233,9 +234,45 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a float value from a Boolean", Boolean.TRUE, float.class, (float) TRUE_AS_INT}, {"Tests that the method returns a float value from a String", ONE_AS_STRING, float.class, Float.valueOf(ONE_AS_STRING)}, // integer conversion test cases + {"Tests that the method returns an int value from a byte", Byte.MIN_VALUE, int.class, Byte.valueOf(Byte.MIN_VALUE).intValue()}, + {"Tests that the method returns an int value from a short", Short.MIN_VALUE, int.class, Short.valueOf(Short.MIN_VALUE).intValue()}, + {"Tests that the method returns an int value from an Integer", Integer.MIN_VALUE, int.class, Integer.MIN_VALUE}, + {"Tests that the method returns an int value from a Long", Long.MIN_VALUE, int.class, Long.valueOf(Long.MIN_VALUE).intValue()}, + {"Tests that the method returns an int value from a Float", Float.MIN_VALUE, int.class, Float.valueOf(Float.MIN_VALUE).intValue()}, + {"Tests that the method returns an int value from a Double", Double.MIN_VALUE, int.class, Double.valueOf(Double.MIN_VALUE).intValue()}, + {"Tests that the method returns an int value from a char", CHAR_INT_VALUE, int.class, getNumericValue(CHAR_INT_VALUE)}, + {"Tests that the method returns an int value from a Boolean", Boolean.TRUE, int.class, TRUE_AS_INT}, + {"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.valueOf(ONE_AS_STRING)}, // long conversion test cases + {"Tests that the method returns a long value from a byte", Byte.MIN_VALUE, long.class, Byte.valueOf(Byte.MIN_VALUE).longValue()}, + {"Tests that the method returns a long value from a short", Short.MIN_VALUE, long.class, Short.valueOf(Short.MIN_VALUE).longValue()}, + {"Tests that the method returns a long value from an Integer", Integer.MIN_VALUE, long.class, Integer.valueOf(Integer.MIN_VALUE).longValue()}, + {"Tests that the method returns a long value from a Long", Long.MIN_VALUE, long.class, Long.MIN_VALUE}, + {"Tests that the method returns a long value from a Float", Float.MIN_VALUE, long.class, Float.valueOf(Float.MIN_VALUE).longValue()}, + {"Tests that the method returns a long value from a Double", Double.MIN_VALUE, long.class, Double.valueOf(Double.MIN_VALUE).longValue()}, + {"Tests that the method returns a long value from a char", CHAR_INT_VALUE, long.class, (long) getNumericValue(CHAR_INT_VALUE)}, + {"Tests that the method returns a long value from a Boolean", Boolean.TRUE, long.class, (long) TRUE_AS_INT}, + {"Tests that the method returns a long value from a String", ONE_AS_STRING, long.class, Long.valueOf(ONE_AS_STRING)}, // short conversion test cases + {"Tests that the method returns a short value from a byte", Byte.MIN_VALUE, short.class, Byte.valueOf(Byte.MIN_VALUE).shortValue()}, + {"Tests that the method returns a short value from a short", Short.MIN_VALUE, short.class, Short.MIN_VALUE}, + {"Tests that the method returns a short value from an Integer", Integer.MIN_VALUE, short.class, Integer.valueOf(Integer.MIN_VALUE).shortValue()}, + {"Tests that the method returns a short value from a Long", Long.MIN_VALUE, short.class, Long.valueOf(Long.MIN_VALUE).shortValue()}, + {"Tests that the method returns a short value from a Float", Float.MIN_VALUE, short.class, Float.valueOf(Float.MIN_VALUE).shortValue()}, + {"Tests that the method returns a short value from a Double", Double.MIN_VALUE, short.class, Double.valueOf(Double.MIN_VALUE).shortValue()}, + {"Tests that the method returns a short value from a char", CHAR_INT_VALUE, short.class, (short) getNumericValue(CHAR_INT_VALUE)}, + {"Tests that the method returns a short value from a Boolean", Boolean.TRUE, short.class, (short) TRUE_AS_INT}, + {"Tests that the method returns a short value from a String", ONE_AS_STRING, short.class, Short.valueOf(ONE_AS_STRING)}, // string conversion test cases + {"Tests that the method returns a String value from a byte", Byte.MIN_VALUE, String.class, Byte.valueOf(Byte.MIN_VALUE).toString()}, + {"Tests that the method returns a String value from a short", Short.MIN_VALUE, String.class, Short.valueOf(Short.MIN_VALUE).toString()}, + {"Tests that the method returns a String value from an Integer", Integer.MIN_VALUE, String.class, String.valueOf(Integer.MIN_VALUE)}, + {"Tests that the method returns a String value from a Long", Long.MIN_VALUE, String.class, String.valueOf(Long.MIN_VALUE)}, + {"Tests that the method returns a String value from a Float", Float.MIN_VALUE, String.class, String.valueOf(Float.MIN_VALUE)}, + {"Tests that the method returns a String value from a Double", Double.MIN_VALUE, String.class, String.valueOf(Double.MIN_VALUE)}, + {"Tests that the method returns a String value from a char", CHAR_INT_VALUE, String.class, String.valueOf(CHAR_INT_VALUE)}, + {"Tests that the method returns a String value from a Boolean", Boolean.TRUE, String.class, String.valueOf(Boolean.TRUE)}, + {"Tests that the method returns a String value from a String", ONE_AS_STRING, String.class, ONE_AS_STRING}, }; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java new file mode 100644 index 000000000..a4b2c8f27 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Type conversion test package. + */ +package com.hotels.beans.conversion; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index 7585c9787..8de29f251 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -17,7 +17,6 @@ package com.hotels.beans.conversion.processor; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; From 7e250a794824bc77919eed5d25ac274ef04eee4d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 10 Jul 2019 12:17:04 +0200 Subject: [PATCH 0716/1786] Modified checkstyle rule in order to not raise exception in case an import is used inside a javadoc --- config/checkstyle/rules.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/checkstyle/rules.xml b/config/checkstyle/rules.xml index 644d056f3..04498920d 100644 --- a/config/checkstyle/rules.xml +++ b/config/checkstyle/rules.xml @@ -116,7 +116,7 @@ - + From 98a63364bbedf1094d5995cfbcf37f1ff5c8c09f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 10 Jul 2019 18:06:10 +0200 Subject: [PATCH 0717/1786] Added test for Double and Short conversion --- .../impl/AbstractConversionProcessorTest.java | 4 +- .../impl/DoubleConversionProcessorTest.java | 146 ++++++++++++++++++ .../impl/ShortConversionProcessorTest.java | 145 +++++++++++++++++ 3 files changed, 293 insertions(+), 2 deletions(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java index 1a601c60f..8a5fb7de4 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java @@ -25,8 +25,8 @@ public abstract class AbstractConversionProcessorTest { static final Integer INTEGER_VALUE = 10; static final Long LONG_VALUE = 10L; static final Float FLOAT_VALUE = 10f; - static final Double DOUBLE_VALUE = 10.51; - static final char CHAR_VALUE = 'c'; + static final Double DOUBLE_VALUE = 10d; + static final char CHAR_VALUE = '1'; static final Boolean BOOLEAN_VALUE = Boolean.TRUE; static final String STRING_VALUE = "140"; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java new file mode 100644 index 000000000..fed25703c --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java @@ -0,0 +1,146 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Character.getNumericValue; +import static java.lang.Double.valueOf; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link DoubleConversionProcessor}. + */ +public class DoubleConversionProcessorTest extends AbstractConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private DoubleConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + + // WHEN + Double actual = underTest.convertByte().apply(BYTE_VALUE); + + // THEN + assertEquals((Double) BYTE_VALUE.doubleValue(), actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + + // WHEN + Double actual = underTest.convertShort().apply(SHORT_VALUE); + + // THEN + assertEquals(DOUBLE_VALUE, actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + + // WHEN + Double actual = underTest.convertInteger().apply(INTEGER_VALUE); + + // THEN + assertEquals((Double) INTEGER_VALUE.doubleValue(), actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + + // WHEN + Double actual = underTest.convertLong().apply(LONG_VALUE); + + // THEN + assertEquals((Double) LONG_VALUE.doubleValue(), actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + + // WHEN + Double actual = underTest.convertFloat().apply(FLOAT_VALUE); + + // THEN + assertEquals((Double) FLOAT_VALUE.doubleValue(), actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + + // WHEN + Double actual = underTest.convertDouble().apply(DOUBLE_VALUE); + + // THEN + assertEquals(DOUBLE_VALUE, actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + + // WHEN + Double actual = underTest.convertCharacter().apply(CHAR_VALUE); + + // THEN + assertEquals(valueOf((short) getNumericValue(CHAR_VALUE)), actual); + } + + @Test + public void testConvertBooleanShouldReturnProperResult() { + // GIVEN + + // WHEN + Double actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + + // THEN + assertEquals(BOOLEAN_VALUE, actual.equals((double) 1)); + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + + // WHEN + Double actual = underTest.convertString().apply(STRING_VALUE); + + // THEN + assertEquals(valueOf(STRING_VALUE), actual); + } +} + diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java new file mode 100644 index 000000000..bc6769e71 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java @@ -0,0 +1,145 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Character.getNumericValue; +import static java.lang.Short.valueOf; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ShortConversionProcessor}. + */ +public class ShortConversionProcessorTest extends AbstractConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private ShortConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + + // WHEN + Short actual = underTest.convertByte().apply(BYTE_VALUE); + + // THEN + assertEquals((Short) BYTE_VALUE.shortValue(), actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + + // WHEN + Short actual = underTest.convertShort().apply(SHORT_VALUE); + + // THEN + assertEquals(SHORT_VALUE, actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + + // WHEN + Short actual = underTest.convertInteger().apply(INTEGER_VALUE); + + // THEN + assertEquals((Short) INTEGER_VALUE.shortValue(), actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + + // WHEN + Short actual = underTest.convertLong().apply(LONG_VALUE); + + // THEN + assertEquals((Short) LONG_VALUE.shortValue(), actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + + // WHEN + Short actual = underTest.convertFloat().apply(FLOAT_VALUE); + + // THEN + assertEquals((Short) FLOAT_VALUE.shortValue(), actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + + // WHEN + Short actual = underTest.convertDouble().apply(DOUBLE_VALUE); + + // THEN + assertEquals((Short) DOUBLE_VALUE.shortValue(), actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + + // WHEN + Short actual = underTest.convertCharacter().apply(CHAR_VALUE); + + // THEN + assertEquals(valueOf((short) getNumericValue(CHAR_VALUE)), actual); + } + + @Test + public void testConvertBooleanShouldReturnProperResult() { + // GIVEN + + // WHEN + Short actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + + // THEN + assertEquals(BOOLEAN_VALUE, actual.equals((short) 1)); + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + + // WHEN + Short actual = underTest.convertString().apply(STRING_VALUE); + + // THEN + assertEquals(valueOf(STRING_VALUE), actual); + } +} From 900edbb000da00f762b8f4e131a4555411afa346 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 10:06:58 +0200 Subject: [PATCH 0718/1786] Updated documentation for the automatic primitive type conversion --- README.md | 30 +++++++++++++- .../hotels/beans/conversion/Converter.java | 2 +- docs/site/markdown/converter/samples.md | 40 +++++++++++++++++++ docs/site/markdown/index.md | 19 ++++++++- docs/site/markdown/transformer/samples.md | 27 +++++++++++++ docs/site/site.xml | 3 ++ 6 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 docs/site/markdown/converter/samples.md diff --git a/README.md b/README.md index a0001d08d..8f44d352e 100644 --- a/README.md +++ b/README.md @@ -72,12 +72,14 @@ mvnw.cmd clean install -P relaxed * easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. * allows to set the default value for all objects not existing in the source object. * allows to skip transformation for a given set of fields. -* supports the values retrieval from getters if a field does not exists in the source object +* supports the values retrieval from getters if a field does not exists in the source object. +* supports the automatic conversion of primitive types. # Feature samples * [Transformation](https://github.com/HotelsDotCom/bull#transformation-samples) * [Validation](https://github.com/HotelsDotCom/bull#validation-samples) +* [Primitive Type automatic conversion](https://github.com/HotelsDotCom/bull#validation-samples) ## Transformation samples @@ -665,6 +667,32 @@ in case it's needed to have the `ConstraintViolation` object: Set> violatedConstraints = beanUtils.getValidator().getConstraintViolations(sampleBean); ~~~ +### Transform primitive types automatically + +Given the following Java Bean: + +~~~Java +public class FromBean { public class ToBean { + private final String indexNumber; private final int indexNumber; + private final BigInteger id; public Long id; + + // constructors... // constructors... + // getters... // getters and setters... + +} } +~~~ + +as, by default the primitive type conversion is disabled, to get the above object converted we should have +implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically from enabling the +functionality described above. + +~~~Java +Transformer transformer = beanUtils.getTransformer() + .setDefaultPrimitiveTypeConversionEnabled(true); + +ToBean toBean = transformer.transform(fromBean, ToBean.class); +~~~ + ## Constraints: * the class's fields that have to be copied must not be static diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java index 30fa9c39c..a0f7f4e68 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java @@ -33,7 +33,7 @@ public interface Converter { /** - * Converts a given primitive value into the given type. + * Converts a given primitive value into the given primitive type. * @param valueToConvert the value to be converted * @param targetClass the destination field class * @return the converted value diff --git a/docs/site/markdown/converter/samples.md b/docs/site/markdown/converter/samples.md new file mode 100644 index 000000000..17d95fd42 --- /dev/null +++ b/docs/site/markdown/converter/samples.md @@ -0,0 +1,40 @@ + + Samples + + +# Converter Samples + +### Convert a String into an int: + +Given the following variable: + +~~~Java +String indexNumber = "26062019"; +~~~ + +to convert it in an `int`: + +~~~Java +Converter converter = new BeanUtils().getPrimitiveTypeConverter(); +int indexNumber = converter.convertValue(indexNumber, int.class); +~~~ + +### Obtain a conversion function that convert from char to byte: + +It's possible to obtain a type conversion function, reusable several time in different places. +Assuming that the required conversion is from `char` to `byte + +~~~Java +char c = '1'; +~~~ + +the conversion function is retrieved through: + +~~~Java +Converter converter = new BeanUtils().getPrimitiveTypeConverter(); +Optional> conversionFunction = converter.getConversionFunction(char.class, byte.class); +byte converted = conversionFunction.map(processor -> processor.apply(c)).orElse(0); +~~~ + +* in case the conversion is not needed as the primitive type and the destination type are the same it will return an empty `Optional` +* in case the conversion function is unavailable or no not possible the method throws a : `TypeConversionException` diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 5eb5c6439..754de6569 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -44,9 +44,24 @@ The validation works with both the default `javax.constraints` provided by Java * Java Bean validation * Retrieve the violated constraints -#### Primitive object automatic conversion: +#### Primitive type object automatic conversion: -Transforms any primitive type value into another one. +Converts a given primitive value into the given primitive type. +The supported types, in which an object can be converted (from / to), are: + +* `Byte` or `byte` +* `Short` or `short` +* `Integer` or `int` +* `Long` or `long` +* `Float` or `float` +* `Double` or `double` +* `Character` or `char` +* `Boolean` or `boolean` +* `String` + +##### Features: +* Primitive type conversion +* Get a conversion function that converts a primitive type into the given one #### Related articles diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 85bd1fd26..31c348ef5 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -438,6 +438,7 @@ beanUtils.getTransformer() ~~~ ### Not existing field in the source object: + In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library gets the field value from that method. ~~~Java public class FromBean { public class ToBean { @@ -453,4 +454,30 @@ And one line code as: ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); ~~~ +### Transform primitive types automatically + +Given the following Java Bean: + +~~~Java +public class FromBean { public class ToBean { + private final String indexNumber; private final int indexNumber; + private final BigInteger id; public Long id; + + // constructors... // constructors... + // getters... // getters and setters... + +} } +~~~ + +as, by default the primitive type conversion is disabled, to get the above object converted we should have +implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically from enabling the +functionality described above. + +~~~Java +Transformer transformer = beanUtils.getTransformer() + .setDefaultPrimitiveTypeConversionEnabled(true); + +ToBean toBean = transformer.transform(fromBean, ToBean.class); +~~~ + More sample beans can be found in the test package: `com.hotels.beans.sample` or on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) \ No newline at end of file diff --git a/docs/site/site.xml b/docs/site/site.xml index ca83d967a..3a04306ce 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -35,6 +35,9 @@

      + + + From 5a1d7f0141a4306441c086064e798561c5b38bcd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 10:52:35 +0200 Subject: [PATCH 0719/1786] Updated readme with converter examples --- README.md | 84 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 8f44d352e..d5f830660 100644 --- a/README.md +++ b/README.md @@ -533,6 +533,36 @@ And one line code as: ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); ~~~ +### Transform primitive types automatically + +Given the following Java Bean: + +~~~Java +public class FromBean { public class ToBean { + private final String indexNumber; private final int indexNumber; + private final BigInteger id; public Long id; + + // constructors... // constructors... + // getters... // getters and setters... + +} } +~~~ + +as, by default the primitive type conversion is disabled, to get the above object converted we should have +implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically from enabling the +functionality described above. + +~~~Java +Transformer transformer = beanUtils.getTransformer() + .setDefaultPrimitiveTypeConversionEnabled(true); + +ToBean toBean = transformer.transform(fromBean, ToBean.class); +~~~ + +## Constraints: + +* the class's fields that have to be copied must not be static + More sample beans can be found in the test package: `com.hotels.beans.sample` ## Third party library comparison @@ -667,35 +697,55 @@ in case it's needed to have the `ConstraintViolation` object: Set> violatedConstraints = beanUtils.getValidator().getConstraintViolations(sampleBean); ~~~ -### Transform primitive types automatically +## Primitive type object converter -Given the following Java Bean: +Converts a given primitive value into the given primitive type. +The supported types, in which an object can be converted (from / to), are: -~~~Java -public class FromBean { public class ToBean { - private final String indexNumber; private final int indexNumber; - private final BigInteger id; public Long id; +* `Byte` or `byte` +* `Short` or `short` +* `Integer` or `int` +* `Long` or `long` +* `Float` or `float` +* `Double` or `double` +* `Character` or `char` +* `Boolean` or `boolean` +* `String` - // constructors... // constructors... - // getters... // getters and setters... +### Convert a String into an int: -} } +Given the following variable: + +~~~Java +String indexNumber = "26062019"; ~~~ -as, by default the primitive type conversion is disabled, to get the above object converted we should have -implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically from enabling the -functionality described above. +to convert it in an `int`: ~~~Java -Transformer transformer = beanUtils.getTransformer() - .setDefaultPrimitiveTypeConversionEnabled(true); +Converter converter = new BeanUtils().getPrimitiveTypeConverter(); +int indexNumber = converter.convertValue(indexNumber, int.class); +~~~ -ToBean toBean = transformer.transform(fromBean, ToBean.class); +### Obtain a conversion function that convert from char to byte: + +It's possible to obtain a type conversion function, reusable several time in different places. +Assuming that the required conversion is from `char` to `byte + +~~~Java +char c = '1'; ~~~ -## Constraints: +the conversion function is retrieved through: -* the class's fields that have to be copied must not be static +~~~Java +Converter converter = new BeanUtils().getPrimitiveTypeConverter(); +Optional> conversionFunction = converter.getConversionFunction(char.class, byte.class); +byte converted = conversionFunction.map(processor -> processor.apply(c)).orElse(0); +~~~ + +* in case the conversion is not needed as the primitive type and the destination type are the same it will return an empty `Optional` +* in case the conversion function is unavailable or no not possible the method throws a : `TypeConversionException` ## Documentation From cfddc916f0d228a780fdc1b23522db59637ad926 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 10:53:43 +0200 Subject: [PATCH 0720/1786] Link to automatic conversion --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5f830660..8a7d7ea8f 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ mvnw.cmd clean install -P relaxed * [Transformation](https://github.com/HotelsDotCom/bull#transformation-samples) * [Validation](https://github.com/HotelsDotCom/bull#validation-samples) -* [Primitive Type automatic conversion](https://github.com/HotelsDotCom/bull#validation-samples) +* [Primitive Type automatic conversion](https://github.com/HotelsDotCom/bull/tree/feature/basic-type-automatic-conversion#primitive-type-object-converter) ## Transformation samples From 3ca0a9ab9fcf02ecf205b7757228bd97c1fa90c7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 11:45:00 +0200 Subject: [PATCH 0721/1786] Updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a7d7ea8f..240e39912 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ mvnw.cmd clean install -P relaxed * [Transformation](https://github.com/HotelsDotCom/bull#transformation-samples) * [Validation](https://github.com/HotelsDotCom/bull#validation-samples) -* [Primitive Type automatic conversion](https://github.com/HotelsDotCom/bull/tree/feature/basic-type-automatic-conversion#primitive-type-object-converter) +* [Primitive Type conversion](https://github.com/HotelsDotCom/bull#primitive-type-object-converter) ## Transformation samples From e025b27eb6c1bd5c097d3ef255663bd5fa0e2368 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 11:59:15 +0200 Subject: [PATCH 0722/1786] Added UT for Boolean conversion --- .../impl/BooleanConversionProcessorTest.java | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java new file mode 100644 index 000000000..95f2ed8cc --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java @@ -0,0 +1,128 @@ +package com.hotels.beans.conversion.processor.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link BooleanConversionProcessor}. + */ +public class BooleanConversionProcessorTest extends AbstractConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private BooleanConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + + // WHEN + boolean actual = underTest.convertByte().apply(BYTE_VALUE); + + // THEN + assertTrue(actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + + // WHEN + boolean actual = underTest.convertShort().apply(SHORT_VALUE); + + // THEN + assertTrue(actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + + // WHEN + boolean actual = underTest.convertInteger().apply(INTEGER_VALUE); + + // THEN + assertTrue(actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + + // WHEN + boolean actual = underTest.convertLong().apply(LONG_VALUE); + + // THEN + assertTrue(actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + + // WHEN + boolean actual = underTest.convertFloat().apply(FLOAT_VALUE); + + // THEN + assertTrue(actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + + // WHEN + boolean actual = underTest.convertDouble().apply(DOUBLE_VALUE); + + // THEN + assertTrue(actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + + // WHEN + boolean actual = underTest.convertCharacter().apply(CHAR_VALUE); + + // THEN + assertFalse(actual); + } + + @Test + public void testConvertBooleanShouldReturnProperResult() { + // GIVEN + + // WHEN + boolean actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + + // THEN + assertEquals(BOOLEAN_VALUE, actual); + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + + // WHEN + boolean actual = underTest.convertString().apply(TRUE_AS_STRING); + + // THEN + assertTrue(actual); + } +} From 84122317ccb60479e9108a877b8950686486a7d6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 12:00:25 +0200 Subject: [PATCH 0723/1786] Added missing constant required for tests --- .../processor/impl/AbstractConversionProcessorTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java index 8a5fb7de4..270ccd586 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java @@ -29,4 +29,5 @@ public abstract class AbstractConversionProcessorTest { static final char CHAR_VALUE = '1'; static final Boolean BOOLEAN_VALUE = Boolean.TRUE; static final String STRING_VALUE = "140"; + static final String TRUE_AS_STRING = "true"; } From bf8006df2d70c18effbb552e066b638c896a4096 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 12:09:09 +0200 Subject: [PATCH 0724/1786] Fixed checkstyle --- .../impl/BooleanConversionProcessorTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java index 95f2ed8cc..99d038846 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java @@ -1,3 +1,19 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hotels.beans.conversion.processor.impl; import static org.junit.Assert.assertEquals; From bf7f8b23f5f25effee5b8cbd162a87805abdf285 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 14:59:06 +0200 Subject: [PATCH 0725/1786] Added UT for ByteConversionProcessor --- .../impl/AbstractConversionProcessorTest.java | 2 +- .../impl/ByteConversionProcessorTest.java | 128 ++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java index 270ccd586..7d8edb81a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java @@ -28,6 +28,6 @@ public abstract class AbstractConversionProcessorTest { static final Double DOUBLE_VALUE = 10d; static final char CHAR_VALUE = '1'; static final Boolean BOOLEAN_VALUE = Boolean.TRUE; - static final String STRING_VALUE = "140"; + static final String STRING_VALUE = "10"; static final String TRUE_AS_STRING = "true"; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java new file mode 100644 index 000000000..a95f058ab --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java @@ -0,0 +1,128 @@ +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Byte.valueOf; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ByteConversionProcessor}. + */ +public class ByteConversionProcessorTest extends AbstractConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private ByteConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + + // WHEN + Byte actual = underTest.convertByte().apply(BYTE_VALUE); + + // THEN + assertEquals(BYTE_VALUE, actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + + // WHEN + byte actual = underTest.convertShort().apply(SHORT_VALUE); + + // THEN + assertEquals(SHORT_VALUE.byteValue(), actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + + // WHEN + byte actual = underTest.convertInteger().apply(INTEGER_VALUE); + + // THEN + assertEquals(INTEGER_VALUE.byteValue(), actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + + // WHEN + byte actual = underTest.convertLong().apply(LONG_VALUE); + + // THEN + assertEquals(LONG_VALUE.byteValue(), actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + + // WHEN + byte actual = underTest.convertFloat().apply(FLOAT_VALUE); + + // THEN + assertEquals(FLOAT_VALUE.byteValue(), actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + + // WHEN + byte actual = underTest.convertDouble().apply(DOUBLE_VALUE); + + // THEN + assertEquals(DOUBLE_VALUE.byteValue(), actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + + // WHEN + byte actual = underTest.convertCharacter().apply(CHAR_VALUE); + + // THEN + assertEquals((byte) CHAR_VALUE, actual); + } + + @Test + public void testConvertBooleanShouldReturnProperResult() { + // GIVEN + + // WHEN + byte actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + + // THEN + assertEquals(1, actual); + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + + // WHEN + Byte actual = underTest.convertString().apply(STRING_VALUE); + + // THEN + assertEquals(valueOf(STRING_VALUE), actual); + } +} From 17f4dc6228fffb1557d778de2330b9d582fa4e0c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 17:14:09 +0200 Subject: [PATCH 0726/1786] Modified test behaviour and added test cases --- .../impl/BooleanConversionProcessor.java | 2 +- .../impl/ByteConversionProcessor.java | 2 +- .../impl/CharacterConversionProcessor.java | 16 +- .../beans/conversion/ConverterTest.java | 16 +- .../impl/AbstractConversionProcessorTest.java | 2 + .../impl/BooleanConversionProcessorTest.java | 27 +++- .../impl/ByteConversionProcessorTest.java | 16 ++ .../CharacterConversionProcessorTest.java | 142 +++++++++++++++++ .../impl/StringConversionProcessorTest.java | 144 ++++++++++++++++++ 9 files changed, 346 insertions(+), 21 deletions(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java index 1d99ea782..3bdbb00c5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -74,7 +74,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return Character::isLetter; + return val -> val == 'T'; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index b931a5b45..01c859a27 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -88,7 +88,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? (byte) 1 : (byte) 0); + return val -> val ? (byte) 1 : (byte) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java index 586d9cdb2..55702f3a7 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -20,6 +20,8 @@ import com.hotels.beans.conversion.processor.ConversionProcessor; +import lombok.val; + /** * Provides all method for converting any primitive type to a {@link Character}. */ @@ -30,7 +32,7 @@ public final class CharacterConversionProcessor implements ConversionProcessor { */ @Override public Function convertByte() { - return val -> val.toString().charAt(0); + return val -> (char) val.byteValue(); } /** @@ -38,7 +40,7 @@ public Function convertByte() { */ @Override public Function convertShort() { - return val -> val.toString().charAt(0); + return val -> (char) val.shortValue(); } /** @@ -46,7 +48,7 @@ public Function convertShort() { */ @Override public Function convertInteger() { - return val -> val.toString().charAt(0); + return val -> (char) val.intValue(); } /** @@ -54,7 +56,7 @@ public Function convertInteger() { */ @Override public Function convertLong() { - return val -> val.toString().charAt(0); + return val -> (char) val.longValue(); } /** @@ -62,7 +64,7 @@ public Function convertLong() { */ @Override public Function convertFloat() { - return val -> val.toString().charAt(0); + return val -> (char) val.floatValue(); } /** @@ -70,7 +72,7 @@ public Function convertFloat() { */ @Override public Function convertDouble() { - return val -> val.toString().charAt(0); + return val -> (char) val.doubleValue(); } /** @@ -86,7 +88,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val.toString().charAt(0); + return val -> val ? 'T' : 'F'; } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index c32157fef..7532197ca 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -46,7 +46,7 @@ */ public class ConverterTest { private static final String ONE_AS_STRING = "1"; - private static final char CHAR_VALUE = 'x'; + private static final char CHAR_VALUE = 'T'; private static final char CHAR_INT_VALUE = '1'; private static final byte TRUE_AS_BYTE = 1; private static final int TRUE_AS_INT = 1; @@ -204,14 +204,14 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a byte value from a Boolean", Boolean.TRUE, byte.class, TRUE_AS_BYTE}, {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, // char conversion test cases - {"Tests that the method returns a char value from a byte", Byte.MIN_VALUE, char.class, Byte.valueOf(Byte.MIN_VALUE).toString().charAt(0)}, - {"Tests that the method returns a char value from a short", Short.MIN_VALUE, char.class, Short.valueOf(Short.MIN_VALUE).toString().charAt(0)}, - {"Tests that the method returns a char value from an Integer", Integer.MIN_VALUE, char.class, Integer.valueOf(Integer.MIN_VALUE).toString().charAt(0)}, - {"Tests that the method returns a char value from a Long", Long.MIN_VALUE, char.class, Long.valueOf(Long.MIN_VALUE).toString().charAt(0)}, - {"Tests that the method returns a char value from a Float", Float.MIN_VALUE, char.class, Float.valueOf(Float.MIN_VALUE).toString().charAt(0)}, - {"Tests that the method returns a char value from a Double", Double.MIN_VALUE, char.class, Double.valueOf(Double.MIN_VALUE).toString().charAt(0)}, + {"Tests that the method returns a char value from a byte", Byte.MIN_VALUE, char.class, (char) Byte.MIN_VALUE}, + {"Tests that the method returns a char value from a short", Short.MIN_VALUE, char.class, (char) Short.MIN_VALUE}, + {"Tests that the method returns a char value from an Integer", Integer.MIN_VALUE, char.class, (char) Integer.MIN_VALUE}, + {"Tests that the method returns a char value from a Long", Long.MIN_VALUE, char.class, (char) Long.MIN_VALUE}, + {"Tests that the method returns a char value from a Float", Float.MIN_VALUE, char.class, (char) Float.MIN_VALUE}, + {"Tests that the method returns a char value from a Double", Double.MIN_VALUE, char.class, (char) Double.MIN_VALUE}, {"Tests that the method returns a char value from a char", CHAR_VALUE, char.class, CHAR_VALUE}, - {"Tests that the method returns a char value from a Boolean", Boolean.TRUE, char.class, Boolean.TRUE.toString().charAt(0)}, + {"Tests that the method returns a char value from a Boolean", Boolean.TRUE, char.class, CHAR_VALUE}, {"Tests that the method returns a char value from a String", ONE_AS_STRING, char.class, ONE_AS_STRING.charAt(0)}, // double conversion test cases {"Tests that the method returns a double value from a byte", Byte.MIN_VALUE, double.class, Byte.valueOf(Byte.MIN_VALUE).doubleValue()}, diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java index 7d8edb81a..0aa7eb9e9 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java @@ -21,6 +21,7 @@ */ public abstract class AbstractConversionProcessorTest { static final Byte BYTE_VALUE = 10; + static final Byte BYTE_VALUE_ZERO = 0; static final Short SHORT_VALUE = 10; static final Integer INTEGER_VALUE = 10; static final Long LONG_VALUE = 10L; @@ -30,4 +31,5 @@ public abstract class AbstractConversionProcessorTest { static final Boolean BOOLEAN_VALUE = Boolean.TRUE; static final String STRING_VALUE = "10"; static final String TRUE_AS_STRING = "true"; + static final char TRUE_AS_CHAR = 'T'; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java index 99d038846..5755cda5a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java @@ -23,6 +23,7 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** @@ -43,15 +44,33 @@ public void beforeClass() { initMocks(this); } - @Test - public void testConvertByteShouldReturnProperResult() { + /** + * Tests that the method {@code convertByte} returns the expected boolean. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "byteToBooleanConvertValueTesting") + public void testConvertByteShouldReturnProperResult(final String testCaseDescription, final byte valueToConvert, boolean expectedResult) { // GIVEN // WHEN - boolean actual = underTest.convertByte().apply(BYTE_VALUE); + boolean actual = underTest.convertByte().apply(valueToConvert); // THEN - assertTrue(actual); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertByte} returns the expected result. + * @return parameters to be used for testing that the method {@code convertByte} returns the expected result. + */ + @DataProvider + private Object[][] byteToBooleanConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns true if the value is not 0", BYTE_VALUE, true}, + {"Tests that the method returns false if the value is 0", BYTE_VALUE_ZERO, false} + }; } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java index a95f058ab..c691b6de6 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java @@ -1,3 +1,19 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hotels.beans.conversion.processor.impl; import static java.lang.Byte.valueOf; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java new file mode 100644 index 000000000..c4fa50167 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java @@ -0,0 +1,142 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link CharacterConversionProcessor}. + */ +public class CharacterConversionProcessorTest extends AbstractConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private CharacterConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + + // WHEN + char actual = underTest.convertByte().apply(BYTE_VALUE); + + // THEN + assertEquals((char) BYTE_VALUE.byteValue(), actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + + // WHEN + char actual = underTest.convertShort().apply(SHORT_VALUE); + + // THEN + assertEquals((char) SHORT_VALUE.byteValue(), actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + + // WHEN + char actual = underTest.convertInteger().apply(INTEGER_VALUE); + + // THEN + assertEquals((char) INTEGER_VALUE.intValue(), actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + + // WHEN + char actual = underTest.convertLong().apply(LONG_VALUE); + + // THEN + assertEquals((char) LONG_VALUE.longValue(), actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + + // WHEN + char actual = underTest.convertFloat().apply(FLOAT_VALUE); + + // THEN + assertEquals((char) FLOAT_VALUE.floatValue(), actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + + // WHEN + char actual = underTest.convertDouble().apply(DOUBLE_VALUE); + + // THEN + assertEquals((char) DOUBLE_VALUE.doubleValue(), actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + + // WHEN + char actual = underTest.convertCharacter().apply(CHAR_VALUE); + + // THEN + assertEquals(CHAR_VALUE, actual); + } + + @Test + public void testConvertBooleanShouldReturnProperResult() { + // GIVEN + + // WHEN + char actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + + // THEN + assertEquals(TRUE_AS_CHAR, actual); + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + + // WHEN + char actual = underTest.convertString().apply(STRING_VALUE); + + // THEN + assertEquals(STRING_VALUE.charAt(0), actual); + } +} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java new file mode 100644 index 000000000..9e6bc4093 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java @@ -0,0 +1,144 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.String.valueOf; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Unit test for {@link StringConversionProcessor}. + */ +public class StringConversionProcessorTest extends AbstractConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private StringConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + + // WHEN + String actual = underTest.convertByte().apply(BYTE_VALUE); + + // THEN + assertEquals(BYTE_VALUE.toString(), actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + + // WHEN + String actual = underTest.convertShort().apply(SHORT_VALUE); + + // THEN + assertEquals(SHORT_VALUE.toString(), actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + + // WHEN + String actual = underTest.convertInteger().apply(INTEGER_VALUE); + + // THEN + assertEquals(INTEGER_VALUE.toString(), actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + + // WHEN + String actual = underTest.convertLong().apply(LONG_VALUE); + + // THEN + assertEquals(LONG_VALUE.toString(), actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + + // WHEN + String actual = underTest.convertFloat().apply(FLOAT_VALUE); + + // THEN + assertEquals(FLOAT_VALUE.toString(), actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + + // WHEN + String actual = underTest.convertDouble().apply(DOUBLE_VALUE); + + // THEN + assertEquals(DOUBLE_VALUE.toString(), actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + + // WHEN + String actual = underTest.convertCharacter().apply(CHAR_VALUE); + + // THEN + assertEquals(valueOf(CHAR_VALUE), actual); + } + + @Test + public void testConvertBooleanShouldReturnProperResult() { + // GIVEN + + // WHEN + String actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + + // THEN + assertEquals(BOOLEAN_VALUE.toString(), actual); + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + + // WHEN + String actual = underTest.convertString().apply(STRING_VALUE); + + // THEN + assertEquals(STRING_VALUE, actual); + } +} From aca04321a00de9efebe333968b9be4e348bf6658 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 17:28:18 +0200 Subject: [PATCH 0727/1786] Finalized boolean conversion test cases --- .../impl/AbstractConversionProcessorTest.java | 6 + .../impl/BooleanConversionProcessorTest.java | 132 +++++++++++++++--- .../CharacterConversionProcessorTest.java | 27 +++- 3 files changed, 140 insertions(+), 25 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java index 0aa7eb9e9..406cd5020 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java @@ -23,13 +23,19 @@ public abstract class AbstractConversionProcessorTest { static final Byte BYTE_VALUE = 10; static final Byte BYTE_VALUE_ZERO = 0; static final Short SHORT_VALUE = 10; + static final Short SHORT_VALUE_ZERO = 0; static final Integer INTEGER_VALUE = 10; + static final Integer INTEGER_VALUE_ZERO = 0; static final Long LONG_VALUE = 10L; + static final Long LONG_VALUE_ZERO = 0L; static final Float FLOAT_VALUE = 10f; + static final Float FLOAT_VALUE_ZERO = 0f; static final Double DOUBLE_VALUE = 10d; + static final Double DOUBLE_VALUE_ZERO = 0d; static final char CHAR_VALUE = '1'; static final Boolean BOOLEAN_VALUE = Boolean.TRUE; static final String STRING_VALUE = "10"; static final String TRUE_AS_STRING = "true"; static final char TRUE_AS_CHAR = 'T'; + static final char FALSE_AS_CHAR = 'F'; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java index 5755cda5a..552bd0dec 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java @@ -51,7 +51,7 @@ public void beforeClass() { * @param expectedResult the expected result */ @Test(dataProvider = "byteToBooleanConvertValueTesting") - public void testConvertByteShouldReturnProperResult(final String testCaseDescription, final byte valueToConvert, boolean expectedResult) { + public void testConvertByteShouldReturnProperResult(final String testCaseDescription, final byte valueToConvert, final boolean expectedResult) { // GIVEN // WHEN @@ -73,59 +73,149 @@ private Object[][] byteToBooleanConvertValueTesting() { }; } - @Test - public void testConvertShortShouldReturnProperResult() { + /** + * Tests that the method {@code convertShort} returns the expected boolean. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "shortToBooleanConvertValueTesting") + public void testConvertShortShouldReturnProperResult(final String testCaseDescription, final short valueToConvert, final boolean expectedResult) { // GIVEN // WHEN - boolean actual = underTest.convertShort().apply(SHORT_VALUE); + boolean actual = underTest.convertShort().apply(valueToConvert); // THEN - assertTrue(actual); + assertEquals(expectedResult, actual); } - @Test - public void testConvertIntegerShouldReturnProperResult() { + /** + * Creates the parameters to be used for testing that the method {@code convertShort} returns the expected result. + * @return parameters to be used for testing that the method {@code convertShort} returns the expected result. + */ + @DataProvider + private Object[][] shortToBooleanConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns true if the value is not 0", SHORT_VALUE, true}, + {"Tests that the method returns false if the value is 0", SHORT_VALUE_ZERO, false} + }; + } + + /** + * Tests that the method {@code convertInteger} returns the expected boolean. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "intToBooleanConvertValueTesting") + public void testConvertIntegerShouldReturnProperResult(final String testCaseDescription, final int valueToConvert, final boolean expectedResult) { // GIVEN // WHEN - boolean actual = underTest.convertInteger().apply(INTEGER_VALUE); + boolean actual = underTest.convertInteger().apply(valueToConvert); // THEN - assertTrue(actual); + assertEquals(expectedResult, actual); } - @Test - public void testConvertLongShouldReturnProperResult() { + /** + * Creates the parameters to be used for testing that the method {@code convertInteger} returns the expected result. + * @return parameters to be used for testing that the method {@code convertInteger} returns the expected result. + */ + @DataProvider + private Object[][] intToBooleanConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns true if the value is not 0", INTEGER_VALUE, true}, + {"Tests that the method returns false if the value is 0", INTEGER_VALUE_ZERO, false} + }; + } + + /** + * Tests that the method {@code convertLong} returns the expected boolean. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "longToBooleanConvertValueTesting") + public void testConvertLongShouldReturnProperResult(final String testCaseDescription, final long valueToConvert, final boolean expectedResult) { // GIVEN // WHEN - boolean actual = underTest.convertLong().apply(LONG_VALUE); + boolean actual = underTest.convertLong().apply(valueToConvert); // THEN - assertTrue(actual); + assertEquals(expectedResult, actual); } - @Test - public void testConvertFloatShouldReturnProperResult() { + /** + * Creates the parameters to be used for testing that the method {@code convertLong} returns the expected result. + * @return parameters to be used for testing that the method {@code convertLong} returns the expected result. + */ + @DataProvider + private Object[][] longToBooleanConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns true if the value is not 0", LONG_VALUE, true}, + {"Tests that the method returns false if the value is 0", LONG_VALUE_ZERO, false} + }; + } + + /** + * Tests that the method {@code convertFloat} returns the expected boolean. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "floatToBooleanConvertValueTesting") + public void testConvertFloatShouldReturnProperResult(final String testCaseDescription, final float valueToConvert, final boolean expectedResult) { // GIVEN // WHEN - boolean actual = underTest.convertFloat().apply(FLOAT_VALUE); + boolean actual = underTest.convertFloat().apply(valueToConvert); // THEN - assertTrue(actual); + assertEquals(expectedResult, actual); } - @Test - public void testConvertDoubleShouldReturnProperResult() { + /** + * Creates the parameters to be used for testing that the method {@code convertFloat} returns the expected result. + * @return parameters to be used for testing that the method {@code convertFloat} returns the expected result. + */ + @DataProvider + private Object[][] floatToBooleanConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns true if the value is not 0", FLOAT_VALUE, true}, + {"Tests that the method returns false if the value is 0", FLOAT_VALUE_ZERO, false} + }; + } + + /** + * Tests that the method {@code convertDouble} returns the expected boolean. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "floatToBooleanConvertValueTesting") + public void testConvertDoubleShouldReturnProperResult(final String testCaseDescription, final double valueToConvert, final boolean expectedResult) { // GIVEN // WHEN - boolean actual = underTest.convertDouble().apply(DOUBLE_VALUE); + boolean actual = underTest.convertDouble().apply(valueToConvert); // THEN - assertTrue(actual); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertDouble} returns the expected result. + * @return parameters to be used for testing that the method {@code convertDouble} returns the expected result. + */ + @DataProvider + private Object[][] doubleToBooleanConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns true if the value is not 0", DOUBLE_VALUE, true}, + {"Tests that the method returns false if the value is 0", DOUBLE_VALUE_ZERO, false} + }; } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java index c4fa50167..013ca1ed0 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java @@ -21,6 +21,7 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** @@ -118,15 +119,33 @@ public void testConvertCharacterShouldReturnProperResult() { assertEquals(CHAR_VALUE, actual); } - @Test - public void testConvertBooleanShouldReturnProperResult() { + /** + * Tests that the method {@code convertBoolean} returns the expected char. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToCharConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final char expectedResult) { // GIVEN // WHEN - char actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + char actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(TRUE_AS_CHAR, actual); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToCharConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns T if the value is true", BOOLEAN_VALUE, TRUE_AS_CHAR}, + {"Tests that the method returns F if the value is false", Boolean.FALSE, FALSE_AS_CHAR} + }; } @Test From a426a8dbe1b174f5d401a20668b39ef34ec0e8fc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jul 2019 17:49:47 +0200 Subject: [PATCH 0728/1786] Finalized all UT for the converted module --- .../impl/AbstractConversionProcessorTest.java | 2 -- .../impl/ByteConversionProcessorTest.java | 29 +++++++++++++++--- .../CharacterConversionProcessorTest.java | 3 ++ .../impl/DoubleConversionProcessorTest.java | 30 ++++++++++++++++--- .../impl/FloatConversionProcessorTest.java | 30 ++++++++++++++++--- .../impl/IntegerConversionProcessorTest.java | 30 ++++++++++++++++--- .../impl/LongConversionProcessorTest.java | 30 ++++++++++++++++--- .../impl/ShortConversionProcessorTest.java | 30 ++++++++++++++++--- 8 files changed, 158 insertions(+), 26 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java index 406cd5020..24ab17b17 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java @@ -36,6 +36,4 @@ public abstract class AbstractConversionProcessorTest { static final Boolean BOOLEAN_VALUE = Boolean.TRUE; static final String STRING_VALUE = "10"; static final String TRUE_AS_STRING = "true"; - static final char TRUE_AS_CHAR = 'T'; - static final char FALSE_AS_CHAR = 'F'; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java index c691b6de6..d31a08d2d 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java @@ -23,12 +23,15 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * Unit test for {@link ByteConversionProcessor}. */ public class ByteConversionProcessorTest extends AbstractConversionProcessorTest { + private static final byte TRUE_AS_BYTE = 1; + private static final byte FALSE_AS_BYTE = 0; /** * The class to be tested. */ @@ -120,15 +123,33 @@ public void testConvertCharacterShouldReturnProperResult() { assertEquals((byte) CHAR_VALUE, actual); } - @Test - public void testConvertBooleanShouldReturnProperResult() { + /** + * Tests that the method {@code convertBoolean} returns the expected byte. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToByteConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final byte expectedResult) { // GIVEN // WHEN - byte actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + int actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(1, actual); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToByteConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns 1 if the value is true", BOOLEAN_VALUE, TRUE_AS_BYTE}, + {"Tests that the method returns 0 if the value is false", Boolean.FALSE, FALSE_AS_BYTE} + }; } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java index 013ca1ed0..be8dda27c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java @@ -28,6 +28,9 @@ * Unit test for {@link CharacterConversionProcessor}. */ public class CharacterConversionProcessorTest extends AbstractConversionProcessorTest { + private static final char TRUE_AS_CHAR = 'T'; + private static final char FALSE_AS_CHAR = 'F'; + /** * The class to be tested. */ diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java index fed25703c..d0d1c4882 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java @@ -24,12 +24,16 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * Unit test for {@link DoubleConversionProcessor}. */ public class DoubleConversionProcessorTest extends AbstractConversionProcessorTest { + private static final double TRUE_AS_DOUBLE = 1d; + private static final double FALSE_AS_DOUBLE = 0d; + /** * The class to be tested. */ @@ -121,15 +125,33 @@ public void testConvertCharacterShouldReturnProperResult() { assertEquals(valueOf((short) getNumericValue(CHAR_VALUE)), actual); } - @Test - public void testConvertBooleanShouldReturnProperResult() { + /** + * Tests that the method {@code convertBoolean} returns the expected double. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToDoubleConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final double expectedResult) { // GIVEN // WHEN - Double actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + Double actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(BOOLEAN_VALUE, actual.equals((double) 1)); + assertEquals(expectedResult, actual, 0.0); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToDoubleConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns 1 if the value is true", BOOLEAN_VALUE, TRUE_AS_DOUBLE}, + {"Tests that the method returns 0 if the value is false", Boolean.FALSE, FALSE_AS_DOUBLE} + }; } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java index d700e600c..5ee7ab4eb 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java @@ -24,12 +24,16 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * Unit test for {@link FloatConversionProcessor}. */ public class FloatConversionProcessorTest extends AbstractConversionProcessorTest { + private static final float TRUE_AS_FLOAT = 1f; + private static final float FALSE_AS_FLOAT = 0f; + /** * The class to be tested. */ @@ -121,15 +125,33 @@ public void testConvertCharacterShouldReturnProperResult() { assertEquals(Float.valueOf(getNumericValue(CHAR_VALUE)), actual); } - @Test - public void testConvertBooleanShouldReturnProperResult() { + /** + * Tests that the method {@code convertBoolean} returns the expected float. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToFloatConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final float expectedResult) { // GIVEN // WHEN - Float actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + Float actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(BOOLEAN_VALUE, actual.equals(1f)); + assertEquals(expectedResult, actual, 0.0); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToFloatConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns 1 if the value is true", BOOLEAN_VALUE, TRUE_AS_FLOAT}, + {"Tests that the method returns 0 if the value is false", Boolean.FALSE, FALSE_AS_FLOAT} + }; } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java index 825d983ae..8ef34805b 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java @@ -24,12 +24,16 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * Unit test for {@link IntegerConversionProcessor}. */ public class IntegerConversionProcessorTest extends AbstractConversionProcessorTest { + private static final int TRUE_AS_INT = 1; + private static final int FALSE_AS_INT = 0; + /** * The class to be tested. */ @@ -121,15 +125,33 @@ public void testConvertCharacterShouldReturnProperResult() { assertEquals((Integer) getNumericValue(CHAR_VALUE), actual); } - @Test - public void testConvertBooleanShouldReturnProperResult() { + /** + * Tests that the method {@code convertBoolean} returns the expected int. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToIntConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final int expectedResult) { // GIVEN // WHEN - Integer actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + int actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(BOOLEAN_VALUE, actual.equals(1)); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToIntConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns 1 if the value is true", BOOLEAN_VALUE, TRUE_AS_INT}, + {"Tests that the method returns 0 if the value is false", Boolean.FALSE, FALSE_AS_INT} + }; } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java index 346f24b82..0d5c39a30 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java @@ -24,12 +24,16 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * Unit test for {@link LongConversionProcessor}. */ public class LongConversionProcessorTest extends AbstractConversionProcessorTest { + private static final long TRUE_AS_LONG = 1L; + private static final long FALSE_AS_LONG = 0L; + /** * The class to be tested. */ @@ -121,15 +125,33 @@ public void testConvertCharacterShouldReturnProperResult() { assertEquals(valueOf(getNumericValue(CHAR_VALUE)), actual); } - @Test - public void testConvertBooleanShouldReturnProperResult() { + /** + * Tests that the method {@code convertBoolean} returns the expected long. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToLongConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final long expectedResult) { // GIVEN // WHEN - Long actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + long actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(BOOLEAN_VALUE, actual.equals(1L)); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToLongConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns 1 if the value is true", BOOLEAN_VALUE, TRUE_AS_LONG}, + {"Tests that the method returns 0 if the value is false", Boolean.FALSE, FALSE_AS_LONG} + }; } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java index bc6769e71..53ae6843d 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java @@ -24,12 +24,16 @@ import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * Unit test for {@link ShortConversionProcessor}. */ public class ShortConversionProcessorTest extends AbstractConversionProcessorTest { + private static final short TRUE_AS_SHORT = 1; + private static final short FALSE_AS_SHORT = 0; + /** * The class to be tested. */ @@ -121,15 +125,33 @@ public void testConvertCharacterShouldReturnProperResult() { assertEquals(valueOf((short) getNumericValue(CHAR_VALUE)), actual); } - @Test - public void testConvertBooleanShouldReturnProperResult() { + /** + * Tests that the method {@code convertBoolean} returns the expected short. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToShortConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final short expectedResult) { // GIVEN // WHEN - Short actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); + short actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(BOOLEAN_VALUE, actual.equals((short) 1)); + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToShortConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns 1 if the value is true", BOOLEAN_VALUE, TRUE_AS_SHORT}, + {"Tests that the method returns 0 if the value is false", Boolean.FALSE, FALSE_AS_SHORT} + }; } @Test From 078326b265c70d110439d42b76e85d02b34c393d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Jul 2019 09:39:41 +0200 Subject: [PATCH 0729/1786] Added UT for the primitive type conversion --- .../transformer/AbstractTransformer.java | 2 +- .../beans/transformer/TransformerImpl.java | 4 +- .../transformer/TransformerSettings.java | 2 +- .../MutableObjectTransformationTest.java | 44 +++++++++++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 5a9a2f45d..327648b7e 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -142,7 +142,7 @@ public final void resetFieldsTransformer() { */ @Override public final Transformer setDefaultValueForMissingField(final boolean useDefaultValue) { - settings.setSetDefaultValue(useDefaultValue); + settings.setSetDefaultValueForMissingFields(useDefaultValue); return this; } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index b495c912b..1dd98f0df 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -376,7 +376,7 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie // in case the source field is a primitive type and the destination one is composite, the source field value is returned without going in deep if (classUtils.isPrimitiveType(sourceObj.getClass())) { fieldValue = sourceObj; - } else if (!isFieldTransformerDefined && !settings.isSetDefaultValue()) { + } else if (!isFieldTransformerDefined && !settings.isSetDefaultValueForMissingFields()) { throw e; } } catch (Exception e) { @@ -405,7 +405,7 @@ private Class getSourceFieldType(final Class sourceObjectClass, final Stri // the source field type is returned without going in deep if (classUtils.isPrimitiveType(sourceObjectClass)) { classType = sourceObjectClass; - } else if (!settings.isSetDefaultValue()) { + } else if (!settings.isSetDefaultValueForMissingFields()) { throw e; } } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index f2bf56dde..03c79e233 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -60,7 +60,7 @@ final class TransformerSettings { * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. */ @Setter - private boolean setDefaultValue; + private boolean setDefaultValueForMissingFields; /** * It allows to apply a transformation to all fields matching with the provided name without using their whole path. diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index d4887c0a5..e20df41f8 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -21,6 +21,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; @@ -33,6 +34,7 @@ import org.testng.annotations.Test; import com.hotels.beans.error.InvalidBeanException; +import com.hotels.beans.error.MissingFieldException; import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooNoField; import com.hotels.beans.sample.FromFooSimple; @@ -230,6 +232,48 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); } + /** + * Test that a bean containing a field not existing in the source object, and without a transformer function defined throws + * MissingFieldException even if the primitiveTypeConversionFunction is enabled. + */ + @Test + public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeConversionIsEnabled() { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); + underTest.setDefaultPrimitiveTypeConversionEnabled(true); + + //WHEN + Exception raisedException = null; + try { + underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); + } catch (final Exception e) { + raisedException = e; + } + + //THEN + assertEquals(MissingFieldException.class, raisedException.getCause().getClass()); + underTest.setDefaultPrimitiveTypeConversionEnabled(false); + } + + /** + * Test that a bean containing a field not existing in the source object, and without a transformer function defined throws + * MissingFieldException even if the primitiveTypeConversionFunction is enabled. + */ + @Test + public void testTransformerDoesNotThrowExceptionIfAFieldIsMissingAndTheDefaultValueSetIsEnabled() { + //GIVEN + FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); + underTest.setDefaultPrimitiveTypeConversionEnabled(true).setDefaultValueForMissingField(true); + + //WHEN + MutableToFooNotExistingFields actual = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); + + //THEN + assertEquals(actual.getId(), fromFooSimple.getId()); + assertEquals(actual.getName(), fromFooSimple.getName()); + underTest.setDefaultPrimitiveTypeConversionEnabled(false).setDefaultValueForMissingField(false); + } + /** * Test transformation field with field transformer. * @param testCaseDescription the test case description From 9259216c45fcd1aa7916047db215da9266b0fe13 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Jul 2019 15:52:37 +0200 Subject: [PATCH 0730/1786] Added UT for the added methods in the Transformer class --- .../beans/performance/PerformanceTest.java | 2 +- .../MutableObjectTransformationTest.java | 2 +- .../beans/transformer/TransformerTest.java | 223 ++++++++++++++++++ .../beans/utils/ReflectionUtilsTest.java | 2 +- .../impl/CharacterConversionProcessor.java | 2 - config/maven/versions-plugin-rules.xml | 3 +- 6 files changed, 228 insertions(+), 6 deletions(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java index b6304a68c..2bdae6618 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -105,7 +105,7 @@ public void beforeClass() { * @param sourceObject the Source object to copy * @param destObjectClass the total destination object * @param maxTransformationTime expected maximum transformation time - * @throws InterruptedException + * @throws InterruptedException if an error occurs during the thread sleep */ @Test(dataProvider = "dataPerformanceTest") public void testCopyPropertiesGetsCompletedInTheExpectedTime(final double totalTransformation, final int waitInterval, diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index e20df41f8..99604c2fc 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -21,7 +21,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; @@ -230,6 +229,7 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor //THEN assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + underTest.resetFieldsTransformer(); } /** diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 00b4f9048..75bd3ad2f 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -16,19 +16,43 @@ package com.hotels.beans.transformer; +import static java.math.BigInteger.ONE; +import static java.math.BigInteger.ZERO; +import static java.util.Collections.emptyMap; +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static java.util.Optional.ofNullable; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; +import static org.springframework.test.util.ReflectionTestUtils.setField; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; import org.mockito.InjectMocks; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.cache.CacheManager; +import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; +import com.hotels.beans.error.MissingFieldException; import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; /** @@ -39,7 +63,13 @@ public class TransformerTest extends AbstractTransformerTest { private static final String SOURCE_FIELD_NAME_2 = "sourceFieldName2"; private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; private static final String GET_SOURCE_FIELD_VALUE_METHOD_NAME = "getSourceFieldValue"; + private static final String GET_SOURCE_FIELD_TYPE_METHOD_NAME = "getSourceFieldType"; private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); + private static final String CACHE_MANAGER_FIELD_NAME = "cacheManager"; + private static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; + private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; + private static final String GET_TRANSFORMER_FUNCTION_METHOD_NAME = "getTransformerFunction"; + private static final String CONVERSION_ANALYZER_FIELD_NAME = "conversionAnalyzer"; /** * The class to be tested. @@ -187,4 +217,197 @@ public void testThatDefaultPrimitiveTypeConversionIsCorrectlyEnabled() { assertTrue(actual); underTest.setDefaultPrimitiveTypeConversionEnabled(false); } + + /** + * Test that the method: {@code getSourceFieldType} returns the source object class in case the given field does not + * exists in the given class and the source object class is primitive. + * @throws Exception if the invoke method fails + */ + @Test + public void testGetSourceFieldTypeReturnsTheSourceObjectClass() throws Exception { + //GIVEN + CacheManager cacheManager = mock(CacheManager.class); + ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + ClassUtils classUtils = mock(ClassUtils.class); + + when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(empty()); + when(reflectionUtils.getDeclaredFieldType(AGE_FIELD_NAME, Integer.class)).thenThrow(MissingFieldException.class); + when(classUtils.isPrimitiveType(Integer.class)).thenReturn(true); + + setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); + setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); + setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + + Method getSourceFieldTypeMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_TYPE_METHOD_NAME, Class.class, String.class); + getSourceFieldTypeMethod.setAccessible(true); + + //WHEN + Class actual = (Class) getSourceFieldTypeMethod.invoke(underTest, Integer.class, AGE_FIELD_NAME); + + //THEN + verify(cacheManager).getFromCache(anyString(), any(Class.class)); + verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, Integer.class); + verify(classUtils).isPrimitiveType(Integer.class); + assertEquals(Integer.class, actual); + restoreUnderTestObject(); + } + + /** + * Test that the method: {@code getSourceFieldType} returns nulls in case the given field does not + * exists in the given class, the source object class is not primitive and the default value set for missing + * fields feature is enabled. + * @throws Exception if the invoke method fails + */ + @Test + public void testGetSourceFieldTypeReturnsNull() throws Exception { + //GIVEN + CacheManager cacheManager = mock(CacheManager.class); + ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + ClassUtils classUtils = mock(ClassUtils.class); + TransformerSettings settings = mock(TransformerSettings.class); + + when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(empty()); + when(reflectionUtils.getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class)).thenThrow(MissingFieldException.class); + when(classUtils.isPrimitiveType(Integer.class)).thenReturn(true); + when(settings.isSetDefaultValueForMissingFields()).thenReturn(true); + + setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); + setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); + setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + setField(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); + + Method getSourceFieldTypeMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_TYPE_METHOD_NAME, Class.class, String.class); + getSourceFieldTypeMethod.setAccessible(true); + + //WHEN + Class actual = (Class) getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); + + //THEN + verify(cacheManager).getFromCache(anyString(), any(Class.class)); + verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); + verify(classUtils).isPrimitiveType(FromFooSimple.class); + verify(settings).isSetDefaultValueForMissingFields(); + assertNull(actual); + restoreUnderTestObject(); + } + + /** + * Test that the method: {@code getSourceFieldType} throws {@link MissingFieldException} in case the given field does not exists + * in the given class and the source object class is not primitive and the default value set for missing fields feature is disabled. + * @throws Exception if the invoke method fails + */ + @Test + public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception { + //GIVEN + CacheManager cacheManager = mock(CacheManager.class); + ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + ClassUtils classUtils = mock(ClassUtils.class); + TransformerSettings settings = mock(TransformerSettings.class); + + when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(empty()); + when(reflectionUtils.getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class)).thenThrow(MissingFieldException.class); + when(classUtils.isPrimitiveType(Integer.class)).thenReturn(false); + when(settings.isSetDefaultValueForMissingFields()).thenReturn(false); + + setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); + setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); + setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + setField(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); + + Method getSourceFieldTypeMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_TYPE_METHOD_NAME, Class.class, String.class); + getSourceFieldTypeMethod.setAccessible(true); + + //WHEN + Exception raisedException = null; + try { + getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); + } catch (final Exception e) { + raisedException = e; + } + + //THEN + verify(cacheManager).getFromCache(anyString(), any(Class.class)); + verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); + verify(classUtils).isPrimitiveType(FromFooSimple.class); + verify(settings).isSetDefaultValueForMissingFields(); + assertNotNull(raisedException); + assertEquals(MissingFieldException.class, raisedException.getCause().getClass()); + restoreUnderTestObject(); + } + + /** + * Test that the {@code getTransformerFunction} works as expected. + * @param testCaseDescription the test case description + * @param fieldName the field name to which the transformer function has to be applied + * @param isDefaultPrimitiveTypeConversionEnabled indicates if the automatic conversion function is enabled + * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not + * @param fieldTransformers the field transformer associated to the given field + * @param sourceFieldType the source field type + * @param expectedFieldTransformerSize the total number of transformation function expected for the given field + * @throws Exception if the method invocation fails + */ + @Test(dataProvider = "dataGetTransformerFunctionTesting") + @SuppressWarnings("unchecked") + public void testGetTransformerFunctionWorksProperly(final String testCaseDescription, final String fieldName, final boolean isDefaultPrimitiveTypeConversionEnabled, + final boolean isDestinationFieldPrimitiveType, final Map fieldTransformers, final Class sourceFieldType, final int expectedFieldTransformerSize) + throws Exception { + //GIVEN + Field field = mock(Field.class); + CacheManager cacheManager = mock(CacheManager.class); + TransformerSettings settings = mock(TransformerSettings.class); + ConversionAnalyzer conversionAnalyzer = mock(ConversionAnalyzer.class); + ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + + when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(ofNullable(sourceFieldType)); + when(settings.isFlatFieldNameTransformation()).thenReturn(false); + when(settings.isDefaultPrimitiveTypeConversionEnabled()).thenReturn(isDefaultPrimitiveTypeConversionEnabled); + when(settings.getFieldsTransformers()).thenReturn(fieldTransformers); + when(conversionAnalyzer.getConversionFunction(any(Class.class), any(Class.class))).thenReturn(of(Object::toString)); + when(field.getType()).thenReturn(sourceFieldType); + when(reflectionUtils.getDeclaredFieldType(fieldName, FromFooSimple.class)).thenReturn(sourceFieldType); + + setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); + setField(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); + setField(underTest, CONVERSION_ANALYZER_FIELD_NAME, conversionAnalyzer); + setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); + + Method getTransformerFunctionMethod = underTest.getClass() + .getDeclaredMethod(GET_TRANSFORMER_FUNCTION_METHOD_NAME, Class.class, String.class, Field.class, boolean.class, String.class); + getTransformerFunctionMethod.setAccessible(true); + + //WHEN + List actual = + (List) getTransformerFunctionMethod.invoke(underTest, FromFooSimple.class, fieldName, field, isDestinationFieldPrimitiveType, fieldName); + + //THEN + assertEquals(expectedFieldTransformerSize, actual.size()); + restoreUnderTestObject(); + } + + /** + * Creates the parameters to be used for testing method {@code getTransformerFunction}. + * @return parameters to be used for testing method {@code getTransformerFunction}. + */ + @DataProvider + private Object[][] dataGetTransformerFunctionTesting() { + return new Object[][] { + {"Test that a type conversion function is added to the existing one if all the conditions are met", + AGE_FIELD_NAME, true, true, emptyMap(), int.class, ONE.intValue()}, + {"Test that no type conversion function is added to the existing one if the source type field is null", + AGE_FIELD_NAME, true, true, emptyMap(), null, ZERO.intValue()}, + {"Test that no conversion function is added to the existing one if the primitive type conversion is disabled", + AGE_FIELD_NAME, false, true, emptyMap(), null, ZERO.intValue()}, + {"Test that no conversion function is added to the existing one if the destination field type is not primitive", + AGE_FIELD_NAME, true, false, emptyMap(), null, ZERO.intValue()}, + {"Test that no conversion function is added to the existing one if there is a field transformer function defined for the existing field", + AGE_FIELD_NAME, true, true, Map.of(AGE_FIELD_NAME, new FieldTransformer<>(AGE_FIELD_NAME, () -> null)), null, ONE.intValue()} + }; + } + + /** + * Restores the underTest object removing all defined mocks. + */ + private void restoreUnderTestObject() { + underTest = new TransformerImpl(); + } } diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index e92d20217..b091af2b5 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -314,7 +314,7 @@ private Object[][] dataGetGetterMethodPrefixTesting() throws Exception { */ @Test(dataProvider = "dataGetFieldAnnotationTesting") public void testGetFieldAnnotationWorksProperly(final String testCaseDescription, final Class annotationToGet, - final boolean expectNull) throws NoSuchFieldException { + final boolean expectNull) { // GIVEN Field nameField = underTest.getDeclaredField(ID_FIELD_NAME, ImmutableToFoo.class); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java index 55702f3a7..a60bf9814 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -20,8 +20,6 @@ import com.hotels.beans.conversion.processor.ConversionProcessor; -import lombok.val; - /** * Provides all method for converting any primitive type to a {@link Character}. */ diff --git a/config/maven/versions-plugin-rules.xml b/config/maven/versions-plugin-rules.xml index fc1620c19..0128a45ae 100644 --- a/config/maven/versions-plugin-rules.xml +++ b/config/maven/versions-plugin-rules.xml @@ -1,5 +1,6 @@ - + (?i).*Alpha(?:-?\d+)? From 71207eb44721150743c14e327628ed7844567a18 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Jul 2019 16:45:25 +0200 Subject: [PATCH 0731/1786] Replaces wildcard into ConversionProcessor class in order to restrict the allowed object type --- .../processor/ConversionProcessor.java | 21 ++++++++++--------- .../impl/BooleanConversionProcessor.java | 2 +- .../impl/ByteConversionProcessor.java | 2 +- .../impl/CharacterConversionProcessor.java | 2 +- .../impl/DoubleConversionProcessor.java | 2 +- .../impl/FloatConversionProcessor.java | 2 +- .../impl/IntegerConversionProcessor.java | 2 +- .../impl/LongConversionProcessor.java | 2 +- .../impl/ShortConversionProcessor.java | 2 +- .../impl/StringConversionProcessor.java | 2 +- 10 files changed, 20 insertions(+), 19 deletions(-) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index 2d8209704..774fca463 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -20,59 +20,60 @@ /** * Conversion methods for all primitive types. + * @param indicates any primitve type object */ -public interface ConversionProcessor { +public interface ConversionProcessor { /** * Converts a {@link Byte} type. * @return the converted value */ - Function convertByte(); + Function convertByte(); /** * Converts a {@link Short} type. * @return the converted value */ - Function convertShort(); + Function convertShort(); /** * Converts an {@link Integer} type. * @return the converted value */ - Function convertInteger(); + Function convertInteger(); /** * Converts a {@link Long} type. * @return the converted value */ - Function convertLong(); + Function convertLong(); /** * Converts an {@link Float} type. * @return the converted value */ - Function convertFloat(); + Function convertFloat(); /** * Converts a {@link Double} type. * @return the converted value */ - Function convertDouble(); + Function convertDouble(); /** * Converts a {@link Character} type. * @return the converted value */ - Function convertCharacter(); + Function convertCharacter(); /** * Converts a {@link Boolean} type. * @return the converted value */ - Function convertBoolean(); + Function convertBoolean(); /** * Converts a {@link String} type. * @return the converted value */ - Function convertString(); + Function convertString(); } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java index 3bdbb00c5..8ee15ceb8 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -23,7 +23,7 @@ /** * Provides all method for converting any primitive type to a {@link Boolean}. */ -public final class BooleanConversionProcessor implements ConversionProcessor { +public final class BooleanConversionProcessor implements ConversionProcessor { @Override public Function convertByte() { return val -> val != 0; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index 01c859a27..1de45aca2 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -25,7 +25,7 @@ /** * Provides all method for converting any primitive type to a {@link Byte}. */ -public final class ByteConversionProcessor implements ConversionProcessor { +public final class ByteConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java index a60bf9814..e3726d889 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -23,7 +23,7 @@ /** * Provides all method for converting any primitive type to a {@link Character}. */ -public final class CharacterConversionProcessor implements ConversionProcessor { +public final class CharacterConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index bb00e2067..c809aff07 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -26,7 +26,7 @@ /** * Provides all method for converting any primitive type to a {@link Double}. */ -public final class DoubleConversionProcessor implements ConversionProcessor { +public final class DoubleConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index 1af32b61d..f5477e6ed 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -26,7 +26,7 @@ /** * Provides all method for converting any primitive type to a {@link Float}. */ -public final class FloatConversionProcessor implements ConversionProcessor { +public final class FloatConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index 64856ed52..cbadfa6b5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -25,7 +25,7 @@ /** * Provides all method for converting any primitive type to a {@link Integer}. */ -public final class IntegerConversionProcessor implements ConversionProcessor { +public final class IntegerConversionProcessor implements ConversionProcessor { @Override public Function convertByte() { diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index a296c583c..89633c158 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -26,7 +26,7 @@ /** * Provides all method for converting any primitive type to a {@link Long}. */ -public final class LongConversionProcessor implements ConversionProcessor { +public final class LongConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index a22ae4799..47f8c453e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -26,7 +26,7 @@ /** * Provides all method for converting any primitive type to a {@link Short}. */ -public final class ShortConversionProcessor implements ConversionProcessor { +public final class ShortConversionProcessor implements ConversionProcessor { @Override public Function convertByte() { diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index 30015704d..b5f858cc5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -23,7 +23,7 @@ /** * Provides all method for converting any primitive type to a {@link String}. */ -public final class StringConversionProcessor implements ConversionProcessor { +public final class StringConversionProcessor implements ConversionProcessor { /** * {@inheritDoc} From 45a08c5d0df2b9e96a733d0ae181c46263b3157c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Jul 2019 17:26:12 +0200 Subject: [PATCH 0732/1786] Added test in order to cover a missing branch condition --- .../beans/transformer/TransformerTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 75bd3ad2f..6f5999a42 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -48,6 +48,7 @@ import com.hotels.beans.cache.CacheManager; import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; +import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.error.MissingFieldException; import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; @@ -188,6 +189,44 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro getSourceFieldValueMethod.invoke(underTest, null, null, null, false); } + /** + * Test that the method: {@code getSourceFieldValue} throws no Exceptions in case reflectionUtils throws exception and + * a field transformer is defined for the given field. + * @throws Exception if the invoke method fails + */ + @Test + @SuppressWarnings("unchecked") + public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined() throws Exception { + //GIVEN + ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + Field field = mock(Field.class); + Class fieldType = Integer.class; + + when(reflectionUtils.getFieldValue(FromFooSimple.class, AGE_FIELD_NAME, fieldType)).thenThrow(InvalidBeanException.class); + when(field.getType()).thenReturn(fieldType); + + setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); + + Method getSourceFieldValueMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_VALUE_METHOD_NAME, Object.class, String.class, Field.class, boolean.class); + getSourceFieldValueMethod.setAccessible(true); + + //WHEN + Exception raisedException = null; + Object actual = null; + try { + actual = getSourceFieldValueMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME, field, true); + } catch (final Exception e) { + raisedException = e; + } + + //THEN + verify(reflectionUtils).getFieldValue(FromFooSimple.class, AGE_FIELD_NAME, fieldType); + verify(field).getType(); + assertNull(raisedException); + assertNull(actual); + restoreUnderTestObject(); + } + /** * Test that by default the primitive type conversion is disabled. */ From 09190a23895c0dc1e02ee157fc5f661492fcfe04 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Jul 2019 17:59:50 +0200 Subject: [PATCH 0733/1786] Added UT for method: getConstructorArgsValues --- .../beans/transformer/TransformerTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 6f5999a42..f0926d7dc 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -31,13 +31,16 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import static org.springframework.test.util.ReflectionTestUtils.setField; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Parameter; import java.util.List; import java.util.Map; @@ -53,6 +56,7 @@ import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; @@ -71,6 +75,7 @@ public class TransformerTest extends AbstractTransformerTest { private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; private static final String GET_TRANSFORMER_FUNCTION_METHOD_NAME = "getTransformerFunction"; private static final String CONVERSION_ANALYZER_FIELD_NAME = "conversionAnalyzer"; + private static final String GET_CONSTRUCTOR_ARGS_VALUES_METHOD_NAME = "getConstructorArgsValues"; /** * The class to be tested. @@ -443,6 +448,45 @@ AGE_FIELD_NAME, true, false, emptyMap(), null, ZERO.intValue()}, }; } + /** + * Test that the method: {@code getConstructorArgsValues} returns the default type value if the parameter name cannot be retrieved from the constructor. + * @throws Exception if the invoke method fails + */ + @Test + @SuppressWarnings("unchecked") + public void testGetConstructorArgsValuesReturnsTheDefaultTypeIfTheDestinationFieldNameIsNull() throws Exception { + //GIVEN + Constructor constructor = mock(Constructor.class); + ClassUtils classUtils = mock(ClassUtils.class); + Parameter constructorParameter = mock(Parameter.class); + Parameter[] constructorParameters = {constructorParameter}; + + when(classUtils.getConstructorParameters(constructor)).thenReturn(constructorParameters); + when(constructorParameter.isNamePresent()).thenReturn(true); + when(constructorParameter.getName()).thenReturn(null); + when(constructorParameter.getType()).thenReturn((Class) Integer.class); + when(classUtils.getDefaultTypeValue(Integer.class)).thenReturn(ZERO.intValue()); + + setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + + Method getConstructorArgsValuesMethod = underTest.getClass() + .getDeclaredMethod(GET_CONSTRUCTOR_ARGS_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class); + getConstructorArgsValuesMethod.setAccessible(true); + + //WHEN + Object[] actual = (Object[]) getConstructorArgsValuesMethod.invoke(underTest, fromFoo, ImmutableToFoo.class, constructor, ID_FIELD_NAME); + + //THEN + verify(classUtils).getConstructorParameters(constructor); + verify(constructorParameter).isNamePresent(); + verify(constructorParameter, times(2)).getName(); + verify(constructorParameter).getType(); + verify(classUtils).getDefaultTypeValue(Integer.class); + assertEquals(ONE.intValue(), actual.length); + assertEquals(ZERO.intValue(), actual[ZERO.intValue()]); + restoreUnderTestObject(); + } + /** * Restores the underTest object removing all defined mocks. */ From 2c8dfd0e5da663f918bf409f8d399a051f555d25 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Jul 2019 18:11:57 +0200 Subject: [PATCH 0734/1786] Increased minimum test coverage ratio --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 0e07532cd..4d3375dbd 100644 --- a/pom.xml +++ b/pom.xml @@ -46,12 +46,12 @@ 2.2.6 0.8.2 - 0.85 - 0.85 - 0.85 + 1.0 + 0.90 + 0.9 0.85 - 0.85 - 0.85 + 0.88 + 0.90 3.3.3 0.12 From e4755978fbac58b47313ad6c8ae1fc58db5df648 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 06:40:36 +0200 Subject: [PATCH 0735/1786] Added tests for isString --- .../hotels/beans/utils/ClassUtilsTest.java | 29 +++++++++++++++++++ pom.xml | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index dd1afb2c5..39082aa1a 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -815,4 +815,33 @@ private Object[][] dataHasAccessibleConstructorsTesting() { {"Tests that the method returns false if the constructor is private", MutableToFooWithBuilder.class, false} }; } + + /** + * Tests that the method {@code isString} returns the expected value. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataIsStringTesting") + public void testIsStringWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { + // GIVEN + + // WHEN + boolean actual = underTest.isString(testClass); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code isString}. + * @return parameters to be used for testing the the method {@code isString}. + */ + @DataProvider + private Object[][] dataIsStringTesting() { + return new Object[][] { + {"Tests that the method returns true if the class is a String", String.class, true}, + {"Tests that the method returns false if the class is not a String", BigDecimal.class, false} + }; + } } diff --git a/pom.xml b/pom.xml index 4d3375dbd..881a1e490 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ 0.8.2 1.0 0.90 - 0.9 + 1.0 0.85 0.88 0.90 From 3278cf56528e71b327b529ce19677c2519fd81e8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 09:09:35 +0200 Subject: [PATCH 0736/1786] Added conversion analyzer test --- .../analyzer/ConversionAnalyzerTest.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index f8951b9a3..e7100f7b6 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -30,6 +30,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; @@ -117,23 +118,25 @@ public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final private Object[][] dataGetConversionFunctionTesting() { return new Object[][] { {"Tests that the method returns a IntegerConversionProcessor that converts from String to int", - String.class, int.class, new IntegerConversionProcessor().convertString()}, + String.class, int.class, new IntegerConversionProcessor().convertString()}, {"Tests that the method returns a StringConversionProcessor that converts from byte to String", - byte.class, String.class, new StringConversionProcessor().convertByte()}, + byte.class, String.class, new StringConversionProcessor().convertByte()}, {"Tests that the method returns a ShortConversionProcessor that converts from short to byte", - short.class, byte.class, new ByteConversionProcessor().convertShort()}, + short.class, byte.class, new ByteConversionProcessor().convertShort()}, {"Tests that the method returns a StringConversionProcessor that converts from int to String", - int.class, String.class, new StringConversionProcessor().convertInteger()}, + int.class, String.class, new StringConversionProcessor().convertInteger()}, {"Tests that the method returns a IntegerConversionProcessor that converts from long to int", - long.class, int.class, new IntegerConversionProcessor().convertLong()}, + long.class, int.class, new IntegerConversionProcessor().convertLong()}, {"Tests that the method returns a DoubleConversionProcessor that converts from float to double", - float.class, double.class, new DoubleConversionProcessor().convertFloat()}, + float.class, double.class, new DoubleConversionProcessor().convertFloat()}, {"Tests that the method returns a FloatConversionProcessor that converts from double to float", - double.class, float.class, new FloatConversionProcessor().convertDouble()}, + double.class, float.class, new FloatConversionProcessor().convertDouble()}, {"Tests that the method returns a StringConversionProcessor that converts from char to String", - char.class, String.class, new StringConversionProcessor().convertCharacter()}, + char.class, String.class, new StringConversionProcessor().convertCharacter()}, {"Tests that the method returns a CharacterConversionProcessor that converts from char to boolean", - boolean.class, char.class, new CharacterConversionProcessor().convertBoolean()} + boolean.class, char.class, new CharacterConversionProcessor().convertBoolean()}, + {"Tests that the method returns a BooleanConversionProcessor that converts from String to boolean", + String.class, boolean.class, new BooleanConversionProcessor().convertString()} }; } } From b61f963e456f0ab479ba94458401c91dce20116e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 09:36:47 +0200 Subject: [PATCH 0737/1786] Added conversion analyzer test cases --- .../beans/conversion/analyzer/ConversionAnalyzerTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index e7100f7b6..450212f9f 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; import java.util.Optional; import java.util.function.Function; @@ -87,7 +88,9 @@ private Object[][] dataGetConversionFunctionEmptyCaseTesting() { {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type but it's not primitive", Pair.class, int.class}, {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type and the destination type is void", - int.class, Void.class} + int.class, Void.class}, + {"Tests that the method returns an empty optional in case the source field type has no processor defined", + BigDecimal.class, Integer.class} }; } From 6c042f387479c323bc769fb73f4a9de0f582bde6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 10:19:23 +0200 Subject: [PATCH 0738/1786] Updated Changelog with the new feature --- CHANGELOG-JDK8.md | 4 ++++ CHANGELOG.md | 4 ++++ bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- .../beans/utils/ReflectionUtilsTest.java | 18 ++++++++++++++++++ bull-converter/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 8ce33dbfb..a1468cc38 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.1.23] TBD +#### Added +* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). + ### [1.1.22] 2019.07.03 #### Added * Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/HotelsDotCom/bull/issues/73)). diff --git a/CHANGELOG.md b/CHANGELOG.md index d15d272c8..12c36aa23 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.5.0] TBD +#### Added +* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). + ### [1.4.7.1] [1.4.7.2] [1.4.7.3] 2019.07.05 #### Changed * Changed sonatype credential diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 90e266bcf..e0676efd9 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8-SNAPSHOT + 1.5.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f06ebf24b..dea4759a0 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8-SNAPSHOT + 1.5.0-SNAPSHOT diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index b091af2b5..a6c158edd 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -38,6 +38,7 @@ import java.lang.reflect.UndeclaredThrowableException; import java.math.BigInteger; import java.util.List; +import java.util.Optional; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -82,6 +83,7 @@ public class ReflectionUtilsTest { private static final String SET_NAME_METHOD_NAME = "setName"; private static final String SET_INDEX_METHOD_NAME = "setIndex"; private static final String INDEX_NUMBER = "123"; + private static final String GET_REAL_TARGET_METHOD_NAME = "getRealTarget"; /** * The class to be tested. @@ -691,6 +693,22 @@ private Object[][] dataInvokeMethodTesting() { }; } + /** + * Test that the method: {@code getRealTarget} returns the object contained in the Optional. + */ + @Test + public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() throws Exception { + //GIVEN + Method getRealTargetMethod = getMethod(underTest.getClass(), GET_REAL_TARGET_METHOD_NAME, true, Object.class); + Optional optionalBigInteger = Optional.of(ZERO); + + //WHEN + Object actual = getRealTargetMethod.invoke(underTest, optionalBigInteger); + + //THEN + assertEquals(ZERO, actual); + } + /** * Retrieves a method. * @param targetClass the class on which look for the method diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 8992424ce..2fdc20410 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -11,7 +11,7 @@ com.hotels.beans bean-utils-library-parent - 1.4.8-SNAPSHOT + 1.5.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 881a1e490..47aab19e2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.4.8-SNAPSHOT + 1.5.0-SNAPSHOT pom 2019 @@ -45,7 +45,7 @@ 3.0.0 2.2.6 - 0.8.2 + 0.8.3 1.0 0.90 1.0 From e49df6ec35d1b828017a64277a2f4b7e01f5f552 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 10:34:14 +0200 Subject: [PATCH 0739/1786] Fixed broken test --- .../java/com/hotels/beans/transformer/TransformerTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index f0926d7dc..cae7aaa60 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -57,6 +57,7 @@ import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.immutable.ImmutableToFoo; +import com.hotels.beans.sample.mutable.MutableToFooAdvFields; import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; @@ -474,7 +475,7 @@ public void testGetConstructorArgsValuesReturnsTheDefaultTypeIfTheDestinationFie getConstructorArgsValuesMethod.setAccessible(true); //WHEN - Object[] actual = (Object[]) getConstructorArgsValuesMethod.invoke(underTest, fromFoo, ImmutableToFoo.class, constructor, ID_FIELD_NAME); + Object[] actual = (Object[]) getConstructorArgsValuesMethod.invoke(underTest, fromFoo, MutableToFooAdvFields.class, constructor, ID_FIELD_NAME); //THEN verify(classUtils).getConstructorParameters(constructor); From ea321a8a070c882688a6da6a3cdb549d5a60e26b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 10:38:47 +0200 Subject: [PATCH 0740/1786] Fixed broken test --- .../beans/transformer/TransformerTest.java | 1 - bull-transformation-generator/pom.xml | 24 ------------- .../transformer-bytecode-adapter/pom.xml | 30 ---------------- .../config/logging/logback-appenders.xml | 30 ---------------- .../config/logging/logback-properties.xml | 5 --- .../src/test/resources/logback-test.xml | 36 ------------------- .../org.mockito.plugins.MockMaker | 1 - .../transformer-generator-core/pom.xml | 30 ---------------- .../config/logging/logback-appenders.xml | 30 ---------------- .../config/logging/logback-properties.xml | 5 --- .../src/test/resources/logback-test.xml | 36 ------------------- .../org.mockito.plugins.MockMaker | 1 - .../transformer-generator-registry/pom.xml | 30 ---------------- .../config/logging/logback-appenders.xml | 30 ---------------- .../config/logging/logback-properties.xml | 5 --- .../src/test/resources/logback-test.xml | 36 ------------------- .../org.mockito.plugins.MockMaker | 1 - .../transformer-source-adapter/pom.xml | 30 ---------------- .../config/logging/logback-appenders.xml | 30 ---------------- .../config/logging/logback-properties.xml | 5 --- .../src/test/resources/logback-test.xml | 36 ------------------- .../org.mockito.plugins.MockMaker | 1 - pom.xml | 7 ---- 23 files changed, 440 deletions(-) delete mode 100644 bull-transformation-generator/pom.xml delete mode 100644 bull-transformation-generator/transformer-bytecode-adapter/pom.xml delete mode 100644 bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-appenders.xml delete mode 100644 bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-properties.xml delete mode 100644 bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/logback-test.xml delete mode 100644 bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 bull-transformation-generator/transformer-generator-core/pom.xml delete mode 100644 bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-appenders.xml delete mode 100644 bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-properties.xml delete mode 100644 bull-transformation-generator/transformer-generator-core/src/test/resources/logback-test.xml delete mode 100644 bull-transformation-generator/transformer-generator-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 bull-transformation-generator/transformer-generator-registry/pom.xml delete mode 100644 bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-appenders.xml delete mode 100644 bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-properties.xml delete mode 100644 bull-transformation-generator/transformer-generator-registry/src/test/resources/logback-test.xml delete mode 100644 bull-transformation-generator/transformer-generator-registry/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 bull-transformation-generator/transformer-source-adapter/pom.xml delete mode 100644 bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-appenders.xml delete mode 100644 bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-properties.xml delete mode 100644 bull-transformation-generator/transformer-source-adapter/src/test/resources/logback-test.xml delete mode 100644 bull-transformation-generator/transformer-source-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index cae7aaa60..3bca0654a 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -56,7 +56,6 @@ import com.hotels.beans.model.FieldMapping; import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooAdvFields; import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; diff --git a/bull-transformation-generator/pom.xml b/bull-transformation-generator/pom.xml deleted file mode 100644 index 693fddc7c..000000000 --- a/bull-transformation-generator/pom.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - 4.0.0 - BULL - Transformer Generator - bull-transformer-generator-parent - pom - 2019 - TODO: description - - - com.hotels.beans - bean-utils-library-parent - 1.4.8-SNAPSHOT - - - - transformer-bytecode-adapter - transformer-source-adapter - transformer-generator-registry - transformer-generator-core - - - - diff --git a/bull-transformation-generator/transformer-bytecode-adapter/pom.xml b/bull-transformation-generator/transformer-bytecode-adapter/pom.xml deleted file mode 100644 index 6008b5d1b..000000000 --- a/bull-transformation-generator/transformer-bytecode-adapter/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - 4.0.0 - BULL - Transformer Bytecode Adapter - transformer-bytecode-adapter - jar - Transformer Bytecode Adapter - - - com.hotels.beans - bull-transformer-generator-parent - 1.4.8-SNAPSHOT - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - test-jar - - - - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-appenders.xml b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-appenders.xml deleted file mode 100644 index 3bfd17005..000000000 --- a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-appenders.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - ${LOG_PATTERN} - - - - - - ${ROOT_LOG_DIR}/bean-utils-library.log - true - - UTF-8 - ${LOG_PATTERN} - - - ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip - - 30 - - 5MB - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-properties.xml b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-properties.xml deleted file mode 100644 index 934b4e88b..000000000 --- a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/config/logging/logback-properties.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/logback-test.xml b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/logback-test.xml deleted file mode 100644 index 4da7aad36..000000000 --- a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/logback-test.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea..000000000 --- a/bull-transformation-generator/transformer-bytecode-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-core/pom.xml b/bull-transformation-generator/transformer-generator-core/pom.xml deleted file mode 100644 index b6dda23a5..000000000 --- a/bull-transformation-generator/transformer-generator-core/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - 4.0.0 - BULL - Transformer Generator Core - transformer-generator-core - jar - Contains the core functions required for the transformer generation - - - com.hotels.beans - bull-transformer-generator-parent - 1.4.8-SNAPSHOT - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - test-jar - - - - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-appenders.xml b/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-appenders.xml deleted file mode 100644 index 3bfd17005..000000000 --- a/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-appenders.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - ${LOG_PATTERN} - - - - - - ${ROOT_LOG_DIR}/bean-utils-library.log - true - - UTF-8 - ${LOG_PATTERN} - - - ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip - - 30 - - 5MB - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-properties.xml b/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-properties.xml deleted file mode 100644 index 934b4e88b..000000000 --- a/bull-transformation-generator/transformer-generator-core/src/test/resources/config/logging/logback-properties.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/bull-transformation-generator/transformer-generator-core/src/test/resources/logback-test.xml b/bull-transformation-generator/transformer-generator-core/src/test/resources/logback-test.xml deleted file mode 100644 index 4da7aad36..000000000 --- a/bull-transformation-generator/transformer-generator-core/src/test/resources/logback-test.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-transformation-generator/transformer-generator-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea..000000000 --- a/bull-transformation-generator/transformer-generator-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-registry/pom.xml b/bull-transformation-generator/transformer-generator-registry/pom.xml deleted file mode 100644 index 4ab86e7a2..000000000 --- a/bull-transformation-generator/transformer-generator-registry/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - 4.0.0 - BULL - Transformer Generator Registry - transformer-generator-registry - jar - Transformer Generator Registry - - - com.hotels.beans - bull-transformer-generator-parent - 1.4.8-SNAPSHOT - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - test-jar - - - - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-appenders.xml b/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-appenders.xml deleted file mode 100644 index 3bfd17005..000000000 --- a/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-appenders.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - ${LOG_PATTERN} - - - - - - ${ROOT_LOG_DIR}/bean-utils-library.log - true - - UTF-8 - ${LOG_PATTERN} - - - ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip - - 30 - - 5MB - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-properties.xml b/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-properties.xml deleted file mode 100644 index 934b4e88b..000000000 --- a/bull-transformation-generator/transformer-generator-registry/src/test/resources/config/logging/logback-properties.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/bull-transformation-generator/transformer-generator-registry/src/test/resources/logback-test.xml b/bull-transformation-generator/transformer-generator-registry/src/test/resources/logback-test.xml deleted file mode 100644 index 4da7aad36..000000000 --- a/bull-transformation-generator/transformer-generator-registry/src/test/resources/logback-test.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-generator-registry/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-transformation-generator/transformer-generator-registry/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea..000000000 --- a/bull-transformation-generator/transformer-generator-registry/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/bull-transformation-generator/transformer-source-adapter/pom.xml b/bull-transformation-generator/transformer-source-adapter/pom.xml deleted file mode 100644 index d8c7a0bcf..000000000 --- a/bull-transformation-generator/transformer-source-adapter/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - 4.0.0 - BULL - Transformer Source Adapter - transformer-source-adapter - jar - Transformer Source Adapter - - - com.hotels.beans - bull-transformer-generator-parent - 1.4.8-SNAPSHOT - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - test-jar - - - - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-appenders.xml b/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-appenders.xml deleted file mode 100644 index 3bfd17005..000000000 --- a/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-appenders.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - ${LOG_PATTERN} - - - - - - ${ROOT_LOG_DIR}/bean-utils-library.log - true - - UTF-8 - ${LOG_PATTERN} - - - ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip - - 30 - - 5MB - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-properties.xml b/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-properties.xml deleted file mode 100644 index 934b4e88b..000000000 --- a/bull-transformation-generator/transformer-source-adapter/src/test/resources/config/logging/logback-properties.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/bull-transformation-generator/transformer-source-adapter/src/test/resources/logback-test.xml b/bull-transformation-generator/transformer-source-adapter/src/test/resources/logback-test.xml deleted file mode 100644 index 4da7aad36..000000000 --- a/bull-transformation-generator/transformer-source-adapter/src/test/resources/logback-test.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/bull-transformation-generator/transformer-source-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-transformation-generator/transformer-source-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea..000000000 --- a/bull-transformation-generator/transformer-source-adapter/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/pom.xml b/pom.xml index d6c2ff42e..47aab19e2 100644 --- a/pom.xml +++ b/pom.xml @@ -294,13 +294,6 @@
      - - - transformer-generator - - bull-transformation-generator - -
      From b669fc9df6acc37b584b82c27b1731fb8cabe1c9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 10:56:25 +0200 Subject: [PATCH 0741/1786] Typo fix --- .../com/hotels/beans/transformer/AbstractTransformer.java | 2 +- .../com/hotels/beans/transformer/TransformerImpl.java | 4 ++-- .../com/hotels/beans/transformer/TransformerSettings.java | 2 +- .../com/hotels/beans/transformer/TransformerTest.java | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 327648b7e..ef058027b 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -142,7 +142,7 @@ public final void resetFieldsTransformer() { */ @Override public final Transformer setDefaultValueForMissingField(final boolean useDefaultValue) { - settings.setSetDefaultValueForMissingFields(useDefaultValue); + settings.setSetDefaultValueForMissingField(useDefaultValue); return this; } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 1dd98f0df..a33bd4e68 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -376,7 +376,7 @@ private Object getSourceFieldValue(final T sourceObj, final String sourceFie // in case the source field is a primitive type and the destination one is composite, the source field value is returned without going in deep if (classUtils.isPrimitiveType(sourceObj.getClass())) { fieldValue = sourceObj; - } else if (!isFieldTransformerDefined && !settings.isSetDefaultValueForMissingFields()) { + } else if (!isFieldTransformerDefined && !settings.isSetDefaultValueForMissingField()) { throw e; } } catch (Exception e) { @@ -405,7 +405,7 @@ private Class getSourceFieldType(final Class sourceObjectClass, final Stri // the source field type is returned without going in deep if (classUtils.isPrimitiveType(sourceObjectClass)) { classType = sourceObjectClass; - } else if (!settings.isSetDefaultValueForMissingFields()) { + } else if (!settings.isSetDefaultValueForMissingField()) { throw e; } } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 03c79e233..f3047f947 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -60,7 +60,7 @@ final class TransformerSettings { * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. */ @Setter - private boolean setDefaultValueForMissingFields; + private boolean setDefaultValueForMissingField; /** * It allows to apply a transformation to all fields matching with the provided name without using their whole path. diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 3bca0654a..855e7ad3a 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -313,7 +313,7 @@ public void testGetSourceFieldTypeReturnsNull() throws Exception { when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(empty()); when(reflectionUtils.getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class)).thenThrow(MissingFieldException.class); when(classUtils.isPrimitiveType(Integer.class)).thenReturn(true); - when(settings.isSetDefaultValueForMissingFields()).thenReturn(true); + when(settings.isSetDefaultValueForMissingField()).thenReturn(true); setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); @@ -330,7 +330,7 @@ public void testGetSourceFieldTypeReturnsNull() throws Exception { verify(cacheManager).getFromCache(anyString(), any(Class.class)); verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); verify(classUtils).isPrimitiveType(FromFooSimple.class); - verify(settings).isSetDefaultValueForMissingFields(); + verify(settings).isSetDefaultValueForMissingField(); assertNull(actual); restoreUnderTestObject(); } @@ -351,7 +351,7 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(empty()); when(reflectionUtils.getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class)).thenThrow(MissingFieldException.class); when(classUtils.isPrimitiveType(Integer.class)).thenReturn(false); - when(settings.isSetDefaultValueForMissingFields()).thenReturn(false); + when(settings.isSetDefaultValueForMissingField()).thenReturn(false); setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); @@ -373,7 +373,7 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception verify(cacheManager).getFromCache(anyString(), any(Class.class)); verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); verify(classUtils).isPrimitiveType(FromFooSimple.class); - verify(settings).isSetDefaultValueForMissingFields(); + verify(settings).isSetDefaultValueForMissingField(); assertNotNull(raisedException); assertEquals(MissingFieldException.class, raisedException.getCause().getClass()); restoreUnderTestObject(); From 0f87d43fffe500ed8ac67d970c01d9a68cff53db Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 11:15:21 +0200 Subject: [PATCH 0742/1786] Modified logic in order to initialize conversion and validator only if needed --- .../transformer/AbstractTransformer.java | 12 ++-- .../beans/transformer/TransformerTest.java | 60 +++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index ef058027b..f8db339e8 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -60,12 +60,12 @@ abstract class AbstractTransformer implements Transformer { /** * Bean Validator. It offers the possibility to validate a given Java Bean against a set of defined constraints. */ - final Validator validator; + Validator validator; /** * Conversion analyzer. It allows to automatically convert common field types. */ - final ConversionAnalyzer conversionAnalyzer; + ConversionAnalyzer conversionAnalyzer; /** * Default constructor. @@ -73,9 +73,7 @@ abstract class AbstractTransformer implements Transformer { AbstractTransformer() { this.reflectionUtils = new ReflectionUtils(); this.classUtils = new ClassUtils(); - this.validator = new ValidatorImpl(); this.settings = new TransformerSettings(); - this.conversionAnalyzer = new ConversionAnalyzer(); this.cacheManager = getCacheManager("transformer"); } @@ -161,6 +159,9 @@ public final Transformer setFlatFieldNameTransformation(final boolean useFlatTra @Override public Transformer setValidationEnabled(final boolean validationEnabled) { settings.setValidationEnabled(validationEnabled); + if (validationEnabled) { + validator = new ValidatorImpl(); + } return this; } @@ -179,6 +180,9 @@ public Transformer setDefaultValueSetEnabled(final boolean defaultValueSetEnable @Override public Transformer setDefaultPrimitiveTypeConversionEnabled(final boolean defaultPrimitiveTypeConversionEnabled) { settings.setDefaultPrimitiveTypeConversionEnabled(defaultPrimitiveTypeConversionEnabled); + if (defaultPrimitiveTypeConversionEnabled) { + conversionAnalyzer = new ConversionAnalyzer(); + } return this; } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 855e7ad3a..e0ca74041 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -493,4 +493,64 @@ public void testGetConstructorArgsValuesReturnsTheDefaultTypeIfTheDestinationFie private void restoreUnderTestObject() { underTest = new TransformerImpl(); } + + /** + * Tests that an instance fo {@link com.hotels.beans.validator.Validator} is created only if the validation is enabled. + * @param testCaseDescription the test case description + * @param validationEnabled true if the validation is enabled, false otherwise + * @param expectedNull the expected result + */ + @Test(dataProvider = "dataValidationInitializationTesting") + public void testValidatorIsInitializedOnlyIfValidationIsEnabled(final String testCaseDescription, final boolean validationEnabled, final boolean expectedNull) { + // GIVEN + + // WHEN + underTest.setValidationEnabled(validationEnabled); + + // THEN + assertEquals(expectedNull, underTest.validator == null); + underTest.setValidationEnabled(false); + } + + /** + * Creates the parameters to be used for testing the method {@code setValidationEnabled}. + * @return parameters to be used for testing the the method {@code setValidationEnabled}. + */ + @DataProvider + private Object[][] dataValidationInitializationTesting() { + return new Object[][] { + {"Tests that the Validator object is not created if the validation is disabled", false, true}, + {"Tests that the Validator object is created if the validation is enabled", true, false} + }; + } + + /** + * Tests that an instance fo {@link ConversionAnalyzer} is created only if the automatic conversion is enabled. + * @param testCaseDescription the test case description + * @param autoConversionEnabled true if the automatic conversion is enabled, false otherwise + * @param expectedNull the expected result + */ + @Test(dataProvider = "dataConversionAnalyzerInitializationTesting") + public void testConversionAnalyzerIsInitializedOnlyIfValidationIsEnabled(final String testCaseDescription, final boolean autoConversionEnabled, final boolean expectedNull) { + // GIVEN + + // WHEN + underTest.setDefaultPrimitiveTypeConversionEnabled(autoConversionEnabled); + + // THEN + assertEquals(expectedNull, underTest.conversionAnalyzer == null); + underTest.setDefaultPrimitiveTypeConversionEnabled(false); + } + + /** + * Creates the parameters to be used for testing the method {@code setValidationEnabled}. + * @return parameters to be used for testing the the method {@code setValidationEnabled}. + */ + @DataProvider + private Object[][] dataConversionAnalyzerInitializationTesting() { + return new Object[][] { + {"Tests that the ConversionAnalyzer object is not created if the automatic conversion is disabled", false, true}, + {"Tests that the ConversionAnalyzer object is created if the automatic conversion is enabled", true, false} + }; + } } From 1892325bc8833c8d25c191364985bdaa6fd94e54 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 11:23:42 +0200 Subject: [PATCH 0743/1786] Updated changelog --- CHANGELOG-JDK8.md | 3 +++ CHANGELOG.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index a1468cc38..c777c5582 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file. ### [1.1.23] TBD #### Added * Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). +#### Changed +* Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled +* Modified Transformer initialization in order to create a `ConversionAnalyzed` instance only if the automatic conversion is enabled ### [1.1.22] 2019.07.03 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 12c36aa23..4f9ac6d63 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file. ### [1.5.0] TBD #### Added * Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). +#### Changed +* Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled +* Modified Transformer initialization in order to create a `ConversionAnalyzed` instance only if the automatic conversion is enabled ### [1.4.7.1] [1.4.7.2] [1.4.7.3] 2019.07.05 #### Changed From 7e19b2182209b88dd37a6ba5c00e4d3119dc8c37 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 16:32:21 +0200 Subject: [PATCH 0744/1786] Added changes as per PR --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index a33bd4e68..f97076677 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -435,8 +435,10 @@ private List getTransformerFunction(final Class sourceObjec .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(fieldTransformerKey, conversionFunction))); } } - ofNullable(settings.getFieldsTransformers().get(fieldTransformerKey)) - .ifPresent(fieldTransformers::add); + FieldTransformer fieldTransformer = settings.getFieldsTransformers().get(fieldTransformerKey); + if (nonNull(fieldTransformer)) { + fieldTransformers.add(fieldTransformer); + } return fieldTransformers; } From b338cbbb70a43e851346350e3179ebe657f160e7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 16 Jul 2019 17:16:53 +0200 Subject: [PATCH 0745/1786] Removed useless test --- .../hotels/beans/transformer/TransformerTest.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index e0ca74041..cee8a36a8 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -232,20 +232,6 @@ public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined restoreUnderTestObject(); } - /** - * Test that by default the primitive type conversion is disabled. - */ - @Test - public void testThatDefaultPrimitiveTypeConversionIsDisabledByDefault() { - //GIVEN - - //WHEN - boolean actual = underTest.settings.isDefaultPrimitiveTypeConversionEnabled(); - - //THEN - assertFalse(actual); - } - /** * Test that the primitive type conversion is correctly enabled. */ From aff09b216abd0fb68e0ad64ca55e8da82b2f1000 Mon Sep 17 00:00:00 2001 From: Felipe Zanardo Affonso Date: Tue, 16 Jul 2019 18:53:08 -0300 Subject: [PATCH 0746/1786] Add InfoQ Brazil article translation --- docs/site/markdown/index.md | 3 ++- docs/site/site.xml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 027e2a0ef..79f8b4923 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -45,5 +45,6 @@ This BeanUtils library is a utility library for managing Bean objects. The libra - #### Related articles * DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) - * InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) + * InfoQ : [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) + * InfoQ Brazil: [Como a Expedia Está Se Livrando dos Transformadores de Java Beans](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/) diff --git a/docs/site/site.xml b/docs/site/site.xml index ca83d967a..2a9470a6f 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -41,6 +41,7 @@ + From 7100d2574320ee08a84c6096972e49fde04c2484 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 17 Jul 2019 10:57:52 +0200 Subject: [PATCH 0747/1786] Added site icon for all browser types and applications --- .../images/icon/android-chrome-192x192.png | Bin 0 -> 12787 bytes .../images/icon/android-chrome-512x512.png | Bin 0 -> 38460 bytes .../images/icon/apple-touch-icon.png | Bin 0 -> 3564 bytes .../resources/images/icon/browserconfig.xml | 9 +++ .../resources/images/icon/favicon-16x16.png | Bin 0 -> 857 bytes .../resources/images/icon/favicon-32x32.png | Bin 0 -> 1372 bytes docs/site/resources/images/icon/favicon.ico | Bin 0 -> 15086 bytes .../resources/images/icon/mstile-150x150.png | Bin 0 -> 3531 bytes .../images/icon/safari-pinned-tab.svg | 74 ++++++++++++++++++ .../resources/images/icon/site.webmanifest | 19 +++++ docs/site/site.xml | 13 ++- 11 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 docs/site/resources/images/icon/android-chrome-192x192.png create mode 100644 docs/site/resources/images/icon/android-chrome-512x512.png create mode 100644 docs/site/resources/images/icon/apple-touch-icon.png create mode 100644 docs/site/resources/images/icon/browserconfig.xml create mode 100644 docs/site/resources/images/icon/favicon-16x16.png create mode 100644 docs/site/resources/images/icon/favicon-32x32.png create mode 100644 docs/site/resources/images/icon/favicon.ico create mode 100644 docs/site/resources/images/icon/mstile-150x150.png create mode 100644 docs/site/resources/images/icon/safari-pinned-tab.svg create mode 100644 docs/site/resources/images/icon/site.webmanifest diff --git a/docs/site/resources/images/icon/android-chrome-192x192.png b/docs/site/resources/images/icon/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..988f02a7e6eb795898f2c13b277d902c35e254c5 GIT binary patch literal 12787 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 T@i&}|D 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 literal 0 HcmV?d00001 diff --git a/docs/site/resources/images/icon/browserconfig.xml b/docs/site/resources/images/icon/browserconfig.xml new file mode 100644 index 000000000..d416bc536 --- /dev/null +++ b/docs/site/resources/images/icon/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #ffffff + + + diff --git a/docs/site/resources/images/icon/favicon-16x16.png b/docs/site/resources/images/icon/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..7f2ce324ceb3905f5e425c9062eb3f505e761be7 GIT binary patch literal 857 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>Sp3 z|7=yM8$dt%l?3?#!%vEp-Ia~eI!2aTX>Je;v+d#2OAO?4o}P*pp8mTn?CXnp#%h;e zc{9y;Z1VQ`e#h^B?uYtD-rC{$?NMQuI!K51-T40`+u6|0fkn2x;TbNT=wmID%O-B;363)DEvl@dAD^y z$eSDA>t#L$PyC(#Zl>{WneU7RA0Ff!cv-}4#$4gDo`2gLewL#Gb)1uA`dpGXxY$fo z@ml&go;hWcrP0a%+N`ZBBDA7=ySzfyUafaOV1A}&o0+CS4dGQG5hX#19-8f8yaN z4Aam!<$wB&=hGktW@T=@WNu+)VeiQz%)$yT4JL!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+081LL*;pAc7|f{R-Eqi6_) z!2kdMg&gLt2gcllk|4ie1_oA1VH=Z>QeQ@e9h%Yt%-tK=xf6K9U&p29dp$iQ6mUX| zE&kcZ+!u8!Q@=bv`)eJO!!3VKuHq@H|NeP(pxK4*u$%l6`+qOz?!Qu@!!hlHT=ZAP zOYhA(u6h_AIWEOA;nbVO5}s=JA8zg{_-X4TzWZC6!Q~@oc>21sKV}!?GSuwdC(N5G|LpTU+xzF|8kf5*&ldT@_TrmxRMdZF8H*kI3^GS}pvvy%_a3HnoVeMtt-fe<%Fp-0af-jwJbSbJNE;nJCVjPLHOWn=ka&iJJ2 zdqeeib{`#<|Evq|)k!METPlK|h)M*Dk2tle@hZ7=@}Ot`Q|Ei6yC4$wjF^iowXh z&{EgHT-VS%#L&RX#L~*dP}{)B%D`Z6%f(I<4Y~O#nQ4`{HJrJbX$sU3UKJ8i5|mi3 zP*9YgmYI{PP*Pcts*qVwlFYzRG3W6o9*)8=4UJR&r_Xpk4Pszc=GIH*7FHJao-D#F ztl-jMayW%qd2@)u=^Iy09657D<_P=g29E_^dJM0`1xr3TnN9^-!QkoY=d#Wzp$P!| CVj|=K literal 0 HcmV?d00001 diff --git a/docs/site/resources/images/icon/favicon.ico b/docs/site/resources/images/icon/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c2eaf899fe95f5fae09e15c8770a2ecce8b8db47 GIT binary patch literal 15086 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 literal 0 HcmV?d00001 diff --git a/docs/site/resources/images/icon/mstile-150x150.png b/docs/site/resources/images/icon/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..85a9fea5b6233f6c77ffb9cd16413e14fec5af2d GIT binary patch literal 3531 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 K9n#gC5&r@)XGhrp literal 0 HcmV?d00001 diff --git a/docs/site/resources/images/icon/safari-pinned-tab.svg b/docs/site/resources/images/icon/safari-pinned-tab.svg new file mode 100644 index 000000000..36c185840 --- /dev/null +++ b/docs/site/resources/images/icon/safari-pinned-tab.svg @@ -0,0 +1,74 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + diff --git a/docs/site/resources/images/icon/site.webmanifest b/docs/site/resources/images/icon/site.webmanifest new file mode 100644 index 000000000..7a218ff4a --- /dev/null +++ b/docs/site/resources/images/icon/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "BULL", + "short_name": "BULL", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/docs/site/site.xml b/docs/site/site.xml index ca83d967a..d4185c2d5 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -19,9 +19,20 @@ + + + + + + + + + ]]> + - +

      From 188ff9622b7b9db0932f3bf07bdd33b7ec7f84b5 Mon Sep 17 00:00:00 2001 From: Felipe Zanardo Affonso Date: Wed, 17 Jul 2019 07:28:44 -0300 Subject: [PATCH 0748/1786] Adjust the links acording to review comments --- docs/site/markdown/index.md | 3 +-- docs/site/site.xml | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 79f8b4923..8a30e2868 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -45,6 +45,5 @@ This BeanUtils library is a utility library for managing Bean objects. The libra - #### Related articles * DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) - * InfoQ : [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) - * InfoQ Brazil: [Como a Expedia Está Se Livrando dos Transformadores de Java Beans](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/) + * InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] diff --git a/docs/site/site.xml b/docs/site/site.xml index 2a9470a6f..5cfc10a41 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -40,8 +40,10 @@ - - + + + + From 524fab43f2ebbd0e36dfaa976e8298320d104a57 Mon Sep 17 00:00:00 2001 From: Felipe Zanardo Affonso Date: Wed, 17 Jul 2019 07:44:20 -0300 Subject: [PATCH 0749/1786] Change PT link to PT-BR at Home --- docs/site/markdown/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 8a30e2868..7320354eb 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -45,5 +45,5 @@ This BeanUtils library is a utility library for managing Bean objects. The libra - #### Related articles * DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) - * InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] + * InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[PT-BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] From 9dee433d14c7d151c09bd478f60360f0bf7789c3 Mon Sep 17 00:00:00 2001 From: Felipe Zanardo Affonso Date: Wed, 17 Jul 2019 08:57:22 -0300 Subject: [PATCH 0750/1786] Correct Portuguese Link at Menu --- docs/site/site.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/site/site.xml b/docs/site/site.xml index a545e8057..57f08f003 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -53,7 +53,7 @@ - + From fd5bf423bd3149af6de4f4bb8021774a313901a5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 17 Jul 2019 14:10:10 +0200 Subject: [PATCH 0751/1786] Added changes on main readme too --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a0001d08d..169f72300 100644 --- a/README.md +++ b/README.md @@ -685,7 +685,7 @@ The application's logo has been designed by: Rob Light. ## Related articles - DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) - - InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) + - InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[PT-BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] ## Legal From 1ab11a6a703f5d63a449e05d2513fb92b3fe533c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 17 Jul 2019 14:22:58 +0200 Subject: [PATCH 0752/1786] minor: site improvements --- docs/site/markdown/articles.md | 9 +++++++++ docs/site/resources/{images/icon => }/browserconfig.xml | 2 +- docs/site/resources/{images/icon => }/site.webmanifest | 4 ++-- docs/site/site.xml | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 docs/site/markdown/articles.md rename docs/site/resources/{images/icon => }/browserconfig.xml (72%) rename docs/site/resources/{images/icon => }/site.webmanifest (73%) diff --git a/docs/site/markdown/articles.md b/docs/site/markdown/articles.md new file mode 100644 index 000000000..2555734b1 --- /dev/null +++ b/docs/site/markdown/articles.md @@ -0,0 +1,9 @@ + + Articles + + +# Articles + +* DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) + +* InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[PT-BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] \ No newline at end of file diff --git a/docs/site/resources/images/icon/browserconfig.xml b/docs/site/resources/browserconfig.xml similarity index 72% rename from docs/site/resources/images/icon/browserconfig.xml rename to docs/site/resources/browserconfig.xml index d416bc536..1e8d9ebe4 100644 --- a/docs/site/resources/images/icon/browserconfig.xml +++ b/docs/site/resources/browserconfig.xml @@ -2,7 +2,7 @@ - + #ffffff diff --git a/docs/site/resources/images/icon/site.webmanifest b/docs/site/resources/site.webmanifest similarity index 73% rename from docs/site/resources/images/icon/site.webmanifest rename to docs/site/resources/site.webmanifest index 7a218ff4a..d440630e3 100644 --- a/docs/site/resources/images/icon/site.webmanifest +++ b/docs/site/resources/site.webmanifest @@ -3,12 +3,12 @@ "short_name": "BULL", "icons": [ { - "src": "/android-chrome-192x192.png", + "src": "images/icon/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { - "src": "/android-chrome-512x512.png", + "src": "images/icon/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } diff --git a/docs/site/site.xml b/docs/site/site.xml index 57f08f003..b8ee1f563 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -51,7 +51,7 @@ - + From 80a7e293825422e62b71094de9b87b8550b3857f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 19 Jul 2019 09:43:04 +0200 Subject: [PATCH 0753/1786] Minor improvement on transformer function condition --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index f97076677..545fbeb31 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -428,14 +428,14 @@ private List getTransformerFunction(final Class sourceObjec final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { List fieldTransformers = new ArrayList<>(); String fieldTransformerKey = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && !settings.getFieldsTransformers().containsKey(fieldTransformerKey)) { + FieldTransformer fieldTransformer = settings.getFieldsTransformers().get(fieldTransformerKey); + if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && isNull(fieldTransformer)) { Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); if (nonNull(sourceFieldType)) { conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(fieldTransformerKey, conversionFunction))); } } - FieldTransformer fieldTransformer = settings.getFieldsTransformers().get(fieldTransformerKey); if (nonNull(fieldTransformer)) { fieldTransformers.add(fieldTransformer); } From db29fef97e07de8aae189d3a8abe90a52b179b7c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 19 Jul 2019 11:10:19 +0200 Subject: [PATCH 0754/1786] Transformer test initialization improvement --- .../transformer/AbstractTransformerTest.java | 18 ++++++++++++++++++ .../BuilderObjectTransformationTest.java | 17 ----------------- .../ImmutableObjectTransformationTest.java | 17 ----------------- .../MixedObjectTransformationTest.java | 16 ---------------- .../MutableObjectTransformationTest.java | 17 ----------------- .../beans/transformer/TransformerTest.java | 17 ----------------- 6 files changed, 18 insertions(+), 84 deletions(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index 2b6188248..dce9ccb91 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -19,6 +19,8 @@ import static java.util.Arrays.asList; import static java.util.Collections.singletonList; +import static org.mockito.MockitoAnnotations.initMocks; + import static com.hotels.beans.constant.ClassType.IMMUTABLE; import java.math.BigDecimal; @@ -29,7 +31,9 @@ import java.util.Map; import java.util.Optional; +import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooAdvFields; @@ -85,6 +89,12 @@ public abstract class AbstractTransformerTest { private static List sourceFooSimpleList; private static FromSubFoo fromSubFoo; + /** + * The class to be tested. + */ + @InjectMocks + TransformerImpl underTest; + /** * Initializes the arguments and objects. */ @@ -93,6 +103,14 @@ public void beforeClass() { initObjects(); } + /** + * Initialized mocks. + */ + @BeforeMethod + public void beforeMethod() { + initMocks(this); + } + /** * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. */ diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 1e46089df..4bfbf9e80 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -17,12 +17,9 @@ package com.hotels.beans.transformer; import static org.junit.Assert.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; -import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -35,20 +32,6 @@ * Unit test for all {@link Transformer} functions related to Object based on Builder Pattern. */ public class BuilderObjectTransformationTest extends AbstractTransformerTest { - /** - * The class to be tested. - */ - @InjectMocks - private TransformerImpl underTest; - - /** - * Initialized mocks. - */ - @BeforeMethod - public void beforeMethod() { - initMocks(this); - } - /** * Test mutable,immutable,mixed beans are correctly copied through builder. * @param testDescription the test case description diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 060b923db..0402c34e6 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -27,7 +27,6 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; import static org.springframework.test.util.ReflectionTestUtils.setField; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; @@ -39,9 +38,7 @@ import java.util.Optional; import java.util.stream.IntStream; -import org.mockito.InjectMocks; import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -82,20 +79,6 @@ public class ImmutableObjectTransformationTest extends AbstractTransformerTest { private static final String GROSS_PRICE_FIELD_NAME = "price.grossPrice"; private static final boolean ACTIVE = true; - /** - * The class to be tested. - */ - @InjectMocks - private TransformerImpl underTest; - - /** - * Initialized mocks. - */ - @BeforeMethod - public void beforeMethod() { - initMocks(this); - } - @AfterMethod public void afterMethod() { underTest.setValidationEnabled(false); diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index fbb193b5d..53f193eee 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -21,15 +21,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import java.math.BigInteger; import java.util.stream.IntStream; -import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.hotels.beans.error.MissingFieldException; @@ -47,19 +44,6 @@ */ public class MixedObjectTransformationTest extends AbstractTransformerTest { private static final boolean ACTIVE = true; - /** - * The class to be tested. - */ - @InjectMocks - private TransformerImpl underTest; - - /** - * Initialized mocks. - */ - @BeforeMethod - public void beforeMethod() { - initMocks(this); - } /** * Test that a Mixed bean with a constructor containing the final field only is correctly copied. diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 99604c2fc..28831cb28 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -23,12 +23,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; -import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -52,20 +49,6 @@ public class MutableObjectTransformationTest extends AbstractTransformerTest { private static final boolean ACTIVE = true; - /** - * The class to be tested. - */ - @InjectMocks - private TransformerImpl underTest; - - /** - * Initialized mocks. - */ - @BeforeMethod - public void beforeMethod() { - initMocks(this); - } - /** * Test that an exception is thrown if there is no default constructor defined for the mutable bean object. */ diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index cee8a36a8..c6866de6d 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -34,7 +34,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; import static org.springframework.test.util.ReflectionTestUtils.setField; import java.lang.reflect.Constructor; @@ -44,8 +43,6 @@ import java.util.List; import java.util.Map; -import org.mockito.InjectMocks; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -77,20 +74,6 @@ public class TransformerTest extends AbstractTransformerTest { private static final String CONVERSION_ANALYZER_FIELD_NAME = "conversionAnalyzer"; private static final String GET_CONSTRUCTOR_ARGS_VALUES_METHOD_NAME = "getConstructorArgsValues"; - /** - * The class to be tested. - */ - @InjectMocks - private TransformerImpl underTest; - - /** - * Initialized mocks. - */ - @BeforeMethod - public void beforeMethod() { - initMocks(this); - } - /** * Test that is possible to remove a field mapping for a given field. */ From 56abe6e88e5e913e00efeea15b28535daf292b63 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 19 Jul 2019 16:58:57 +0200 Subject: [PATCH 0755/1786] Cached default type transformer function --- .../transformer/AbstractTransformer.java | 14 +++- .../beans/transformer/TransformerImpl.java | 66 ++++++++++++++----- .../beans/transformer/TransformerTest.java | 31 ++++----- .../com/hotels/beans/cache/CacheManager.java | 8 +++ .../hotels/beans/cache/CacheManagerTest.java | 18 +++++ 5 files changed, 105 insertions(+), 32 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index f8db339e8..ec650349d 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -18,8 +18,8 @@ import static java.util.Arrays.asList; -import static com.hotels.beans.validator.Validator.notNull; import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.beans.validator.Validator.notNull; import java.util.Map; @@ -37,6 +37,16 @@ * Contains all method implementation that will be common to any {@link Transformer} implementation. */ abstract class AbstractTransformer implements Transformer { + /** + * The cache key prefix for the Transformer Functions. + */ + static final String TRANSFORMER_FUNCTION_CACHE_PREFIX = "TransformerFunction"; + + /** + * A regex that returns all the transformer function cached items. + */ + private static final String TRANSFORMER_FUNCTION_REGEX = "^" + TRANSFORMER_FUNCTION_CACHE_PREFIX + ".*"; + /** * Reflection utils instance {@link ReflectionUtils}. */ @@ -125,6 +135,7 @@ public final Transformer withFieldTransformer(final FieldTransformer... fieldTra public final void removeFieldTransformer(final String destFieldName) { notNull(destFieldName, "The field name for which the transformer function has to be removed cannot be null!"); settings.getFieldsTransformers().remove(destFieldName); + cacheManager.removeMatchingKeys(TRANSFORMER_FUNCTION_REGEX + destFieldName); } /** @@ -133,6 +144,7 @@ public final void removeFieldTransformer(final String destFieldName) { @Override public final void resetFieldsTransformer() { settings.getFieldsTransformers().clear(); + cacheManager.removeMatchingKeys(TRANSFORMER_FUNCTION_REGEX); } /** diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 545fbeb31..df6b0fe1a 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -26,13 +26,13 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static com.hotels.beans.constant.Punctuation.DOT; +import static com.hotels.beans.base.Defaults.defaultValue; +import static com.hotels.beans.constant.ClassType.MIXED; +import static com.hotels.beans.constant.ClassType.MUTABLE; import static com.hotels.beans.constant.Punctuation.COMMA; +import static com.hotels.beans.constant.Punctuation.DOT; import static com.hotels.beans.constant.Punctuation.LPAREN; import static com.hotels.beans.constant.Punctuation.RPAREN; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.base.Defaults.defaultValue; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; @@ -313,7 +313,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN return defaultValue(fieldType); } boolean primitiveType = classUtils.isPrimitiveType(fieldType); - List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, field, primitiveType, fieldBreadcrumb); + List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, targetClass, field, primitiveType, fieldBreadcrumb); boolean isTransformerFunctionDefined = !transformerFunction.isEmpty(); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { @@ -419,29 +419,63 @@ private Class getSourceFieldType(final Class sourceObjectClass, final Stri * a conversion function is automatically added. * @param sourceObjectClass the source object class * @param sourceFieldName the source field name - * @param field The field on which the transformation should be applied. + * @param targetClass the destination object class + * @param field the field on which the transformation should be applied * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not - * @param breadcrumb The full field path on which the transformation should be applied. + * @param breadcrumb The full field path on which the transformation should be applied + * @param the target object type * @return the transformer function. */ - private List getTransformerFunction(final Class sourceObjectClass, final String sourceFieldName, final Field field, - final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { + private List getTransformerFunction(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, + final Field field, final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { List fieldTransformers = new ArrayList<>(); String fieldTransformerKey = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; FieldTransformer fieldTransformer = settings.getFieldsTransformers().get(fieldTransformerKey); - if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && isNull(fieldTransformer)) { - Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); - if (nonNull(sourceFieldType)) { - conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) - .ifPresent(conversionFunction -> fieldTransformers.add(new FieldTransformer<>(fieldTransformerKey, conversionFunction))); - } + boolean hasFieldTransformerDefined = nonNull(fieldTransformer); + FieldTransformer defaultPrimitiveTypeTransformer = getDefaultPrimitiveTypeTransformer(sourceObjectClass, sourceFieldName, targetClass, field, + isDestinationFieldPrimitiveType, fieldTransformerKey, hasFieldTransformerDefined); + if (nonNull(defaultPrimitiveTypeTransformer)) { + fieldTransformers.add(defaultPrimitiveTypeTransformer); } - if (nonNull(fieldTransformer)) { + if (hasFieldTransformerDefined) { fieldTransformers.add(fieldTransformer); } return fieldTransformers; } + /** + * Verifies if a default type transformer function is required and in case returns it. + * @param sourceObjectClass the source object class + * @param sourceFieldName the source field name + * @param targetClass the destination object class + * @param field the field on which the transformation should be applied. + * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not + * @param fieldTransformerKey the field name or the full path to the field to which assign the transformer + * @param hasFieldTransformerDefined indicates if there is a transformer defined + * @param the target object type + * @return the default type transformer function + */ + private FieldTransformer getDefaultPrimitiveTypeTransformer(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, + final Field field, final boolean isDestinationFieldPrimitiveType, final String fieldTransformerKey, final boolean hasFieldTransformerDefined) { + String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + targetClass + + "-" + fieldTransformerKey + "-" + hasFieldTransformerDefined + + "-" + settings.isDefaultPrimitiveTypeConversionEnabled() + "-" + field.getName(); + return cacheManager.getFromCache(cacheKey, FieldTransformer.class) + .orElseGet(() -> { + FieldTransformer defaultPrimitiveTypeTransformer = null; + if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && !hasFieldTransformerDefined) { + Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); + if (nonNull(sourceFieldType)) { + defaultPrimitiveTypeTransformer = conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) + .map(conversionFunction -> new FieldTransformer<>(fieldTransformerKey, conversionFunction)) + .orElse(null); + } + } + cacheManager.cacheObject(cacheKey, defaultPrimitiveTypeTransformer); + return defaultPrimitiveTypeTransformer; + }); + } + /** * Retrieves the value of a field. * @param targetClass the destination object class diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index c6866de6d..5ac0664f5 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -21,7 +21,6 @@ import static java.util.Collections.emptyMap; import static java.util.Optional.empty; import static java.util.Optional.of; -import static java.util.Optional.ofNullable; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -54,6 +53,7 @@ import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.mutable.MutableToFooAdvFields; +import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; @@ -371,11 +371,12 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip ConversionAnalyzer conversionAnalyzer = mock(ConversionAnalyzer.class); ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); - when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(ofNullable(sourceFieldType)); + when(cacheManager.getFromCache(anyString(), any())).thenReturn(empty()); when(settings.isFlatFieldNameTransformation()).thenReturn(false); when(settings.isDefaultPrimitiveTypeConversionEnabled()).thenReturn(isDefaultPrimitiveTypeConversionEnabled); when(settings.getFieldsTransformers()).thenReturn(fieldTransformers); when(conversionAnalyzer.getConversionFunction(any(Class.class), any(Class.class))).thenReturn(of(Object::toString)); + when(field.getName()).thenReturn(fieldName); when(field.getType()).thenReturn(sourceFieldType); when(reflectionUtils.getDeclaredFieldType(fieldName, FromFooSimple.class)).thenReturn(sourceFieldType); @@ -385,12 +386,12 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); Method getTransformerFunctionMethod = underTest.getClass() - .getDeclaredMethod(GET_TRANSFORMER_FUNCTION_METHOD_NAME, Class.class, String.class, Field.class, boolean.class, String.class); + .getDeclaredMethod(GET_TRANSFORMER_FUNCTION_METHOD_NAME, Class.class, String.class, Class.class, Field.class, boolean.class, String.class); getTransformerFunctionMethod.setAccessible(true); //WHEN - List actual = - (List) getTransformerFunctionMethod.invoke(underTest, FromFooSimple.class, fieldName, field, isDestinationFieldPrimitiveType, fieldName); + List actual = (List) + getTransformerFunctionMethod.invoke(underTest, FromFooSimple.class, fieldName, MutableToFooSimple.class, field, isDestinationFieldPrimitiveType, fieldName); //THEN assertEquals(expectedFieldTransformerSize, actual.size()); @@ -404,16 +405,16 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip @DataProvider private Object[][] dataGetTransformerFunctionTesting() { return new Object[][] { - {"Test that a type conversion function is added to the existing one if all the conditions are met", - AGE_FIELD_NAME, true, true, emptyMap(), int.class, ONE.intValue()}, - {"Test that no type conversion function is added to the existing one if the source type field is null", - AGE_FIELD_NAME, true, true, emptyMap(), null, ZERO.intValue()}, - {"Test that no conversion function is added to the existing one if the primitive type conversion is disabled", - AGE_FIELD_NAME, false, true, emptyMap(), null, ZERO.intValue()}, - {"Test that no conversion function is added to the existing one if the destination field type is not primitive", - AGE_FIELD_NAME, true, false, emptyMap(), null, ZERO.intValue()}, - {"Test that no conversion function is added to the existing one if there is a field transformer function defined for the existing field", - AGE_FIELD_NAME, true, true, Map.of(AGE_FIELD_NAME, new FieldTransformer<>(AGE_FIELD_NAME, () -> null)), null, ONE.intValue()} + {"Test that a type conversion function is added to the existing one if all the conditions are met", + AGE_FIELD_NAME, true, true, emptyMap(), int.class, ONE.intValue()}, + {"Test that no type conversion function is added to the existing one if the source type field is null", + AGE_FIELD_NAME, true, true, emptyMap(), null, ZERO.intValue()}, + {"Test that no conversion function is added to the existing one if the primitive type conversion is disabled", + AGE_FIELD_NAME, false, true, emptyMap(), null, ZERO.intValue()}, + {"Test that no conversion function is added to the existing one if the destination field type is not primitive", + AGE_FIELD_NAME, true, false, emptyMap(), null, ZERO.intValue()}, + {"Test that no conversion function is added to the existing one if there is a field transformer function defined for the existing field", + AGE_FIELD_NAME, true, true, Map.of(AGE_FIELD_NAME, new FieldTransformer<>(AGE_FIELD_NAME, () -> null)), null, ONE.intValue()} }; } diff --git a/bull-common/src/main/java/com/hotels/beans/cache/CacheManager.java b/bull-common/src/main/java/com/hotels/beans/cache/CacheManager.java index e17e53529..5f3667704 100644 --- a/bull-common/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/bull-common/src/main/java/com/hotels/beans/cache/CacheManager.java @@ -79,4 +79,12 @@ public Optional getFromCache(final String cacheKey, final Class key.matches(regex)); + } } diff --git a/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java index d2797df26..e3c0b147d 100644 --- a/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java @@ -35,6 +35,8 @@ public class CacheManagerTest { private static final String DEFAULT_VALUE = "defaultValue"; private static final String CACHE_KEY = "cacheKey"; private static final Class CACHED_OBJECT_CLASS = String.class; + private static final String STARTS_WITH_REGEX = "^ca.*"; + /** * The class to be tested. */ @@ -97,4 +99,20 @@ public void testRemoveFromCacheRemovesTheObject() { // THEN assertFalse(actual.isPresent()); } + + /** + * Tests that the method {@code removeMatchingKeys} really removes the object with the matching key from the cache. + */ + @Test + public void testRemoveMatchingKeysFromCacheRemovesTheObject() { + // GIVEN + underTest.cacheObject(CACHE_KEY, VALUE); + + // WHEN + underTest.removeMatchingKeys(STARTS_WITH_REGEX); + Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); + + // THEN + assertFalse(actual.isPresent()); + } } From 39689b77156f6cf043d3448e3bcb116793ea505c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 19 Jul 2019 17:55:11 +0200 Subject: [PATCH 0756/1786] minor field renaming --- .../hotels/beans/transformer/TransformerImpl.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index df6b0fe1a..b3d8260f0 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -431,13 +431,13 @@ private List getTransformerFunction(final Class sourceO List fieldTransformers = new ArrayList<>(); String fieldTransformerKey = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; FieldTransformer fieldTransformer = settings.getFieldsTransformers().get(fieldTransformerKey); - boolean hasFieldTransformerDefined = nonNull(fieldTransformer); + boolean isFieldTransformerDefined = nonNull(fieldTransformer); FieldTransformer defaultPrimitiveTypeTransformer = getDefaultPrimitiveTypeTransformer(sourceObjectClass, sourceFieldName, targetClass, field, - isDestinationFieldPrimitiveType, fieldTransformerKey, hasFieldTransformerDefined); + isDestinationFieldPrimitiveType, fieldTransformerKey, isFieldTransformerDefined); if (nonNull(defaultPrimitiveTypeTransformer)) { fieldTransformers.add(defaultPrimitiveTypeTransformer); } - if (hasFieldTransformerDefined) { + if (isFieldTransformerDefined) { fieldTransformers.add(fieldTransformer); } return fieldTransformers; @@ -451,19 +451,19 @@ private List getTransformerFunction(final Class sourceO * @param field the field on which the transformation should be applied. * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @param fieldTransformerKey the field name or the full path to the field to which assign the transformer - * @param hasFieldTransformerDefined indicates if there is a transformer defined + * @param isFieldTransformerDefined indicates if there is a transformer defined * @param the target object type * @return the default type transformer function */ private FieldTransformer getDefaultPrimitiveTypeTransformer(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, - final Field field, final boolean isDestinationFieldPrimitiveType, final String fieldTransformerKey, final boolean hasFieldTransformerDefined) { + final Field field, final boolean isDestinationFieldPrimitiveType, final String fieldTransformerKey, final boolean isFieldTransformerDefined) { String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + targetClass - + "-" + fieldTransformerKey + "-" + hasFieldTransformerDefined + + "-" + fieldTransformerKey + "-" + isFieldTransformerDefined + "-" + settings.isDefaultPrimitiveTypeConversionEnabled() + "-" + field.getName(); return cacheManager.getFromCache(cacheKey, FieldTransformer.class) .orElseGet(() -> { FieldTransformer defaultPrimitiveTypeTransformer = null; - if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && !hasFieldTransformerDefined) { + if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && !isFieldTransformerDefined) { Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); if (nonNull(sourceFieldType)) { defaultPrimitiveTypeTransformer = conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) From f6173aa5fef44e1269af9835752dd3816ed28caf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 22 Jul 2019 11:10:45 +0200 Subject: [PATCH 0757/1786] Renamed primitive type transformation function --- README.md | 2 +- .../beans/transformer/AbstractTransformer.java | 6 +++--- .../hotels/beans/transformer/Transformer.java | 4 ++-- .../beans/transformer/TransformerImpl.java | 12 ++++++------ .../beans/transformer/TransformerSettings.java | 2 +- .../MutableObjectTransformationTest.java | 12 ++++++------ .../beans/transformer/TransformerTest.java | 18 +++++++++--------- docs/site/markdown/transformer/samples.md | 2 +- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 31273bb3f..cc0af2dc6 100644 --- a/README.md +++ b/README.md @@ -554,7 +554,7 @@ functionality described above. ~~~Java Transformer transformer = beanUtils.getTransformer() - .setDefaultPrimitiveTypeConversionEnabled(true); + .setPrimitiveTypeConversionEnabled(true); ToBean toBean = transformer.transform(fromBean, ToBean.class); ~~~ diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index ec650349d..0a8bd37fe 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -190,9 +190,9 @@ public Transformer setDefaultValueSetEnabled(final boolean defaultValueSetEnable * {@inheritDoc} */ @Override - public Transformer setDefaultPrimitiveTypeConversionEnabled(final boolean defaultPrimitiveTypeConversionEnabled) { - settings.setDefaultPrimitiveTypeConversionEnabled(defaultPrimitiveTypeConversionEnabled); - if (defaultPrimitiveTypeConversionEnabled) { + public Transformer setPrimitiveTypeConversionEnabled(final boolean primitiveTypeConversionEnabled) { + settings.setPrimitiveTypeConversionEnabled(primitiveTypeConversionEnabled); + if (primitiveTypeConversionEnabled) { conversionAnalyzer = new ConversionAnalyzer(); } return this; diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java index 8e1632288..3983d9c6e 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -127,8 +127,8 @@ public interface Transformer { /** * It allows to enable/disable the automatic conversion of primitive types. - * @param defaultPrimitiveTypeConversionEnabled if true primitive types are transformed automatically. By default it's false. + * @param primitiveTypeConversionEnabled if true primitive types are transformed automatically. By default it's false. * @return the {@link Transformer} instance */ - Transformer setDefaultPrimitiveTypeConversionEnabled(boolean defaultPrimitiveTypeConversionEnabled); + Transformer setPrimitiveTypeConversionEnabled(boolean primitiveTypeConversionEnabled); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index b3d8260f0..7fa28be6f 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -432,10 +432,10 @@ private List getTransformerFunction(final Class sourceO String fieldTransformerKey = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; FieldTransformer fieldTransformer = settings.getFieldsTransformers().get(fieldTransformerKey); boolean isFieldTransformerDefined = nonNull(fieldTransformer); - FieldTransformer defaultPrimitiveTypeTransformer = getDefaultPrimitiveTypeTransformer(sourceObjectClass, sourceFieldName, targetClass, field, + FieldTransformer primitiveTypeTransformer = getPrimitiveTypeTransformer(sourceObjectClass, sourceFieldName, targetClass, field, isDestinationFieldPrimitiveType, fieldTransformerKey, isFieldTransformerDefined); - if (nonNull(defaultPrimitiveTypeTransformer)) { - fieldTransformers.add(defaultPrimitiveTypeTransformer); + if (nonNull(primitiveTypeTransformer)) { + fieldTransformers.add(primitiveTypeTransformer); } if (isFieldTransformerDefined) { fieldTransformers.add(fieldTransformer); @@ -455,15 +455,15 @@ private List getTransformerFunction(final Class sourceO * @param the target object type * @return the default type transformer function */ - private FieldTransformer getDefaultPrimitiveTypeTransformer(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, + private FieldTransformer getPrimitiveTypeTransformer(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, final Field field, final boolean isDestinationFieldPrimitiveType, final String fieldTransformerKey, final boolean isFieldTransformerDefined) { String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + targetClass + "-" + fieldTransformerKey + "-" + isFieldTransformerDefined - + "-" + settings.isDefaultPrimitiveTypeConversionEnabled() + "-" + field.getName(); + + "-" + settings.isPrimitiveTypeConversionEnabled() + "-" + field.getName(); return cacheManager.getFromCache(cacheKey, FieldTransformer.class) .orElseGet(() -> { FieldTransformer defaultPrimitiveTypeTransformer = null; - if (settings.isDefaultPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && !isFieldTransformerDefined) { + if (settings.isPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && !isFieldTransformerDefined) { Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); if (nonNull(sourceFieldType)) { defaultPrimitiveTypeTransformer = conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index f3047f947..902131bb3 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -88,5 +88,5 @@ final class TransformerSettings { * If set to true primitive types are transformed automatically. */ @Setter - private boolean defaultPrimitiveTypeConversionEnabled; + private boolean primitiveTypeConversionEnabled; } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 28831cb28..ed150d951 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -223,7 +223,7 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeConversionIsEnabled() { //GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); - underTest.setDefaultPrimitiveTypeConversionEnabled(true); + underTest.setPrimitiveTypeConversionEnabled(true); //WHEN Exception raisedException = null; @@ -235,7 +235,7 @@ public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeCo //THEN assertEquals(MissingFieldException.class, raisedException.getCause().getClass()); - underTest.setDefaultPrimitiveTypeConversionEnabled(false); + underTest.setPrimitiveTypeConversionEnabled(false); } /** @@ -246,7 +246,7 @@ public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeCo public void testTransformerDoesNotThrowExceptionIfAFieldIsMissingAndTheDefaultValueSetIsEnabled() { //GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); - underTest.setDefaultPrimitiveTypeConversionEnabled(true).setDefaultValueForMissingField(true); + underTest.setPrimitiveTypeConversionEnabled(true).setDefaultValueForMissingField(true); //WHEN MutableToFooNotExistingFields actual = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); @@ -254,7 +254,7 @@ public void testTransformerDoesNotThrowExceptionIfAFieldIsMissingAndTheDefaultVa //THEN assertEquals(actual.getId(), fromFooSimple.getId()); assertEquals(actual.getName(), fromFooSimple.getName()); - underTest.setDefaultPrimitiveTypeConversionEnabled(false).setDefaultValueForMissingField(false); + underTest.setPrimitiveTypeConversionEnabled(false).setDefaultValueForMissingField(false); } /** @@ -317,7 +317,7 @@ public void testFieldTransformationSkipWorksProperly() { public void testAutomaticPrimitiveTypeTransformationWorksProperly() { //GIVEN double delta = 0d; - underTest.setDefaultPrimitiveTypeConversionEnabled(true); + underTest.setPrimitiveTypeConversionEnabled(true); //WHEN MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); @@ -327,6 +327,6 @@ public void testAutomaticPrimitiveTypeTransformationWorksProperly() { assertEquals(String.valueOf(fromFooPrimitiveTypes.getId()), actual.getId()); assertEquals(Float.valueOf(fromFooPrimitiveTypes.getPrice()).doubleValue(), actual.getPrice(), delta); assertEquals(ACTIVE, actual.isActive()); - underTest.setDefaultPrimitiveTypeConversionEnabled(false); + underTest.setPrimitiveTypeConversionEnabled(false); } } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 5ac0664f5..5bd24b6c6 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -219,16 +219,16 @@ public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined * Test that the primitive type conversion is correctly enabled. */ @Test - public void testThatDefaultPrimitiveTypeConversionIsCorrectlyEnabled() { + public void testThatPrimitiveTypeConversionIsCorrectlyEnabled() { //GIVEN - underTest.setDefaultPrimitiveTypeConversionEnabled(true); + underTest.setPrimitiveTypeConversionEnabled(true); //WHEN - boolean actual = underTest.settings.isDefaultPrimitiveTypeConversionEnabled(); + boolean actual = underTest.settings.isPrimitiveTypeConversionEnabled(); //THEN assertTrue(actual); - underTest.setDefaultPrimitiveTypeConversionEnabled(false); + underTest.setPrimitiveTypeConversionEnabled(false); } /** @@ -352,7 +352,7 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception * Test that the {@code getTransformerFunction} works as expected. * @param testCaseDescription the test case description * @param fieldName the field name to which the transformer function has to be applied - * @param isDefaultPrimitiveTypeConversionEnabled indicates if the automatic conversion function is enabled + * @param isPrimitiveTypeConversionEnabled indicates if the automatic conversion function is enabled * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @param fieldTransformers the field transformer associated to the given field * @param sourceFieldType the source field type @@ -361,7 +361,7 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception */ @Test(dataProvider = "dataGetTransformerFunctionTesting") @SuppressWarnings("unchecked") - public void testGetTransformerFunctionWorksProperly(final String testCaseDescription, final String fieldName, final boolean isDefaultPrimitiveTypeConversionEnabled, + public void testGetTransformerFunctionWorksProperly(final String testCaseDescription, final String fieldName, final boolean isPrimitiveTypeConversionEnabled, final boolean isDestinationFieldPrimitiveType, final Map fieldTransformers, final Class sourceFieldType, final int expectedFieldTransformerSize) throws Exception { //GIVEN @@ -373,7 +373,7 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip when(cacheManager.getFromCache(anyString(), any())).thenReturn(empty()); when(settings.isFlatFieldNameTransformation()).thenReturn(false); - when(settings.isDefaultPrimitiveTypeConversionEnabled()).thenReturn(isDefaultPrimitiveTypeConversionEnabled); + when(settings.isPrimitiveTypeConversionEnabled()).thenReturn(isPrimitiveTypeConversionEnabled); when(settings.getFieldsTransformers()).thenReturn(fieldTransformers); when(conversionAnalyzer.getConversionFunction(any(Class.class), any(Class.class))).thenReturn(of(Object::toString)); when(field.getName()).thenReturn(fieldName); @@ -505,11 +505,11 @@ public void testConversionAnalyzerIsInitializedOnlyIfValidationIsEnabled(final S // GIVEN // WHEN - underTest.setDefaultPrimitiveTypeConversionEnabled(autoConversionEnabled); + underTest.setPrimitiveTypeConversionEnabled(autoConversionEnabled); // THEN assertEquals(expectedNull, underTest.conversionAnalyzer == null); - underTest.setDefaultPrimitiveTypeConversionEnabled(false); + underTest.setPrimitiveTypeConversionEnabled(false); } /** diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 31c348ef5..61f3bb29c 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -475,7 +475,7 @@ functionality described above. ~~~Java Transformer transformer = beanUtils.getTransformer() - .setDefaultPrimitiveTypeConversionEnabled(true); + .setPrimitiveTypeConversionEnabled(true); ToBean toBean = transformer.transform(fromBean, ToBean.class); ~~~ From 2471870693d62e6058bc2d9a021c9bf52f817c3c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 22 Jul 2019 16:12:05 +0200 Subject: [PATCH 0758/1786] Started implementation of conversion for BigInteger and BigDecimal --- .../analyzer/ConversionAnalyzer.java | 6 ++ .../processor/ConversionProcessor.java | 14 +++ .../processor/ConversionProcessorFactory.java | 8 ++ .../impl/BigDecimalConversionProcessor.java | 4 + .../impl/BigIntegerConversionProcessor.java | 102 ++++++++++++++++++ 5 files changed, 134 insertions(+) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 75081e3e6..4ef4fa7e9 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -31,6 +31,8 @@ import static com.hotels.beans.utils.ClassUtils.isShort; import static com.hotels.beans.utils.ClassUtils.isString; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.Optional; import java.util.function.Function; @@ -106,6 +108,10 @@ public Optional> getConversionFunction(final Class s conversionFunction = of(conversionProcessor.convertCharacter()); } else if (isBoolean(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertBoolean()); + } else if (sourceFieldType == BigInteger.class) { + conversionFunction = of(conversionProcessor.convertBigInteger()); + } else if (sourceFieldType == BigDecimal.class) { + conversionFunction = of(conversionProcessor.convertBigDecimal()); } return conversionFunction; } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index 774fca463..9274d4717 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -16,6 +16,8 @@ package com.hotels.beans.conversion.processor; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; /** @@ -76,4 +78,16 @@ public interface ConversionProcessor { * @return the converted value */ Function convertString(); + + /** + * Converts an {@link BigInteger} type. + * @return the converted value + */ + Function convertBigInteger(); + + /** + * Converts an {@link BigDecimal} type. + * @return the converted value + */ + Function convertBigDecimal(); } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index 25c24730c..3b9a299fd 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -31,8 +31,12 @@ import static lombok.AccessLevel.PRIVATE; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.Optional; +import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; +import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; @@ -75,6 +79,10 @@ public static Optional getConversionProcessor(final Class { + + @Override + public Function convertByte() { + return Byte::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return Short::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return Long::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return Float::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return Double::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return Character::getNumericValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> valueOf(val ? 1 : 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return Integer::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return null; + } +} From af22b11deceead7becc12573babaa9d9462afc2f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 23 Jul 2019 16:29:29 +0200 Subject: [PATCH 0759/1786] - Added conversion for BigDecimal and BigInteger too - Implemented test for: ByteConversionProcessor and BooleanConversionProcessor --- README.md | 2 + .../com/hotels/beans/utils/ClassUtils.java | 2 +- .../processor/ConversionProcessor.java | 2 +- .../impl/BigDecimalConversionProcessor.java | 117 +++++++++++++++++- .../impl/BigIntegerConversionProcessor.java | 51 +++++--- .../impl/BooleanConversionProcessor.java | 21 ++++ .../impl/ByteConversionProcessor.java | 19 ++- .../impl/CharacterConversionProcessor.java | 19 ++- .../impl/DoubleConversionProcessor.java | 18 +++ .../impl/FloatConversionProcessor.java | 12 ++ .../impl/IntegerConversionProcessor.java | 22 +++- .../impl/LongConversionProcessor.java | 19 ++- .../impl/ShortConversionProcessor.java | 22 +++- .../impl/StringConversionProcessor.java | 19 ++- .../analyzer/ConversionAnalyzerTest.java | 13 +- .../impl/BooleanConversionProcessorTest.java | 61 +++++++++ .../impl/ByteConversionProcessorTest.java | 27 ++++ docs/site/markdown/index.md | 2 + 18 files changed, 418 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index cc0af2dc6..f183010a5 100644 --- a/README.md +++ b/README.md @@ -708,6 +708,8 @@ The supported types, in which an object can be converted (from / to), are: * `Long` or `long` * `Float` or `float` * `Double` or `double` +* `BigDecimal` +* `BigInteger` * `Character` or `char` * `Boolean` or `boolean` * `String` diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java index d6f82a755..22580850e 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -243,7 +243,7 @@ public static boolean isBoolean(final Class type) { * @return true if is String */ public static boolean isString(final Class type) { - return String.class.isAssignableFrom(type); + return type == String.class; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index 9274d4717..b00551e24 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -22,7 +22,7 @@ /** * Conversion methods for all primitive types. - * @param indicates any primitve type object + * @param indicates any primitive type object */ public interface ConversionProcessor { /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java index 5ac59b922..7a158583a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java @@ -1,4 +1,119 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hotels.beans.conversion.processor.impl; -public class BigDecimalConversionProcessor { +import static java.lang.Character.getNumericValue; +import static java.math.BigDecimal.valueOf; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a {@link BigDecimal}. + */ +public final class BigDecimalConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertByte() { + return val -> valueOf(val.doubleValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return BigDecimal::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return BigDecimal::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return BigDecimal::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return BigDecimal::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return BigDecimal::valueOf; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> valueOf(getNumericValue(val)); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> valueOf(val ? (double) 1 : (double) 0); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return BigDecimal::new; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return val -> valueOf(val.intValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return val -> val; + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java index a0a3acd17..9926acbb7 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java @@ -1,6 +1,23 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hotels.beans.conversion.processor.impl; -import static java.lang.Integer.valueOf; +import static java.lang.Character.getNumericValue; +import static java.math.BigInteger.valueOf; import java.math.BigDecimal; import java.math.BigInteger; @@ -8,16 +25,16 @@ import com.hotels.beans.conversion.processor.ConversionProcessor; -import lombok.val; - /** * Provides all method for converting any primitive type to a {@link BigInteger}. */ -public class BigIntegerConversionProcessor implements ConversionProcessor { - +public final class BigIntegerConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ @Override public Function convertByte() { - return Byte::intValue; + return val -> valueOf(val.longValue()); } /** @@ -25,7 +42,7 @@ public Function convertByte() { */ @Override public Function convertShort() { - return Short::intValue; + return BigInteger::valueOf; } /** @@ -33,7 +50,7 @@ public Function convertShort() { */ @Override public Function convertInteger() { - return val -> val; + return BigInteger::valueOf; } /** @@ -41,7 +58,7 @@ public Function convertInteger() { */ @Override public Function convertLong() { - return Long::intValue; + return BigInteger::valueOf; } /** @@ -49,7 +66,7 @@ public Function convertLong() { */ @Override public Function convertFloat() { - return Float::intValue; + return val -> valueOf(val.intValue()); } /** @@ -57,7 +74,7 @@ public Function convertFloat() { */ @Override public Function convertDouble() { - return Double::intValue; + return val -> valueOf(val.intValue()); } /** @@ -65,7 +82,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return Character::getNumericValue; + return val -> valueOf(getNumericValue(val)); } /** @@ -81,22 +98,22 @@ public Function convertBoolean() { */ @Override public Function convertString() { - return Integer::valueOf; + return BigInteger::new; } /** * {@inheritDoc} */ @Override - public Function convertBigInteger() { - return null; + public Function convertBigInteger() { + return val -> val; } /** * {@inheritDoc} */ @Override - public Function convertBigDecimal() { - return null; + public Function convertBigDecimal() { + return BigDecimal::toBigInteger; } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java index 8ee15ceb8..6f689e6af 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -16,6 +16,8 @@ package com.hotels.beans.conversion.processor.impl; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -24,6 +26,9 @@ * Provides all method for converting any primitive type to a {@link Boolean}. */ public final class BooleanConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ @Override public Function convertByte() { return val -> val != 0; @@ -92,4 +97,20 @@ public Function convertBoolean() { public Function convertString() { return Boolean::valueOf; } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return val -> val.intValue() != 0; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return val -> val.intValue() != 0; + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index 1de45aca2..69449c8ab 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -18,6 +18,8 @@ import static java.lang.Byte.valueOf; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -26,7 +28,6 @@ * Provides all method for converting any primitive type to a {@link Byte}. */ public final class ByteConversionProcessor implements ConversionProcessor { - /** * {@inheritDoc} */ @@ -98,4 +99,20 @@ public Function convertBoolean() { public Function convertString() { return Byte::valueOf; } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return Number::byteValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return Number::byteValue; + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java index e3726d889..d4e0de5a0 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -16,6 +16,8 @@ package com.hotels.beans.conversion.processor.impl; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -24,7 +26,6 @@ * Provides all method for converting any primitive type to a {@link Character}. */ public final class CharacterConversionProcessor implements ConversionProcessor { - /** * {@inheritDoc} */ @@ -96,4 +97,20 @@ public Function convertBoolean() { public Function convertString() { return val -> val.charAt(0); } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return val -> (char) val.intValue(); + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return val -> (char) val.doubleValue(); + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index c809aff07..4b663d56e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -19,6 +19,8 @@ import static java.lang.Character.getNumericValue; import static java.lang.Double.valueOf; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -98,4 +100,20 @@ public Function convertBoolean() { public Function convertString() { return Double::valueOf; } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return BigInteger::doubleValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return BigDecimal::doubleValue; + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index f5477e6ed..9418d0b72 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -19,6 +19,8 @@ import static java.lang.Character.getNumericValue; import static java.lang.Float.valueOf; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -98,4 +100,14 @@ public Function convertBoolean() { public Function convertString() { return Float::valueOf; } + + @Override + public Function convertBigInteger() { + return BigInteger::floatValue; + } + + @Override + public Function convertBigDecimal() { + return BigDecimal::floatValue; + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index cbadfa6b5..017c85ad0 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -18,6 +18,8 @@ import static java.lang.Integer.valueOf; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -26,7 +28,9 @@ * Provides all method for converting any primitive type to a {@link Integer}. */ public final class IntegerConversionProcessor implements ConversionProcessor { - + /** + * {@inheritDoc} + */ @Override public Function convertByte() { return Byte::intValue; @@ -95,4 +99,20 @@ public Function convertBoolean() { public Function convertString() { return Integer::valueOf; } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return BigInteger::intValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return BigDecimal::intValue; + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index 89633c158..013b174dc 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -19,6 +19,8 @@ import static java.lang.Character.getNumericValue; import static java.lang.Long.valueOf; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -27,7 +29,6 @@ * Provides all method for converting any primitive type to a {@link Long}. */ public final class LongConversionProcessor implements ConversionProcessor { - /** * {@inheritDoc} */ @@ -99,4 +100,20 @@ public Function convertBoolean() { public Function convertString() { return Long::valueOf; } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return BigInteger::longValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return BigDecimal::longValue; + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index 47f8c453e..a7e549cbc 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -19,6 +19,8 @@ import static java.lang.Character.getNumericValue; import static java.lang.Short.valueOf; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -27,7 +29,9 @@ * Provides all method for converting any primitive type to a {@link Short}. */ public final class ShortConversionProcessor implements ConversionProcessor { - + /** + * {@inheritDoc} + */ @Override public Function convertByte() { return Byte::shortValue; @@ -96,4 +100,20 @@ public Function convertBoolean() { public Function convertString() { return Short::valueOf; } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return Number::shortValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return Number::shortValue; + } } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index b5f858cc5..bb6cc276b 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -16,6 +16,8 @@ package com.hotels.beans.conversion.processor.impl; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.function.Function; import com.hotels.beans.conversion.processor.ConversionProcessor; @@ -24,7 +26,6 @@ * Provides all method for converting any primitive type to a {@link String}. */ public final class StringConversionProcessor implements ConversionProcessor { - /** * {@inheritDoc} */ @@ -96,4 +97,20 @@ public Function convertBoolean() { public Function convertString() { return val -> val; } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return BigInteger::toString; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return BigDecimal::toPlainString; + } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index 450212f9f..1f16884df 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -22,6 +22,7 @@ import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; +import java.math.BigInteger; import java.util.Optional; import java.util.function.Function; @@ -31,6 +32,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; +import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; @@ -88,9 +91,7 @@ private Object[][] dataGetConversionFunctionEmptyCaseTesting() { {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type but it's not primitive", Pair.class, int.class}, {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type and the destination type is void", - int.class, Void.class}, - {"Tests that the method returns an empty optional in case the source field type has no processor defined", - BigDecimal.class, Integer.class} + int.class, Void.class} }; } @@ -139,7 +140,11 @@ char.class, String.class, new StringConversionProcessor().convertCharacter()}, {"Tests that the method returns a CharacterConversionProcessor that converts from char to boolean", boolean.class, char.class, new CharacterConversionProcessor().convertBoolean()}, {"Tests that the method returns a BooleanConversionProcessor that converts from String to boolean", - String.class, boolean.class, new BooleanConversionProcessor().convertString()} + String.class, boolean.class, new BooleanConversionProcessor().convertString()}, + {"Tests that the method returns a BigIntegerConversionProcessor that converts from String to BigInteger", + String.class, BigInteger.class, new BigIntegerConversionProcessor().convertString()}, + {"Tests that the method returns a BigDecimalConversionProcessor that converts from String to BigDecimal", + String.class, BigDecimal.class, new BigDecimalConversionProcessor().convertString()}, }; } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java index 552bd0dec..6df39f506 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java @@ -21,6 +21,9 @@ import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -250,4 +253,62 @@ public void testConvertStringShouldReturnProperResult() { // THEN assertTrue(actual); } + + /** + * Tests that the method {@code convertBigInteger} returns the expected boolean. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "bigIntegerToBooleanConvertValueTesting") + public void testConvertBigIntegerShouldReturnProperResult(final String testCaseDescription, final BigInteger valueToConvert, final boolean expectedResult) { + // GIVEN + + // WHEN + boolean actual = underTest.convertBigInteger().apply(valueToConvert); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertFloat} returns the expected result. + * @return parameters to be used for testing that the method {@code convertFloat} returns the expected result. + */ + @DataProvider + private Object[][] bigIntegerToBooleanConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns true if the value is not 0", BigInteger.ONE, true}, + {"Tests that the method returns false if the value is 0", BigInteger.ZERO, false} + }; + } + + /** + * Tests that the method {@code convertBigDecimal} returns the expected boolean. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "bigDecimalToBooleanConvertValueTesting") + public void testConvertBigIntegerShouldReturnProperResult(final String testCaseDescription, final BigDecimal valueToConvert, final boolean expectedResult) { + // GIVEN + + // WHEN + boolean actual = underTest.convertBigDecimal().apply(valueToConvert); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertFloat} returns the expected result. + * @return parameters to be used for testing that the method {@code convertFloat} returns the expected result. + */ + @DataProvider + private Object[][] bigDecimalToBooleanConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns true if the value is not 0", BigDecimal.ONE, true}, + {"Tests that the method returns false if the value is 0", BigDecimal.ZERO, false} + }; + } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java index d31a08d2d..a86e5de0c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java @@ -21,6 +21,9 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -162,4 +165,28 @@ public void testConvertStringShouldReturnProperResult() { // THEN assertEquals(valueOf(STRING_VALUE), actual); } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + byte expectedValue = BigInteger.ZERO.byteValue(); + + // WHEN + Byte actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(expectedValue, actual.byteValue()); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + byte expectedValue = BigDecimal.ZERO.byteValue(); + + // WHEN + Byte actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual.byteValue()); + } } diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index ec873e2c3..bb918edde 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -55,6 +55,8 @@ The supported types, in which an object can be converted (from / to), are: * `Long` or `long` * `Float` or `float` * `Double` or `double` +* `BigDecimal` +* `BigInteger` * `Character` or `char` * `Boolean` or `boolean` * `String` From 96582c9f38b7e6694297f76b4cbfb22427221b70 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 23 Jul 2019 18:05:19 +0200 Subject: [PATCH 0760/1786] Implemented convertBigDecimal and convertBigInteger methods --- .../beans/conversion/ConverterTest.java | 47 +++++++++++++++++++ .../ConversionProcessorFactoryTest.java | 8 +++- .../impl/ByteConversionProcessorTest.java | 9 ++-- .../CharacterConversionProcessorTest.java | 27 +++++++++++ .../impl/DoubleConversionProcessorTest.java | 30 +++++++++++- .../impl/FloatConversionProcessorTest.java | 30 +++++++++++- .../impl/IntegerConversionProcessorTest.java | 27 +++++++++++ .../impl/LongConversionProcessorTest.java | 27 +++++++++++ .../impl/ShortConversionProcessorTest.java | 27 +++++++++++ .../impl/StringConversionProcessorTest.java | 27 +++++++++++ 10 files changed, 252 insertions(+), 7 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 7532197ca..ae06caa66 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; import java.math.BigInteger; import java.util.Optional; import java.util.function.Function; @@ -50,6 +51,9 @@ public class ConverterTest { private static final char CHAR_INT_VALUE = '1'; private static final byte TRUE_AS_BYTE = 1; private static final int TRUE_AS_INT = 1; + private static final char BIG_DECIMAL_ZERO_AS_CHAR = (char) BigDecimal.ZERO.doubleValue(); + private static final char BIG_INTEGER_ZERO_AS_CHAR = (char) BigInteger.ZERO.intValue(); + private static final double TRUE_AS_DOUBLE = 1.0; /** * The class to be tested. */ @@ -193,6 +197,8 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a boolean value from a char", CHAR_VALUE, boolean.class, Boolean.TRUE}, {"Tests that the method returns a boolean value from a Boolean", Boolean.TRUE, boolean.class, Boolean.TRUE}, {"Tests that the method returns a boolean value from a String", String.valueOf(Boolean.FALSE), boolean.class, Boolean.FALSE}, + {"Tests that the method returns a boolean value from a BigInteger", BigInteger.ZERO, boolean.class, Boolean.FALSE}, + {"Tests that the method returns a boolean value from a BigDecimal", BigDecimal.ZERO, boolean.class, Boolean.FALSE}, // byte conversion test cases {"Tests that the method returns a byte value from a byte", Byte.MIN_VALUE, byte.class, Byte.MIN_VALUE}, {"Tests that the method returns a byte value from a short", Short.MIN_VALUE, byte.class, Short.valueOf(Short.MIN_VALUE).byteValue()}, @@ -203,6 +209,8 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a byte value from a char", CHAR_VALUE, byte.class, (byte) Character.valueOf(CHAR_VALUE).charValue()}, {"Tests that the method returns a byte value from a Boolean", Boolean.TRUE, byte.class, TRUE_AS_BYTE}, {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a byte value from a BigInteger", BigInteger.ZERO, byte.class, BigInteger.ZERO.byteValue()}, + {"Tests that the method returns a byte value from a BigDecimal", BigDecimal.ZERO, byte.class, BigDecimal.ZERO.byteValue()}, // char conversion test cases {"Tests that the method returns a char value from a byte", Byte.MIN_VALUE, char.class, (char) Byte.MIN_VALUE}, {"Tests that the method returns a char value from a short", Short.MIN_VALUE, char.class, (char) Short.MIN_VALUE}, @@ -213,6 +221,8 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a char value from a char", CHAR_VALUE, char.class, CHAR_VALUE}, {"Tests that the method returns a char value from a Boolean", Boolean.TRUE, char.class, CHAR_VALUE}, {"Tests that the method returns a char value from a String", ONE_AS_STRING, char.class, ONE_AS_STRING.charAt(0)}, + {"Tests that the method returns a char value from a BigInteger", BigInteger.ZERO, char.class, BIG_INTEGER_ZERO_AS_CHAR}, + {"Tests that the method returns a char value from a BigDecimal", BigDecimal.ZERO, char.class, BIG_DECIMAL_ZERO_AS_CHAR}, // double conversion test cases {"Tests that the method returns a double value from a byte", Byte.MIN_VALUE, double.class, Byte.valueOf(Byte.MIN_VALUE).doubleValue()}, {"Tests that the method returns a double value from a short", Short.MIN_VALUE, double.class, Short.valueOf(Short.MIN_VALUE).doubleValue()}, @@ -223,6 +233,8 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a double value from a char", CHAR_INT_VALUE, double.class, Double.valueOf(String.valueOf(CHAR_INT_VALUE))}, {"Tests that the method returns a double value from a Boolean", Boolean.TRUE, double.class, (double) TRUE_AS_INT}, {"Tests that the method returns a double value from a String", ONE_AS_STRING, double.class, Double.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a double value from a BigInteger", BigInteger.ZERO, double.class, BigInteger.ZERO.doubleValue()}, + {"Tests that the method returns a double value from a BigDecimal", BigDecimal.ZERO, double.class, BigDecimal.ZERO.doubleValue()}, // float conversion test cases {"Tests that the method returns a float value from a byte", Byte.MIN_VALUE, float.class, Byte.valueOf(Byte.MIN_VALUE).floatValue()}, {"Tests that the method returns a float value from a short", Short.MIN_VALUE, float.class, Short.valueOf(Short.MIN_VALUE).floatValue()}, @@ -233,6 +245,8 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a float value from a char", CHAR_INT_VALUE, float.class, (float) getNumericValue(CHAR_INT_VALUE)}, {"Tests that the method returns a float value from a Boolean", Boolean.TRUE, float.class, (float) TRUE_AS_INT}, {"Tests that the method returns a float value from a String", ONE_AS_STRING, float.class, Float.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a float value from a BigInteger", BigInteger.ZERO, float.class, BigInteger.ZERO.floatValue()}, + {"Tests that the method returns a float value from a BigDecimal", BigDecimal.ZERO, float.class, BigDecimal.ZERO.floatValue()}, // integer conversion test cases {"Tests that the method returns an int value from a byte", Byte.MIN_VALUE, int.class, Byte.valueOf(Byte.MIN_VALUE).intValue()}, {"Tests that the method returns an int value from a short", Short.MIN_VALUE, int.class, Short.valueOf(Short.MIN_VALUE).intValue()}, @@ -243,6 +257,8 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns an int value from a char", CHAR_INT_VALUE, int.class, getNumericValue(CHAR_INT_VALUE)}, {"Tests that the method returns an int value from a Boolean", Boolean.TRUE, int.class, TRUE_AS_INT}, {"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns an int value from a BigInteger", BigInteger.ZERO, int.class, BigInteger.ZERO.intValue()}, + {"Tests that the method returns an int value from a BigDecimal", BigDecimal.ZERO, int.class, BigDecimal.ZERO.intValue()}, // long conversion test cases {"Tests that the method returns a long value from a byte", Byte.MIN_VALUE, long.class, Byte.valueOf(Byte.MIN_VALUE).longValue()}, {"Tests that the method returns a long value from a short", Short.MIN_VALUE, long.class, Short.valueOf(Short.MIN_VALUE).longValue()}, @@ -253,6 +269,8 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a long value from a char", CHAR_INT_VALUE, long.class, (long) getNumericValue(CHAR_INT_VALUE)}, {"Tests that the method returns a long value from a Boolean", Boolean.TRUE, long.class, (long) TRUE_AS_INT}, {"Tests that the method returns a long value from a String", ONE_AS_STRING, long.class, Long.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a long value from a BigInteger", BigInteger.ZERO, long.class, BigInteger.ZERO.longValue()}, + {"Tests that the method returns a long value from a BigDecimal", BigDecimal.ZERO, long.class, BigDecimal.ZERO.longValue()}, // short conversion test cases {"Tests that the method returns a short value from a byte", Byte.MIN_VALUE, short.class, Byte.valueOf(Byte.MIN_VALUE).shortValue()}, {"Tests that the method returns a short value from a short", Short.MIN_VALUE, short.class, Short.MIN_VALUE}, @@ -263,6 +281,8 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a short value from a char", CHAR_INT_VALUE, short.class, (short) getNumericValue(CHAR_INT_VALUE)}, {"Tests that the method returns a short value from a Boolean", Boolean.TRUE, short.class, (short) TRUE_AS_INT}, {"Tests that the method returns a short value from a String", ONE_AS_STRING, short.class, Short.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a short value from a BigInteger", BigInteger.ZERO, short.class, BigInteger.ZERO.shortValue()}, + {"Tests that the method returns a short value from a BigDecimal", BigDecimal.ZERO, short.class, BigDecimal.ZERO.shortValue()}, // string conversion test cases {"Tests that the method returns a String value from a byte", Byte.MIN_VALUE, String.class, Byte.valueOf(Byte.MIN_VALUE).toString()}, {"Tests that the method returns a String value from a short", Short.MIN_VALUE, String.class, Short.valueOf(Short.MIN_VALUE).toString()}, @@ -273,6 +293,33 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a String value from a char", CHAR_INT_VALUE, String.class, String.valueOf(CHAR_INT_VALUE)}, {"Tests that the method returns a String value from a Boolean", Boolean.TRUE, String.class, String.valueOf(Boolean.TRUE)}, {"Tests that the method returns a String value from a String", ONE_AS_STRING, String.class, ONE_AS_STRING}, + {"Tests that the method returns a String value from a BigInteger", BigInteger.ZERO, String.class, BigInteger.ZERO.toString()}, + {"Tests that the method returns a String value from a BigDecimal", BigDecimal.ZERO, String.class, BigDecimal.ZERO.toPlainString()}, + // BigInteger conversion test cases + {"Tests that the method returns a BigInteger value from a byte", Byte.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Byte.valueOf(Byte.MIN_VALUE).longValue())}, + {"Tests that the method returns a BigInteger value from a short", Short.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Short.MIN_VALUE)}, + {"Tests that the method returns a BigInteger value from an Integer", Integer.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Integer.MIN_VALUE)}, + {"Tests that the method returns a BigInteger value from a Long", Long.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Long.MIN_VALUE)}, + {"Tests that the method returns a BigInteger value from a Float", Float.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Float.valueOf(Float.MIN_VALUE).intValue())}, + {"Tests that the method returns a BigInteger value from a Double", Double.MIN_VALUE, BigInteger.class, + BigInteger.valueOf(Double.valueOf(Double.MIN_VALUE).intValue())}, + {"Tests that the method returns a BigInteger value from a char", CHAR_INT_VALUE, BigInteger.class, BigInteger.valueOf(getNumericValue(CHAR_INT_VALUE))}, + {"Tests that the method returns a BigInteger value from a Boolean", Boolean.TRUE, BigInteger.class, BigInteger.valueOf(TRUE_AS_INT)}, + {"Tests that the method returns a BigInteger value from a String", ONE_AS_STRING, BigInteger.class, new BigInteger(ONE_AS_STRING)}, + {"Tests that the method returns a BigInteger value from a BigInteger", BigInteger.ZERO, BigInteger.class, BigInteger.ZERO}, + {"Tests that the method returns a BigInteger value from a BigDecimal", BigDecimal.ZERO, BigInteger.class, BigDecimal.ZERO.toBigInteger()}, + // BigDecimal conversion test cases + {"Tests that the method returns a BigDecimal value from a byte", Byte.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Byte.valueOf(Byte.MIN_VALUE).doubleValue())}, + {"Tests that the method returns a BigDecimal value from a short", Short.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Short.MIN_VALUE)}, + {"Tests that the method returns a BigDecimal value from an Integer", Integer.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Integer.MIN_VALUE)}, + {"Tests that the method returns a BigDecimal value from a Long", Long.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Long.MIN_VALUE)}, + {"Tests that the method returns a BigDecimal value from a Float", Float.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Float.MIN_VALUE)}, + {"Tests that the method returns a BigDecimal value from a Double", Double.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Double.MIN_VALUE)}, + {"Tests that the method returns a BigDecimal value from a char", CHAR_INT_VALUE, BigDecimal.class, BigDecimal.valueOf(getNumericValue(CHAR_INT_VALUE))}, + {"Tests that the method returns a BigDecimal value from a Boolean", Boolean.TRUE, BigDecimal.class, BigDecimal.valueOf(TRUE_AS_DOUBLE)}, + {"Tests that the method returns a BigDecimal value from a String", ONE_AS_STRING, BigDecimal.class, new BigDecimal(ONE_AS_STRING)}, + {"Tests that the method returns a BigDecimal value from a BigInteger", BigInteger.ZERO, BigDecimal.class, BigDecimal.valueOf(BigInteger.ZERO.intValue())}, + {"Tests that the method returns a BigDecimal value from a BigDecimal", BigDecimal.ZERO, BigDecimal.class, BigDecimal.ZERO}, }; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index 8de29f251..e3486ac99 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -20,6 +20,8 @@ import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.Optional; import org.apache.commons.lang3.tuple.Pair; @@ -28,6 +30,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; +import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; @@ -111,7 +115,9 @@ private Object[][] dataGetConversionProcessorTesting() { {"Tests that the method returns a CharacterConversionProcessor is case the target class is a char", char.class, CharacterConversionProcessor.class}, {"Tests that the method returns a StringConversionProcessor is case the target class is a String", String.class, StringConversionProcessor.class}, {"Tests that the method returns a BooleanConversionProcessor is case the target class is a Boolean", Boolean.class, BooleanConversionProcessor.class}, - {"Tests that the method returns a BooleanConversionProcessor is case the target class is a boolean", boolean.class, BooleanConversionProcessor.class} + {"Tests that the method returns a BooleanConversionProcessor is case the target class is a boolean", boolean.class, BooleanConversionProcessor.class}, + {"Tests that the method returns a BigIntegerConversionProcessor is case the target class is a BigInteger", BigInteger.class, BigIntegerConversionProcessor.class}, + {"Tests that the method returns a BigDecimalConversionProcessor is case the target class is a BigDecimal", BigDecimal.class, BigDecimalConversionProcessor.class} }; } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java index a86e5de0c..8d6f3fedd 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java @@ -35,6 +35,7 @@ public class ByteConversionProcessorTest extends AbstractConversionProcessorTest { private static final byte TRUE_AS_BYTE = 1; private static final byte FALSE_AS_BYTE = 0; + /** * The class to be tested. */ @@ -172,10 +173,10 @@ public void testConvertBigIntegerShouldReturnProperResult() { byte expectedValue = BigInteger.ZERO.byteValue(); // WHEN - Byte actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + byte actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expectedValue, actual.byteValue()); + assertEquals(expectedValue, actual); } @Test @@ -184,9 +185,9 @@ public void testConvertBigDecimalShouldReturnProperResult() { byte expectedValue = BigDecimal.ZERO.byteValue(); // WHEN - Byte actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + byte actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual.byteValue()); + assertEquals(expectedValue, actual); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java index be8dda27c..c9ed9ed2f 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java @@ -19,6 +19,9 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -161,4 +164,28 @@ public void testConvertStringShouldReturnProperResult() { // THEN assertEquals(STRING_VALUE.charAt(0), actual); } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + char expectedValue = (char) BigInteger.ZERO.intValue(); + + // WHEN + char actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + char expectedValue = (char) BigDecimal.ZERO.doubleValue(); + + // WHEN + char actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java index d0d1c4882..912297c92 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java @@ -22,6 +22,9 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -33,6 +36,7 @@ public class DoubleConversionProcessorTest extends AbstractConversionProcessorTest { private static final double TRUE_AS_DOUBLE = 1d; private static final double FALSE_AS_DOUBLE = 0d; + private static final double DELTA = 0.0; /** * The class to be tested. @@ -139,7 +143,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc Double actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual, 0.0); + assertEquals(expectedResult, actual, DELTA); } /** @@ -164,5 +168,29 @@ public void testConvertStringShouldReturnProperResult() { // THEN assertEquals(valueOf(STRING_VALUE), actual); } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + double expectedValue = BigInteger.ZERO.doubleValue(); + + // WHEN + double actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(expectedValue, actual, DELTA); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + double expectedValue = BigDecimal.ZERO.doubleValue(); + + // WHEN + double actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual, DELTA); + } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java index 5ee7ab4eb..686ac8f19 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java @@ -22,6 +22,9 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -33,6 +36,7 @@ public class FloatConversionProcessorTest extends AbstractConversionProcessorTest { private static final float TRUE_AS_FLOAT = 1f; private static final float FALSE_AS_FLOAT = 0f; + private static final double DELTA = 0.0; /** * The class to be tested. @@ -139,7 +143,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc Float actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual, 0.0); + assertEquals(expectedResult, actual, DELTA); } /** @@ -164,5 +168,29 @@ public void testConvertStringShouldReturnProperResult() { // THEN assertEquals(valueOf(STRING_VALUE), actual); } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + double expectedValue = BigInteger.ZERO.floatValue(); + + // WHEN + double actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(expectedValue, actual, DELTA); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + float expectedValue = BigDecimal.ZERO.floatValue(); + + // WHEN + float actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual, DELTA); + } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java index 8ef34805b..3daab02ff 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java @@ -22,6 +22,9 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -164,5 +167,29 @@ public void testConvertStringShouldReturnProperResult() { // THEN assertEquals(valueOf(STRING_VALUE), actual); } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + int expectedValue = BigInteger.ZERO.intValue(); + + // WHEN + int actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + int expectedValue = BigDecimal.ZERO.intValue(); + + // WHEN + int actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java index 0d5c39a30..9b6ffba5d 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java @@ -22,6 +22,9 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -164,5 +167,29 @@ public void testConvertStringShouldReturnProperResult() { // THEN assertEquals(valueOf(STRING_VALUE), actual); } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + long expectedValue = BigInteger.ZERO.longValue(); + + // WHEN + long actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + long expectedValue = BigDecimal.ZERO.longValue(); + + // WHEN + long actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java index 53ae6843d..3a14ab971 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java @@ -22,6 +22,9 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -164,4 +167,28 @@ public void testConvertStringShouldReturnProperResult() { // THEN assertEquals(valueOf(STRING_VALUE), actual); } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + short expectedValue = BigInteger.ZERO.shortValue(); + + // WHEN + short actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + short expectedValue = BigDecimal.ZERO.shortValue(); + + // WHEN + short actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java index 9e6bc4093..728fc8e23 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java @@ -21,6 +21,9 @@ import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigDecimal; +import java.math.BigInteger; + import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -141,4 +144,28 @@ public void testConvertStringShouldReturnProperResult() { // THEN assertEquals(STRING_VALUE, actual); } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + String expectedValue = BigDecimal.ZERO.toPlainString(); + + // WHEN + String actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + String expectedValue = BigDecimal.ZERO.toPlainString(); + + // WHEN + String actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } } From 353e49e39184fd5447bbe3960b35dfab880e68b0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 24 Jul 2019 09:53:45 +0200 Subject: [PATCH 0761/1786] Added UT for: BigDecimalConversionProcessor and BigIntegerConversionProcessorTest --- .../impl/BigDecimalConversionProcessor.java | 2 +- .../beans/conversion/ConverterTest.java | 2 +- .../analyzer/ConversionAnalyzerTest.java | 8 +- .../BigDecimalConversionProcessorTest.java | 199 ++++++++++++++++++ .../BigIntegerConversionProcessorTest.java | 198 +++++++++++++++++ 5 files changed, 404 insertions(+), 5 deletions(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java index 7a158583a..02247261d 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java @@ -90,7 +90,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? (double) 1 : (double) 0); + return val -> valueOf(val ? 1 : 0); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index ae06caa66..546819e56 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -316,7 +316,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a BigDecimal value from a Float", Float.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Float.MIN_VALUE)}, {"Tests that the method returns a BigDecimal value from a Double", Double.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Double.MIN_VALUE)}, {"Tests that the method returns a BigDecimal value from a char", CHAR_INT_VALUE, BigDecimal.class, BigDecimal.valueOf(getNumericValue(CHAR_INT_VALUE))}, - {"Tests that the method returns a BigDecimal value from a Boolean", Boolean.TRUE, BigDecimal.class, BigDecimal.valueOf(TRUE_AS_DOUBLE)}, + {"Tests that the method returns a BigDecimal value from a Boolean", Boolean.TRUE, BigDecimal.class, BigDecimal.valueOf(TRUE_AS_INT)}, {"Tests that the method returns a BigDecimal value from a String", ONE_AS_STRING, BigDecimal.class, new BigDecimal(ONE_AS_STRING)}, {"Tests that the method returns a BigDecimal value from a BigInteger", BigInteger.ZERO, BigDecimal.class, BigDecimal.valueOf(BigInteger.ZERO.intValue())}, {"Tests that the method returns a BigDecimal value from a BigDecimal", BigDecimal.ZERO, BigDecimal.class, BigDecimal.ZERO}, diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index 1f16884df..3b77b9663 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -91,7 +91,9 @@ private Object[][] dataGetConversionFunctionEmptyCaseTesting() { {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type but it's not primitive", Pair.class, int.class}, {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type and the destination type is void", - int.class, Void.class} + int.class, Void.class}, + {"Tests that the method returns an empty optional in case the source field type is not equal to the source field type and the source type is void", + Void.class, int.class} }; } @@ -141,8 +143,8 @@ char.class, String.class, new StringConversionProcessor().convertCharacter()}, boolean.class, char.class, new CharacterConversionProcessor().convertBoolean()}, {"Tests that the method returns a BooleanConversionProcessor that converts from String to boolean", String.class, boolean.class, new BooleanConversionProcessor().convertString()}, - {"Tests that the method returns a BigIntegerConversionProcessor that converts from String to BigInteger", - String.class, BigInteger.class, new BigIntegerConversionProcessor().convertString()}, + {"Tests that the method returns a BigIntegerConversionProcessor that converts from BigDecimal to BigInteger", + BigDecimal.class, BigInteger.class, new BigIntegerConversionProcessor().convertBigDecimal()}, {"Tests that the method returns a BigDecimalConversionProcessor that converts from String to BigDecimal", String.class, BigDecimal.class, new BigDecimalConversionProcessor().convertString()}, }; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java new file mode 100644 index 000000000..262bc9444 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java @@ -0,0 +1,199 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Character.getNumericValue; +import static java.math.BigDecimal.valueOf; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link BigDecimalConversionProcessor}. + */ +public class BigDecimalConversionProcessorTest extends AbstractConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private BigDecimalConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + BigDecimal expected = valueOf(BYTE_VALUE.doubleValue()); + + // WHEN + BigDecimal actual = underTest.convertByte().apply(BYTE_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + BigDecimal expected = valueOf(SHORT_VALUE); + + // WHEN + BigDecimal actual = underTest.convertShort().apply(SHORT_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + BigDecimal expected = valueOf(INTEGER_VALUE); + + // WHEN + BigDecimal actual = underTest.convertInteger().apply(INTEGER_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + BigDecimal expected = valueOf(LONG_VALUE); + + // WHEN + BigDecimal actual = underTest.convertLong().apply(LONG_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + BigDecimal expected = valueOf(FLOAT_VALUE); + + // WHEN + BigDecimal actual = underTest.convertFloat().apply(FLOAT_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + BigDecimal expected = valueOf(DOUBLE_VALUE); + + // WHEN + BigDecimal actual = underTest.convertDouble().apply(DOUBLE_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + BigDecimal expected = valueOf(getNumericValue(CHAR_VALUE)); + + // WHEN + BigDecimal actual = underTest.convertCharacter().apply(CHAR_VALUE); + + // THEN + assertEquals(expected, actual); + } + + /** + * Tests that the method {@code convertBoolean} returns the expected BigDecimal. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToIntConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final BigDecimal expectedResult) { + // GIVEN + + // WHEN + BigDecimal actual = underTest.convertBoolean().apply(valueToConvert); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToIntConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns 1 if the value is true", BOOLEAN_VALUE, BigDecimal.ONE}, + {"Tests that the method returns 0 if the value is false", Boolean.FALSE, BigDecimal.ZERO} + }; + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + BigDecimal expected = new BigDecimal(STRING_VALUE); + + // WHEN + BigDecimal actual = underTest.convertString().apply(STRING_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + BigDecimal expected = valueOf(BigInteger.ZERO.intValue()); + + // WHEN + BigDecimal actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + BigDecimal expectedValue = BigDecimal.ZERO; + + // WHEN + BigDecimal actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } +} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java new file mode 100644 index 000000000..765320b18 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java @@ -0,0 +1,198 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static java.lang.Character.getNumericValue; +import static java.math.BigInteger.valueOf; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link BigIntegerConversionProcessor}. + */ +public class BigIntegerConversionProcessorTest extends AbstractConversionProcessorTest { + /** + * The class to be tested. + */ + @InjectMocks + private BigIntegerConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + BigInteger expected = valueOf(BYTE_VALUE.longValue()); + + // WHEN + BigInteger actual = underTest.convertByte().apply(BYTE_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + BigInteger expected = valueOf(SHORT_VALUE); + + // WHEN + BigInteger actual = underTest.convertShort().apply(SHORT_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + BigInteger expected = valueOf(INTEGER_VALUE); + + // WHEN + BigInteger actual = underTest.convertInteger().apply(INTEGER_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + BigInteger expected = valueOf(LONG_VALUE); + + // WHEN + BigInteger actual = underTest.convertLong().apply(LONG_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + BigInteger expected = valueOf(FLOAT_VALUE.intValue()); + + // WHEN + BigInteger actual = underTest.convertFloat().apply(FLOAT_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + BigInteger expected = valueOf(DOUBLE_VALUE.intValue()); + + // WHEN + BigInteger actual = underTest.convertDouble().apply(DOUBLE_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + BigInteger expected = valueOf(getNumericValue(CHAR_VALUE)); + + // WHEN + BigInteger actual = underTest.convertCharacter().apply(CHAR_VALUE); + + // THEN + assertEquals(expected, actual); + } + + /** + * Tests that the method {@code convertBoolean} returns the expected BigInteger. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToIntConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final BigInteger expectedResult) { + // GIVEN + + // WHEN + BigInteger actual = underTest.convertBoolean().apply(valueToConvert); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToIntConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns 1 if the value is true", BOOLEAN_VALUE, BigInteger.ONE}, + {"Tests that the method returns 0 if the value is false", Boolean.FALSE, BigInteger.ZERO} + }; + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + BigInteger expected = new BigInteger(STRING_VALUE); + + // WHEN + BigInteger actual = underTest.convertString().apply(STRING_VALUE); + + // THEN + assertEquals(expected, actual); + } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + + // WHEN + BigInteger actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertEquals(BigInteger.ZERO, actual); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + BigInteger expectedValue = BigDecimal.ZERO.toBigInteger(); + + // WHEN + BigInteger actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertEquals(expectedValue, actual); + } +} From 73ad3192a12b6890dc72effae8e8105a09394a4d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 24 Jul 2019 12:37:59 +0200 Subject: [PATCH 0762/1786] Primitive transformer function retrieval refactoring --- .../beans/transformer/TransformerImpl.java | 40 ++++++++++--------- .../analyzer/ConversionAnalyzerTest.java | 2 + 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 7fa28be6f..6067c725e 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -426,8 +426,8 @@ private Class getSourceFieldType(final Class sourceObjectClass, final Stri * @param the target object type * @return the transformer function. */ - private List getTransformerFunction(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, - final Field field, final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { + private List getTransformerFunction(final Class sourceObjectClass, final String sourceFieldName, + final Class targetClass, final Field field, final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { List fieldTransformers = new ArrayList<>(); String fieldTransformerKey = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; FieldTransformer fieldTransformer = settings.getFieldsTransformers().get(fieldTransformerKey); @@ -457,23 +457,27 @@ private List getTransformerFunction(final Class sourceO */ private FieldTransformer getPrimitiveTypeTransformer(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, final Field field, final boolean isDestinationFieldPrimitiveType, final String fieldTransformerKey, final boolean isFieldTransformerDefined) { - String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + targetClass - + "-" + fieldTransformerKey + "-" + isFieldTransformerDefined - + "-" + settings.isPrimitiveTypeConversionEnabled() + "-" + field.getName(); - return cacheManager.getFromCache(cacheKey, FieldTransformer.class) - .orElseGet(() -> { - FieldTransformer defaultPrimitiveTypeTransformer = null; - if (settings.isPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType && !isFieldTransformerDefined) { - Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); - if (nonNull(sourceFieldType)) { - defaultPrimitiveTypeTransformer = conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) - .map(conversionFunction -> new FieldTransformer<>(fieldTransformerKey, conversionFunction)) - .orElse(null); + FieldTransformer fieldTransformer = null; + if (settings.isPrimitiveTypeConversionEnabled()) { + String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + targetClass.getName() + + "-" + fieldTransformerKey + "-" + isFieldTransformerDefined + + "-" + field.getName(); + fieldTransformer = cacheManager.getFromCache(cacheKey, FieldTransformer.class) + .orElseGet(() -> { + FieldTransformer primitiveTypeTransformer = null; + if (isDestinationFieldPrimitiveType && !isFieldTransformerDefined) { + Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); + if (nonNull(sourceFieldType)) { + primitiveTypeTransformer = conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) + .map(conversionFunction -> new FieldTransformer<>(fieldTransformerKey, conversionFunction)) + .orElse(null); + } } - } - cacheManager.cacheObject(cacheKey, defaultPrimitiveTypeTransformer); - return defaultPrimitiveTypeTransformer; - }); + cacheManager.cacheObject(cacheKey, primitiveTypeTransformer); + return primitiveTypeTransformer; + }); + } + return fieldTransformer; } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index 3b77b9663..9ea7b7d7c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -19,6 +19,7 @@ import static java.util.Optional.empty; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -113,6 +114,7 @@ public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN + assertTrue(actual.isPresent()); assertEquals(expectedConversionFunction, actual.get()); } From 8345636c5ab82591131c2acbf4e84cff334add05 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 24 Jul 2019 16:38:03 +0200 Subject: [PATCH 0763/1786] test travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 20c7e144a..b251d10fc 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - install: travis_retry mvn clean install -DskipTests + script: travis_retry mvn clean install -DskipTests - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present From 1ed1ed28d3fdc6b7e359866bafa8b2f52063d6ee Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 24 Jul 2019 16:47:41 +0200 Subject: [PATCH 0764/1786] reverted travis changes --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b251d10fc..20c7e144a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ jobs: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - script: travis_retry mvn clean install -DskipTests + install: travis_retry mvn clean install -DskipTests - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present From 85ecc4dd58b6bd79f59377b675b44e9f001fc3c5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 24 Jul 2019 16:49:50 +0200 Subject: [PATCH 0765/1786] Modified travis config in order to not execute mvn test automatically --- .travis.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 20c7e144a..19da80924 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,27 +1,28 @@ language: java cache: directories: - - "~/.m2/repository" + - "~/.m2/repository" jdk: openjdk11 env: global: - # HCOM OSS Sonatype jira info - - secure: W40tXg80XoNy8L3GujgF4PzuiWqY4q5o+XVqppj1atLS7dFa/KuSjJ6bBWF0ootVjmXpRofUF5/Tg2zwcwtOKm9wSjCdgmoGht2CFryieoNVuwJ7MFBLheMvpKp940vHpXDMxb5mc/lff1yM/XNLd5aUa5ITw8GE7qowc3Irc2tUTZKQem+o3mwnuj0dBsRUQt2eGIEkqDWn/pQ5SfjUWSQp3YUVv0iPjIvwV+lHSEB9Mod8Am/5TYuFxINgo6R3MX5K7rwaXjvErSUz6gAP2kqoA+EZDUotmdhFr8zVVpB8e33bPwxNlTYJ5fePKIkLz3TjEb1UVpav2/Ie/jpD0QbfCL/hukEPV/JKye+4fOIJeRZGwBXOQQsscyfcNf9utHittG4ZEzOXwYutbSf4qjoI5V48/hC8hs0OL3RJGE6e4v9tQwvIxY/IopqreACVrHIRK34fOoABQpFUPsmcGTuLrAGJqjDn9UiXJqb9Qlgav1Ly0KKH5YnKQoxyc5RvQDC8NvafSDgex0udGwTVGDNYgQeGVmrOy/C6iDIyEe5hn5gXwDFWFMxETjHcYka7gCngCbDiGIOMxiOeHbnO2dG7HbNME6p9nRovdD/n5cnp4sj3ttysyMNRt8NE2IkZRfJ+LQUqcavpkeVRvN5O/drNBtYnTOXC+lGCV0XGL2E= - - secure: cniGJvvR9/RcmRAp0F+iLvqQGH3zlvDYUb1GqZpX2ZKgqJ9syidk/Xy456HdR9WM9gTHZdQLNXYQFx9Dt41pa3Ft9nEi9LvmoLp/3rh/Siogx2X/madDxqHOXshCMYUg9ndSk8KKvjYSb+ztxT8j1qDW553Fax2YPWQiGRT5FXaEg1vl6znR362AhXaU1MgB8Wq+tDzTYJZugGj13u0S/vkNuTd30IQ5sW9YoQ4QwYPJIaG6ix1EUo0P3u96edakQjIAdciMLkggsfQkZr2MF5vAHjUI4+qW5wyAV2mzauc2MKhvKkJnF6WcNYOsXBOyDCAPJNo5YM4ODJM9ot7CcfKllecBaFUs4Uqh2U0lIe6opRtMdYPwV/GAAXwanSKgM1dNxgmPHnUWffWjaUJAbN94E/EH9JtGK2FAuxWqhbsPuMbpGK3XXuojU1fYj3oGGYFmSE3xWmhtSU89xiDrmrooGxxkaRt00eWtK+qCuiR8KGkN//i3+3x2F0ysVoOJL5WSSzNyfbtfp6laHTZv/LSAFgjSEmJF04L4m4Yhm/EDKaUXZjR/TAK2NZDTxlOxaOGVhwPA8Xj5YSwDMTd5k+cPntpYn/NbWtRr4fwk6VxI4XOOtksdiSk4Eiiaco2qEyd3X1tW/B9bPaAAFk8jHD35GNZAazgvNq7+kpMOg1s= - # GPG_KEYNAME - - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= - # GPG_PASSPHRASE - - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= + # HCOM OSS Sonatype jira info + - secure: W40tXg80XoNy8L3GujgF4PzuiWqY4q5o+XVqppj1atLS7dFa/KuSjJ6bBWF0ootVjmXpRofUF5/Tg2zwcwtOKm9wSjCdgmoGht2CFryieoNVuwJ7MFBLheMvpKp940vHpXDMxb5mc/lff1yM/XNLd5aUa5ITw8GE7qowc3Irc2tUTZKQem+o3mwnuj0dBsRUQt2eGIEkqDWn/pQ5SfjUWSQp3YUVv0iPjIvwV+lHSEB9Mod8Am/5TYuFxINgo6R3MX5K7rwaXjvErSUz6gAP2kqoA+EZDUotmdhFr8zVVpB8e33bPwxNlTYJ5fePKIkLz3TjEb1UVpav2/Ie/jpD0QbfCL/hukEPV/JKye+4fOIJeRZGwBXOQQsscyfcNf9utHittG4ZEzOXwYutbSf4qjoI5V48/hC8hs0OL3RJGE6e4v9tQwvIxY/IopqreACVrHIRK34fOoABQpFUPsmcGTuLrAGJqjDn9UiXJqb9Qlgav1Ly0KKH5YnKQoxyc5RvQDC8NvafSDgex0udGwTVGDNYgQeGVmrOy/C6iDIyEe5hn5gXwDFWFMxETjHcYka7gCngCbDiGIOMxiOeHbnO2dG7HbNME6p9nRovdD/n5cnp4sj3ttysyMNRt8NE2IkZRfJ+LQUqcavpkeVRvN5O/drNBtYnTOXC+lGCV0XGL2E= + - secure: cniGJvvR9/RcmRAp0F+iLvqQGH3zlvDYUb1GqZpX2ZKgqJ9syidk/Xy456HdR9WM9gTHZdQLNXYQFx9Dt41pa3Ft9nEi9LvmoLp/3rh/Siogx2X/madDxqHOXshCMYUg9ndSk8KKvjYSb+ztxT8j1qDW553Fax2YPWQiGRT5FXaEg1vl6znR362AhXaU1MgB8Wq+tDzTYJZugGj13u0S/vkNuTd30IQ5sW9YoQ4QwYPJIaG6ix1EUo0P3u96edakQjIAdciMLkggsfQkZr2MF5vAHjUI4+qW5wyAV2mzauc2MKhvKkJnF6WcNYOsXBOyDCAPJNo5YM4ODJM9ot7CcfKllecBaFUs4Uqh2U0lIe6opRtMdYPwV/GAAXwanSKgM1dNxgmPHnUWffWjaUJAbN94E/EH9JtGK2FAuxWqhbsPuMbpGK3XXuojU1fYj3oGGYFmSE3xWmhtSU89xiDrmrooGxxkaRt00eWtK+qCuiR8KGkN//i3+3x2F0ysVoOJL5WSSzNyfbtfp6laHTZv/LSAFgjSEmJF04L4m4Yhm/EDKaUXZjR/TAK2NZDTxlOxaOGVhwPA8Xj5YSwDMTd5k+cPntpYn/NbWtRr4fwk6VxI4XOOtksdiSk4Eiiaco2qEyd3X1tW/B9bPaAAFk8jHD35GNZAazgvNq7+kpMOg1s= + # GPG_KEYNAME + - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= + # GPG_PASSPHRASE + - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= install: skip jobs: include: # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" - install: travis_retry mvn clean install -DskipTests + script: travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present + script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release @@ -36,9 +37,8 @@ jobs: - stage: "Release" name: "Releasing artifacts" if: type NOT IN (pull_request) AND tag IS present - install: skip - after_deploy: skip - before_script: + script: skip + before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate From 2ca31863a9f92e6c72a39c933b282be8fcc58116 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 25 Jul 2019 08:29:03 +0200 Subject: [PATCH 0766/1786] Changed wrong test comment --- .../beans/transformer/MutableObjectTransformationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index ed150d951..c4f64c8c9 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -239,8 +239,8 @@ public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeCo } /** - * Test that a bean containing a field not existing in the source object, and without a transformer function defined throws - * MissingFieldException even if the primitiveTypeConversionFunction is enabled. + * Test that a bean containing a field not existing in the source object, and without a transformer function defined, + * does not throws MissingFieldException and the primitiveTypeConversionFunction is enabled. */ @Test public void testTransformerDoesNotThrowExceptionIfAFieldIsMissingAndTheDefaultValueSetIsEnabled() { From 95fe2936fb01f3933b43fd41708922d5a181c9b0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 29 Jul 2019 07:51:36 +0200 Subject: [PATCH 0767/1786] Minor: added suppression --- .../com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 4ef4fa7e9..ae4f6ff39 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -88,6 +88,7 @@ public Optional> getConversionFunction(final Class s * @param sourceFieldType he source field class * @return the conversion function */ + @SuppressWarnings("unchecked") private Optional> getTypeConversionFunction(final ConversionProcessor conversionProcessor, final Class sourceFieldType) { Optional> conversionFunction = empty(); if (isString(sourceFieldType)) { From 2919addaf0496dc028581a8ddfcfd997e11a6fcb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 29 Jul 2019 08:00:53 +0200 Subject: [PATCH 0768/1786] Removed unnecessary boxing --- .../conversion/processor/impl/ByteConversionProcessor.java | 4 +--- .../conversion/processor/impl/DoubleConversionProcessor.java | 2 +- .../conversion/processor/impl/FloatConversionProcessor.java | 4 ++-- .../conversion/processor/impl/IntegerConversionProcessor.java | 2 +- .../conversion/processor/impl/LongConversionProcessor.java | 4 ++-- .../conversion/processor/impl/ShortConversionProcessor.java | 2 +- .../test/java/com/hotels/beans/conversion/ConverterTest.java | 2 ++ .../conversion/processor/ConversionProcessorFactoryTest.java | 1 + 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index 69449c8ab..f78fe2ff2 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -16,8 +16,6 @@ package com.hotels.beans.conversion.processor.impl; -import static java.lang.Byte.valueOf; - import java.math.BigDecimal; import java.math.BigInteger; import java.util.function.Function; @@ -81,7 +79,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return val -> valueOf((byte) val.charValue()); + return val -> (byte) val.charValue(); } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index 4b663d56e..d5d9a12e5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -90,7 +90,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? (double) 1 : (double) 0); + return val -> val ? (double) 1 : (double) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index 9418d0b72..24f81d2ae 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -82,7 +82,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return val -> valueOf(getNumericValue(val)); + return val -> (float) getNumericValue(val); } /** @@ -90,7 +90,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? (float) 1 : (float) 0); + return val -> val ? (float) 1 : (float) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index 017c85ad0..bd671fbd1 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -89,7 +89,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? 1 : 0); + return val -> val ? 1 : 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index 013b174dc..c0077331f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -82,7 +82,7 @@ public Function convertDouble() { */ @Override public Function convertCharacter() { - return val -> valueOf(getNumericValue(val)); + return val -> (long) getNumericValue(val); } /** @@ -90,7 +90,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? (long) 1 : (long) 0); + return val -> val ? (long) 1 : (long) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index a7e549cbc..aa2f67c1d 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -90,7 +90,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? (short) 1 : (short) 0); + return val -> val ? (short) 1 : (short) 0; } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 546819e56..39a3c1518 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -21,6 +21,7 @@ import static java.util.Optional.empty; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -116,6 +117,7 @@ public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN + assertTrue(actual.isPresent()); assertEquals(expectedConversionFunction, actual.get()); } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index e3486ac99..75948b3b1 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -89,6 +89,7 @@ public void testGetConversionProcessorWorksAsExpected(final String testCaseDescr Optional actual = underTest.getConversionProcessor(targetClass); // THEN + assertTrue(actual.isPresent()); assertEquals(expectedResult, actual.get().getClass()); } From 3eb146889004aab9599db01baf42fba3303ef131 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 29 Jul 2019 15:30:22 +0200 Subject: [PATCH 0769/1786] Minor improvements --- .gitignore | 21 +++++-------------- README.md | 2 +- .../beans/error/InvalidBeanException.java | 2 +- .../impl/DoubleConversionProcessor.java | 1 - .../impl/FloatConversionProcessor.java | 1 - .../impl/IntegerConversionProcessor.java | 2 -- .../impl/LongConversionProcessor.java | 1 - .../impl/ShortConversionProcessor.java | 1 - 8 files changed, 7 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index aac3971d7..8685a648c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ -target/ !.mvn/wrapper/maven-wrapper.jar temp/ #---------------------------------------# -# STS # +# STS and Eclipse # #---------------------------------------# .apt_generated .classpath @@ -19,8 +18,11 @@ temp/ *.iws *.iml *.ipr +.idea/ -### NetBeans ### +#---------------------------------------# +# NetBeans # +#---------------------------------------# nbproject/private/ build/ !config/build/ @@ -86,19 +88,6 @@ logs/ # VS Code /.vscode -#---------------------------------------# -# JetBrains Ignores # -#---------------------------------------# -.idea/ -*.iml - -#---------------------------------------# -# Eclipse # -#---------------------------------------# -.project -.classpath -.settings - #---------------------------------------# # Netbeans Ignores # #---------------------------------------# diff --git a/README.md b/README.md index f183010a5..29d77855d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

      +

      BULL

      diff --git a/bull-common/src/main/java/com/hotels/beans/error/InvalidBeanException.java b/bull-common/src/main/java/com/hotels/beans/error/InvalidBeanException.java index 8b76bc73c..443165071 100644 --- a/bull-common/src/main/java/com/hotels/beans/error/InvalidBeanException.java +++ b/bull-common/src/main/java/com/hotels/beans/error/InvalidBeanException.java @@ -25,7 +25,7 @@ public class InvalidBeanException extends RuntimeException { * detail message of {@code (cause==null ? null : cause.toString())} * (which typically contains the class and detail message of * {@code cause}). This constructor is useful for invalid bean exceptions - * that are little more than wrappers for other throwables. + * that are little more than wrappers for other throwable. * * @param cause the cause (which is saved for later retrieval by the * {@link #getCause()} method). (A {@code null} value is diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index d5d9a12e5..8b3caaca3 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -17,7 +17,6 @@ package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; -import static java.lang.Double.valueOf; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index 24f81d2ae..01d951540 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -17,7 +17,6 @@ package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; -import static java.lang.Float.valueOf; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index bd671fbd1..ab6e78fbe 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -16,8 +16,6 @@ package com.hotels.beans.conversion.processor.impl; -import static java.lang.Integer.valueOf; - import java.math.BigDecimal; import java.math.BigInteger; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index c0077331f..d0b507072 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -17,7 +17,6 @@ package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; -import static java.lang.Long.valueOf; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index aa2f67c1d..cb5fea341 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -17,7 +17,6 @@ package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; -import static java.lang.Short.valueOf; import java.math.BigDecimal; import java.math.BigInteger; From 5922cecbeb4f269138cab97725fceb58538f2b46 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 29 Jul 2019 16:58:13 +0200 Subject: [PATCH 0770/1786] Added utilities method for checking the object type --- .../com/hotels/beans/utils/ClassUtils.java | 45 ++++++++-- .../hotels/beans/utils/ClassUtilsTest.java | 88 +++++++++++++++++++ 2 files changed, 124 insertions(+), 9 deletions(-) diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java index 22580850e..36d3df6cf 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -143,7 +143,7 @@ public boolean isPrimitiveType(final Class clazz) { public boolean isPrimitiveTypeArray(final Class clazz) { final String cacheKey = "isPrimitiveTypeArray-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = isPrimitiveType(clazz.getComponentType()); + final Boolean res = clazz.isArray() && isPrimitiveType(clazz.getComponentType()); CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); @@ -166,7 +166,7 @@ public boolean isSpecialType(final Class clazz) { } /** - * Checks if the given type is a Double. + * Checks if the given type is a {@link Double}. * @param type the class to check * @return true if is Double */ @@ -175,7 +175,7 @@ public static boolean isDouble(final Class type) { } /** - * Checks if the given type is a Float. + * Checks if the given type is a {@link Float}. * @param type the class to check * @return true if is Float */ @@ -184,7 +184,7 @@ public static boolean isFloat(final Class type) { } /** - * Checks if the given type is a Long. + * Checks if the given type is a {@link Long}. * @param type the class to check * @return true if is Long */ @@ -193,7 +193,7 @@ public static boolean isLong(final Class type) { } /** - * Checks if the given type is a Short. + * Checks if the given type is a {@link Short}. * @param type the class to check * @return true if is Short */ @@ -202,7 +202,7 @@ public static boolean isShort(final Class type) { } /** - * Checks if the given type is a Integer. + * Checks if the given type is an {@link Integer}. * @param type the class to check * @return true if is Integer */ @@ -211,7 +211,7 @@ public static boolean isInt(final Class type) { } /** - * Checks if the given type is a Byte. + * Checks if the given type is a {@link Byte}. * @param type the class to check * @return true if is Byte */ @@ -220,7 +220,7 @@ public static boolean isByte(final Class type) { } /** - * Checks if the given type is a Boolean. + * Checks if the given type is a {@link Character}. * @param type the class to check * @return true if is Character */ @@ -229,7 +229,7 @@ public static boolean isChar(final Class type) { } /** - * Checks if the given type is a Boolean. + * Checks if the given type is a {@link Boolean}. * @param type the class to check * @return true if is Boolean */ @@ -246,6 +246,33 @@ public static boolean isString(final Class type) { return type == String.class; } + /** + * Checks if the given type is a {@link BigInteger}. + * @param type the class to check + * @return true if is String + */ + public static boolean isBigInteger(final Class type) { + return type == BigInteger.class; + } + + /** + * Checks if the given type is a {@link BigDecimal}. + * @param type the class to check + * @return true if is String + */ + public static boolean isBigDecimal(final Class type) { + return type == BigDecimal.class; + } + + /** + * Checks if the given type is a byte[]. + * @param type the class to check + * @return true if is String + */ + public static boolean isByteArray(final Class type) { + return type == byte[].class; + } + /** * Return the private final fields of a class. * @param clazz class from which gets the field diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 39082aa1a..18a2782b7 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -33,6 +33,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.math.BigDecimal; +import java.math.BigInteger; import java.time.Instant; import java.util.List; import java.util.Locale; @@ -844,4 +845,91 @@ private Object[][] dataIsStringTesting() { {"Tests that the method returns false if the class is not a String", BigDecimal.class, false} }; } + + /** + * Tests that the method {@code isBigInteger} returns the expected value. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataIsBigIntegerTesting") + public void testIsBigIntegerWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { + // GIVEN + + // WHEN + boolean actual = underTest.isBigInteger(testClass); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code isBigInteger}. + * @return parameters to be used for testing the the method {@code isBigInteger}. + */ + @DataProvider + private Object[][] dataIsBigIntegerTesting() { + return new Object[][] { + {"Tests that the method returns true if the class is a BigInteger", BigInteger.class, true}, + {"Tests that the method returns false if the class is not a BigInteger", BigDecimal.class, false} + }; + } + + /** + * Tests that the method {@code isBigDecimal} returns the expected value. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataIsBigDecimalTesting") + public void testIsBigDecimalWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { + // GIVEN + + // WHEN + boolean actual = underTest.isBigDecimal(testClass); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code isBigDecimal}. + * @return parameters to be used for testing the the method {@code isBigDecimal}. + */ + @DataProvider + private Object[][] dataIsBigDecimalTesting() { + return new Object[][] { + {"Tests that the method returns true if the class is a BigDecimal", BigDecimal.class, true}, + {"Tests that the method returns false if the class is not a BigDecimal", BigInteger.class, false} + }; + } + + /** + * Tests that the method {@code isByteArray} returns the expected value. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataIsByteArrayTesting") + public void testIsBiteArrayWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { + // GIVEN + + // WHEN + boolean actual = underTest.isByteArray(testClass); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code isByteArray}. + * @return parameters to be used for testing the the method {@code isByteArray}. + */ + @DataProvider + private Object[][] dataIsByteArrayTesting() { + return new Object[][] { + {"Tests that the method returns true if the class is a byte[]", byte[].class, true}, + {"Tests that the method returns false if the class is not a byte[]", byte.class, false} + }; + } } From 72123beae88422b35fb5247b308cd7c183b5e16b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 29 Jul 2019 17:09:09 +0200 Subject: [PATCH 0771/1786] Minor: typo error fix --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- .../conversion/analyzer/ConversionAnalyzer.java | 8 ++++---- .../processor/ConversionProcessorFactory.java | 8 ++++---- .../com/hotels/beans/conversion/ConverterTest.java | 12 +++++++++++- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index c777c5582..cab804416 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. * Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). #### Changed * Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled -* Modified Transformer initialization in order to create a `ConversionAnalyzed` instance only if the automatic conversion is enabled +* Modified Transformer initialization in order to create a `ConversionAnalyzer` instance only if the automatic conversion is enabled ### [1.1.22] 2019.07.03 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f9ac6d63..26038f395 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. * Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). #### Changed * Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled -* Modified Transformer initialization in order to create a `ConversionAnalyzed` instance only if the automatic conversion is enabled +* Modified Transformer initialization in order to create a `ConversionAnalyzer` instance only if the automatic conversion is enabled ### [1.4.7.1] [1.4.7.2] [1.4.7.3] 2019.07.05 #### Changed diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index ae4f6ff39..6c9e02ff7 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -30,9 +30,9 @@ import static com.hotels.beans.utils.ClassUtils.isLong; import static com.hotels.beans.utils.ClassUtils.isShort; import static com.hotels.beans.utils.ClassUtils.isString; +import static com.hotels.beans.utils.ClassUtils.isBigDecimal; +import static com.hotels.beans.utils.ClassUtils.isBigInteger; -import java.math.BigDecimal; -import java.math.BigInteger; import java.util.Optional; import java.util.function.Function; @@ -109,9 +109,9 @@ public Optional> getConversionFunction(final Class s conversionFunction = of(conversionProcessor.convertCharacter()); } else if (isBoolean(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertBoolean()); - } else if (sourceFieldType == BigInteger.class) { + } else if (isBigInteger(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertBigInteger()); - } else if (sourceFieldType == BigDecimal.class) { + } else if (isBigDecimal(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertBigDecimal()); } return conversionFunction; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index 3b9a299fd..8d70c37e5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -19,6 +19,8 @@ import static java.util.Optional.empty; import static java.util.Optional.of; +import static com.hotels.beans.utils.ClassUtils.isBigDecimal; +import static com.hotels.beans.utils.ClassUtils.isBigInteger; import static com.hotels.beans.utils.ClassUtils.isBoolean; import static com.hotels.beans.utils.ClassUtils.isByte; import static com.hotels.beans.utils.ClassUtils.isChar; @@ -31,8 +33,6 @@ import static lombok.AccessLevel.PRIVATE; -import java.math.BigDecimal; -import java.math.BigInteger; import java.util.Optional; import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; @@ -79,9 +79,9 @@ public static Optional getConversionProcessor(final Class Date: Thu, 1 Aug 2019 08:23:01 +0200 Subject: [PATCH 0772/1786] Added byte array conversion support --- README.md | 2 +- .../analyzer/ConversionAnalyzer.java | 6 +- .../processor/ConversionProcessor.java | 8 + .../processor/ConversionProcessorFactory.java | 4 + .../impl/BigDecimalConversionProcessor.java | 17 ++ .../impl/BigIntegerConversionProcessor.java | 17 ++ .../impl/BooleanConversionProcessor.java | 8 + .../impl/ByteArrayConversionProcessor.java | 124 +++++++++++ .../impl/ByteConversionProcessor.java | 8 + .../impl/CharacterConversionProcessor.java | 18 ++ .../impl/DoubleConversionProcessor.java | 18 ++ .../impl/FloatConversionProcessor.java | 17 ++ .../impl/IntegerConversionProcessor.java | 18 ++ .../impl/LongConversionProcessor.java | 17 ++ .../impl/ShortConversionProcessor.java | 17 ++ .../impl/StringConversionProcessor.java | 8 + .../beans/conversion/ConverterTest.java | 63 +++++- .../analyzer/ConversionAnalyzerTest.java | 3 + .../ConversionProcessorFactoryTest.java | 4 +- .../impl/AbstractConversionProcessorTest.java | 2 + .../BigDecimalConversionProcessorTest.java | 23 ++ .../BigIntegerConversionProcessorTest.java | 23 ++ .../impl/BooleanConversionProcessorTest.java | 29 +++ .../ByteArrayConversionProcessorTest.java | 210 ++++++++++++++++++ .../impl/ByteConversionProcessorTest.java | 11 + .../CharacterConversionProcessorTest.java | 24 ++ .../impl/DoubleConversionProcessorTest.java | 23 ++ .../impl/FloatConversionProcessorTest.java | 23 ++ .../impl/IntegerConversionProcessorTest.java | 23 ++ .../impl/LongConversionProcessorTest.java | 23 ++ .../impl/ShortConversionProcessorTest.java | 23 ++ .../impl/StringConversionProcessorTest.java | 12 + docs/site/markdown/index.md | 2 +- 33 files changed, 820 insertions(+), 8 deletions(-) create mode 100644 bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessorTest.java diff --git a/README.md b/README.md index 29d77855d..98396c557 100644 --- a/README.md +++ b/README.md @@ -702,7 +702,7 @@ Set> violatedConstraints = beanUtils.getValidator(). Converts a given primitive value into the given primitive type. The supported types, in which an object can be converted (from / to), are: -* `Byte` or `byte` +* `Byte`, `byte` or `byte[]` * `Short` or `short` * `Integer` or `int` * `Long` or `long` diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 6c9e02ff7..5bbfa3ed1 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -32,6 +32,7 @@ import static com.hotels.beans.utils.ClassUtils.isString; import static com.hotels.beans.utils.ClassUtils.isBigDecimal; import static com.hotels.beans.utils.ClassUtils.isBigInteger; +import static com.hotels.beans.utils.ClassUtils.isByteArray; import java.util.Optional; import java.util.function.Function; @@ -72,7 +73,8 @@ public Optional> getConversionFunction(final Class s final String cacheKey = "ConversionFunction-" + sourceClass.getName() + "-" + targetClass.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional conversionFunction = empty(); - if (!targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName()) && classUtils.isPrimitiveType(sourceClass)) { + if (!targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName()) + && (classUtils.isPrimitiveType(sourceClass) || classUtils.isPrimitiveTypeArray(sourceClass))) { conversionFunction = getConversionProcessor(targetClass) .flatMap(cp -> getTypeConversionFunction(cp, sourceClass)); } @@ -113,6 +115,8 @@ public Optional> getConversionFunction(final Class s conversionFunction = of(conversionProcessor.convertBigInteger()); } else if (isBigDecimal(sourceFieldType)) { conversionFunction = of(conversionProcessor.convertBigDecimal()); + } else if (isByteArray(sourceFieldType)) { + conversionFunction = of(conversionProcessor.convertByteArray()); } return conversionFunction; } diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index b00551e24..7938cfecc 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -31,6 +31,14 @@ public interface ConversionProcessor { */ Function convertByte(); + /** + * Converts a byte[] type. + * @return the converted value + * @throws com.hotels.beans.conversion.error.TypeConversionException if the number of bytes in the array is less + * than the minimum required to create the destination type + */ + Function convertByteArray(); + /** * Converts a {@link Short} type. * @return the converted value diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index 8d70c37e5..d8497cf41 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -21,6 +21,7 @@ import static com.hotels.beans.utils.ClassUtils.isBigDecimal; import static com.hotels.beans.utils.ClassUtils.isBigInteger; +import static com.hotels.beans.utils.ClassUtils.isByteArray; import static com.hotels.beans.utils.ClassUtils.isBoolean; import static com.hotels.beans.utils.ClassUtils.isByte; import static com.hotels.beans.utils.ClassUtils.isChar; @@ -38,6 +39,7 @@ import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; +import com.hotels.beans.conversion.processor.impl.ByteArrayConversionProcessor; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; @@ -83,6 +85,8 @@ public static Optional getConversionProcessor(final Class convertByte() { return val -> valueOf(val.doubleValue()); } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> { + try { + return valueOf(wrap(val).getDouble()); + } catch (BufferUnderflowException e) { + throw new TypeConversionException("Not enough byte to represents a BigDecimal. At least 8 bytes are required."); + } + }; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java index 9926acbb7..e1dfee697 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java @@ -18,11 +18,14 @@ import static java.lang.Character.getNumericValue; import static java.math.BigInteger.valueOf; +import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.BufferUnderflowException; import java.util.function.Function; +import com.hotels.beans.conversion.error.TypeConversionException; import com.hotels.beans.conversion.processor.ConversionProcessor; /** @@ -37,6 +40,20 @@ public Function convertByte() { return val -> valueOf(val.longValue()); } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> { + try { + return valueOf(wrap(val).getLong()); + } catch (BufferUnderflowException e) { + throw new TypeConversionException("Not enough byte to represents a BigInteger. At least 8 bytes are required."); + } + }; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java index 6f689e6af..bd4d5ab59 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -34,6 +34,14 @@ public Function convertByte() { return val -> val != 0; } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> val[0] != 0; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java new file mode 100644 index 000000000..555774818 --- /dev/null +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java @@ -0,0 +1,124 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.function.Function; + +import com.hotels.beans.conversion.processor.ConversionProcessor; + +/** + * Provides all method for converting any primitive type to a byte[]. + */ +public final class ByteArrayConversionProcessor implements ConversionProcessor { + /** + * {@inheritDoc} + */ + @Override + public Function convertByte() { + return val -> new byte[] {val}; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> val; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertShort() { + return val -> new byte[] {val.byteValue()}; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertInteger() { + return val -> new byte[] {val.byteValue()}; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertLong() { + return val -> new byte[] {val.byteValue()}; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertFloat() { + return val -> new byte[] {val.byteValue()}; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertDouble() { + return val -> new byte[] {val.byteValue()}; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertCharacter() { + return val -> new byte[] {(byte) val.charValue()}; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBoolean() { + return val -> new byte[] {val ? (byte) 1 : (byte) 0}; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertString() { + return String::getBytes; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigInteger() { + return val -> new byte[] {val.byteValue()}; + } + + /** + * {@inheritDoc} + */ + @Override + public Function convertBigDecimal() { + return val -> new byte[] {val.byteValue()}; + } +} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index f78fe2ff2..5c77b63a5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -34,6 +34,14 @@ public Function convertByte() { return val -> val; } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> val[0]; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java index d4e0de5a0..f09471a01 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -16,10 +16,14 @@ package com.hotels.beans.conversion.processor.impl; +import static java.nio.ByteBuffer.wrap; + import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.BufferUnderflowException; import java.util.function.Function; +import com.hotels.beans.conversion.error.TypeConversionException; import com.hotels.beans.conversion.processor.ConversionProcessor; /** @@ -34,6 +38,20 @@ public Function convertByte() { return val -> (char) val.byteValue(); } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> { + try { + return wrap(val).getChar(); + } catch (BufferUnderflowException e) { + throw new TypeConversionException("Not enough byte to represents a Char. At least 2 bytes are required."); + } + }; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index 8b3caaca3..e3738b67c 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -17,11 +17,15 @@ package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; +import static java.math.BigDecimal.valueOf; +import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.BufferUnderflowException; import java.util.function.Function; +import com.hotels.beans.conversion.error.TypeConversionException; import com.hotels.beans.conversion.processor.ConversionProcessor; /** @@ -36,6 +40,20 @@ public Function convertByte() { return Byte::doubleValue; } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> { + try { + return wrap(val).getDouble(); + } catch (BufferUnderflowException e) { + throw new TypeConversionException("Not enough byte to represents a Double. At least 8 bytes are required."); + } + }; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index 01d951540..1b194b38f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -17,11 +17,14 @@ package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; +import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.BufferUnderflowException; import java.util.function.Function; +import com.hotels.beans.conversion.error.TypeConversionException; import com.hotels.beans.conversion.processor.ConversionProcessor; /** @@ -36,6 +39,20 @@ public Function convertByte() { return Byte::floatValue; } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> { + try { + return wrap(val).getFloat(); + } catch (BufferUnderflowException e) { + throw new TypeConversionException("Not enough byte to represents a Float. At least 4 bytes are required."); + } + }; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index ab6e78fbe..2e0a5d3fc 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -16,10 +16,14 @@ package com.hotels.beans.conversion.processor.impl; +import static java.nio.ByteBuffer.wrap; + import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.BufferUnderflowException; import java.util.function.Function; +import com.hotels.beans.conversion.error.TypeConversionException; import com.hotels.beans.conversion.processor.ConversionProcessor; /** @@ -34,6 +38,20 @@ public Function convertByte() { return Byte::intValue; } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> { + try { + return wrap(val).getInt(); + } catch (BufferUnderflowException e) { + throw new TypeConversionException("Not enough byte to represents an Integer. At least 4 bytes are required."); + } + }; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index d0b507072..ff39ed684 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -17,11 +17,14 @@ package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; +import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.BufferUnderflowException; import java.util.function.Function; +import com.hotels.beans.conversion.error.TypeConversionException; import com.hotels.beans.conversion.processor.ConversionProcessor; /** @@ -36,6 +39,20 @@ public Function convertByte() { return Byte::longValue; } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> { + try { + return wrap(val).getLong(); + } catch (BufferUnderflowException e) { + throw new TypeConversionException("Not enough byte to represents a Long. At least 8 bytes are required."); + } + }; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index cb5fea341..3983104a6 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -17,11 +17,14 @@ package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; +import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.BufferUnderflowException; import java.util.function.Function; +import com.hotels.beans.conversion.error.TypeConversionException; import com.hotels.beans.conversion.processor.ConversionProcessor; /** @@ -36,6 +39,20 @@ public Function convertByte() { return Byte::shortValue; } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return val -> { + try { + return wrap(val).getShort(); + } catch (BufferUnderflowException e) { + throw new TypeConversionException("Not enough byte to represents a Short. At least 2 bytes are required."); + } + }; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index bb6cc276b..00a63e2b8 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -34,6 +34,14 @@ public Function convertByte() { return Object::toString; } + /** + * {@inheritDoc} + */ + @Override + public Function convertByteArray() { + return String::new; + } + /** * {@inheritDoc} */ diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 85cf044c5..7d73e1f97 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -18,8 +18,10 @@ import static java.lang.Character.getNumericValue; import static java.math.BigInteger.ZERO; +import static java.nio.ByteBuffer.wrap; import static java.util.Optional.empty; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; @@ -57,7 +59,9 @@ public class ConverterTest { private static final int TRUE_AS_INT = 1; private static final char BIG_DECIMAL_ZERO_AS_CHAR = (char) BigDecimal.ZERO.doubleValue(); private static final char BIG_INTEGER_ZERO_AS_CHAR = (char) BigInteger.ZERO.intValue(); - private static final double TRUE_AS_DOUBLE = 1.0; + private static final byte[] TRUE_AS_BYTE_ARRAY = new byte[]{1}; + private static final byte[] BYTE_ARRAY = new byte[]{1, 2, 3, 4, 5, 6, 7, 8}; + /** * The class to be tested. */ @@ -154,8 +158,9 @@ boolean.class, char.class, new CharacterConversionProcessor().convertBoolean()}, {"Tests that the method returns a CharacterConversionProcessor that converts from BigInteger to BigDecimal", BigInteger.class, BigDecimal.class, new BigDecimalConversionProcessor().convertBigInteger()}, {"Tests that the method returns a CharacterConversionProcessor that converts from BigDecimal to BigInteger", - BigDecimal.class, BigInteger.class, new BigIntegerConversionProcessor().convertBigDecimal()} - + BigDecimal.class, BigInteger.class, new BigIntegerConversionProcessor().convertBigDecimal()}, + {"Tests that the method returns a CharacterConversionProcessor that converts from byte[] to String", + byte[].class, String.class, new StringConversionProcessor().convertByteArray()} }; } @@ -170,7 +175,6 @@ public void testConvertValueRaisesExceptionIfItsCalledWithNullTargetClassParam() underTest.convertValue(ZERO, null); } - /** * Tests that the method {@code convertValue} returns the expected converted value. * @param testCaseDescription the test case description @@ -211,6 +215,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a boolean value from a String", String.valueOf(Boolean.FALSE), boolean.class, Boolean.FALSE}, {"Tests that the method returns a boolean value from a BigInteger", BigInteger.ZERO, boolean.class, Boolean.FALSE}, {"Tests that the method returns a boolean value from a BigDecimal", BigDecimal.ZERO, boolean.class, Boolean.FALSE}, + {"Tests that the method returns a boolean value from a byte[]", TRUE_AS_BYTE_ARRAY, boolean.class, Boolean.TRUE}, // byte conversion test cases {"Tests that the method returns a byte value from a byte", Byte.MIN_VALUE, byte.class, Byte.MIN_VALUE}, {"Tests that the method returns a byte value from a short", Short.MIN_VALUE, byte.class, Short.valueOf(Short.MIN_VALUE).byteValue()}, @@ -223,6 +228,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, {"Tests that the method returns a byte value from a BigInteger", BigInteger.ZERO, byte.class, BigInteger.ZERO.byteValue()}, {"Tests that the method returns a byte value from a BigDecimal", BigDecimal.ZERO, byte.class, BigDecimal.ZERO.byteValue()}, + {"Tests that the method returns a byte value from a byte[]", TRUE_AS_BYTE_ARRAY, byte.class, TRUE_AS_BYTE}, // char conversion test cases {"Tests that the method returns a char value from a byte", Byte.MIN_VALUE, char.class, (char) Byte.MIN_VALUE}, {"Tests that the method returns a char value from a short", Short.MIN_VALUE, char.class, (char) Short.MIN_VALUE}, @@ -235,6 +241,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a char value from a String", ONE_AS_STRING, char.class, ONE_AS_STRING.charAt(0)}, {"Tests that the method returns a char value from a BigInteger", BigInteger.ZERO, char.class, BIG_INTEGER_ZERO_AS_CHAR}, {"Tests that the method returns a char value from a BigDecimal", BigDecimal.ZERO, char.class, BIG_DECIMAL_ZERO_AS_CHAR}, + {"Tests that the method returns a char value from a byte[]", BYTE_ARRAY, char.class, wrap(BYTE_ARRAY).getChar()}, // double conversion test cases {"Tests that the method returns a double value from a byte", Byte.MIN_VALUE, double.class, Byte.valueOf(Byte.MIN_VALUE).doubleValue()}, {"Tests that the method returns a double value from a short", Short.MIN_VALUE, double.class, Short.valueOf(Short.MIN_VALUE).doubleValue()}, @@ -247,6 +254,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a double value from a String", ONE_AS_STRING, double.class, Double.valueOf(ONE_AS_STRING)}, {"Tests that the method returns a double value from a BigInteger", BigInteger.ZERO, double.class, BigInteger.ZERO.doubleValue()}, {"Tests that the method returns a double value from a BigDecimal", BigDecimal.ZERO, double.class, BigDecimal.ZERO.doubleValue()}, + {"Tests that the method returns a double value from a byte[]", BYTE_ARRAY, double.class, wrap(BYTE_ARRAY).getDouble()}, // float conversion test cases {"Tests that the method returns a float value from a byte", Byte.MIN_VALUE, float.class, Byte.valueOf(Byte.MIN_VALUE).floatValue()}, {"Tests that the method returns a float value from a short", Short.MIN_VALUE, float.class, Short.valueOf(Short.MIN_VALUE).floatValue()}, @@ -259,6 +267,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a float value from a String", ONE_AS_STRING, float.class, Float.valueOf(ONE_AS_STRING)}, {"Tests that the method returns a float value from a BigInteger", BigInteger.ZERO, float.class, BigInteger.ZERO.floatValue()}, {"Tests that the method returns a float value from a BigDecimal", BigDecimal.ZERO, float.class, BigDecimal.ZERO.floatValue()}, + {"Tests that the method returns a float value from a byte[]", BYTE_ARRAY, float.class, wrap(BYTE_ARRAY).getFloat()}, // integer conversion test cases {"Tests that the method returns an int value from a byte", Byte.MIN_VALUE, int.class, Byte.valueOf(Byte.MIN_VALUE).intValue()}, {"Tests that the method returns an int value from a short", Short.MIN_VALUE, int.class, Short.valueOf(Short.MIN_VALUE).intValue()}, @@ -271,6 +280,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.valueOf(ONE_AS_STRING)}, {"Tests that the method returns an int value from a BigInteger", BigInteger.ZERO, int.class, BigInteger.ZERO.intValue()}, {"Tests that the method returns an int value from a BigDecimal", BigDecimal.ZERO, int.class, BigDecimal.ZERO.intValue()}, + {"Tests that the method returns a int value from a byte[]", BYTE_ARRAY, int.class, wrap(BYTE_ARRAY).getInt()}, // long conversion test cases {"Tests that the method returns a long value from a byte", Byte.MIN_VALUE, long.class, Byte.valueOf(Byte.MIN_VALUE).longValue()}, {"Tests that the method returns a long value from a short", Short.MIN_VALUE, long.class, Short.valueOf(Short.MIN_VALUE).longValue()}, @@ -283,6 +293,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a long value from a String", ONE_AS_STRING, long.class, Long.valueOf(ONE_AS_STRING)}, {"Tests that the method returns a long value from a BigInteger", BigInteger.ZERO, long.class, BigInteger.ZERO.longValue()}, {"Tests that the method returns a long value from a BigDecimal", BigDecimal.ZERO, long.class, BigDecimal.ZERO.longValue()}, + {"Tests that the method returns a long value from a byte[]", BYTE_ARRAY, long.class, wrap(BYTE_ARRAY).getLong()}, // short conversion test cases {"Tests that the method returns a short value from a byte", Byte.MIN_VALUE, short.class, Byte.valueOf(Byte.MIN_VALUE).shortValue()}, {"Tests that the method returns a short value from a short", Short.MIN_VALUE, short.class, Short.MIN_VALUE}, @@ -295,6 +306,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a short value from a String", ONE_AS_STRING, short.class, Short.valueOf(ONE_AS_STRING)}, {"Tests that the method returns a short value from a BigInteger", BigInteger.ZERO, short.class, BigInteger.ZERO.shortValue()}, {"Tests that the method returns a short value from a BigDecimal", BigDecimal.ZERO, short.class, BigDecimal.ZERO.shortValue()}, + {"Tests that the method returns a short value from a byte[]", BYTE_ARRAY, short.class, wrap(BYTE_ARRAY).getShort()}, // string conversion test cases {"Tests that the method returns a String value from a byte", Byte.MIN_VALUE, String.class, Byte.valueOf(Byte.MIN_VALUE).toString()}, {"Tests that the method returns a String value from a short", Short.MIN_VALUE, String.class, Short.valueOf(Short.MIN_VALUE).toString()}, @@ -307,6 +319,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a String value from a String", ONE_AS_STRING, String.class, ONE_AS_STRING}, {"Tests that the method returns a String value from a BigInteger", BigInteger.ZERO, String.class, BigInteger.ZERO.toString()}, {"Tests that the method returns a String value from a BigDecimal", BigDecimal.ZERO, String.class, BigDecimal.ZERO.toPlainString()}, + {"Tests that the method returns a String value from a byte[]", TRUE_AS_BYTE_ARRAY, String.class, new String(TRUE_AS_BYTE_ARRAY)}, // BigInteger conversion test cases {"Tests that the method returns a BigInteger value from a byte", Byte.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Byte.valueOf(Byte.MIN_VALUE).longValue())}, {"Tests that the method returns a BigInteger value from a short", Short.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Short.MIN_VALUE)}, @@ -320,6 +333,7 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a BigInteger value from a String", ONE_AS_STRING, BigInteger.class, new BigInteger(ONE_AS_STRING)}, {"Tests that the method returns a BigInteger value from a BigInteger", BigInteger.ZERO, BigInteger.class, BigInteger.ZERO}, {"Tests that the method returns a BigInteger value from a BigDecimal", BigDecimal.ZERO, BigInteger.class, BigDecimal.ZERO.toBigInteger()}, + {"Tests that the method returns a BigInteger value from a byte[]", BYTE_ARRAY, BigInteger.class, BigInteger.valueOf(wrap(BYTE_ARRAY).getLong())}, // BigDecimal conversion test cases {"Tests that the method returns a BigDecimal value from a byte", Byte.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Byte.valueOf(Byte.MIN_VALUE).doubleValue())}, {"Tests that the method returns a BigDecimal value from a short", Short.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Short.MIN_VALUE)}, @@ -332,6 +346,47 @@ private Object[][] dataConvertValueTesting() { {"Tests that the method returns a BigDecimal value from a String", ONE_AS_STRING, BigDecimal.class, new BigDecimal(ONE_AS_STRING)}, {"Tests that the method returns a BigDecimal value from a BigInteger", BigInteger.ZERO, BigDecimal.class, BigDecimal.valueOf(BigInteger.ZERO.intValue())}, {"Tests that the method returns a BigDecimal value from a BigDecimal", BigDecimal.ZERO, BigDecimal.class, BigDecimal.ZERO}, + {"Tests that the method returns a BigDecimal value from a byte[]", BYTE_ARRAY, BigDecimal.class, BigDecimal.valueOf(wrap(BYTE_ARRAY).getDouble())} + }; + } + + /** + * Tests that the method {@code convertValue} returns the expected converted byte[] value. + * @param testCaseDescription the test case description + * @param valueToConvert the value to convert + * @param expectedValue the expected result + * @param the value to convert class type + */ + @Test(dataProvider = "dataConvertByteArrayValueTesting") + public void testConvertByteArrayValueWorksProperly(final String testCaseDescription, final T valueToConvert, final byte[] expectedValue) { + // GIVEN + + // WHEN + byte[] actual = (byte[]) underTest.convertValue(valueToConvert, byte[].class); + + // THEN + assertArrayEquals(expectedValue, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for byte[] type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for byte[] type. + */ + @DataProvider + private Object[][] dataConvertByteArrayValueTesting() { + return new Object[][]{ + {"Tests that the method returns a byte[] value from a byte", Byte.MIN_VALUE, new byte[] {Byte.MIN_VALUE}}, + {"Tests that the method returns a byte[] value from a byte[]", TRUE_AS_BYTE_ARRAY, TRUE_AS_BYTE_ARRAY}, + {"Tests that the method returns a byte[] value from a short", Short.MIN_VALUE, new byte[] {Short.valueOf(Short.MIN_VALUE).byteValue()}}, + {"Tests that the method returns a byte[] value from an Integer", Integer.MIN_VALUE, new byte[] {Integer.valueOf(Integer.MIN_VALUE).byteValue()}}, + {"Tests that the method returns a byte[] value from a Long", Long.MIN_VALUE, new byte[] {Long.valueOf(Long.MIN_VALUE).byteValue()}}, + {"Tests that the method returns a byte[] value from a Float", Float.MIN_VALUE, new byte[] {Float.valueOf(Float.MIN_VALUE).byteValue()}}, + {"Tests that the method returns a byte[] value from a Double", Double.MIN_VALUE, new byte[] {Double.valueOf(Double.MIN_VALUE).byteValue()}}, + {"Tests that the method returns a byte[] value from a char", CHAR_VALUE, new byte[] {(byte) CHAR_VALUE}}, + {"Tests that the method returns a byte[] value from a Boolean", Boolean.TRUE, TRUE_AS_BYTE_ARRAY}, + {"Tests that the method returns a byte[] value from a String", ONE_AS_STRING, ONE_AS_STRING.getBytes()}, + {"Tests that the method returns a byte[] value from a BigInteger", BigInteger.ZERO, new byte[] {BigInteger.ZERO.byteValue()}}, + {"Tests that the method returns a byte[] value from a BigDecimal", BigDecimal.ZERO, new byte[] {BigDecimal.ZERO.byteValue()}} }; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index 9ea7b7d7c..59e85e623 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -36,6 +36,7 @@ import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; +import com.hotels.beans.conversion.processor.impl.ByteArrayConversionProcessor; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; @@ -149,6 +150,8 @@ String.class, boolean.class, new BooleanConversionProcessor().convertString()}, BigDecimal.class, BigInteger.class, new BigIntegerConversionProcessor().convertBigDecimal()}, {"Tests that the method returns a BigDecimalConversionProcessor that converts from String to BigDecimal", String.class, BigDecimal.class, new BigDecimalConversionProcessor().convertString()}, + {"Tests that the method returns a ByteConversionProcessor that converts from String to byte[]", + String.class, byte[].class, new ByteArrayConversionProcessor().convertString()} }; } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index 75948b3b1..ac40b013a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -33,6 +33,7 @@ import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; +import com.hotels.beans.conversion.processor.impl.ByteArrayConversionProcessor; import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; @@ -118,7 +119,8 @@ private Object[][] dataGetConversionProcessorTesting() { {"Tests that the method returns a BooleanConversionProcessor is case the target class is a Boolean", Boolean.class, BooleanConversionProcessor.class}, {"Tests that the method returns a BooleanConversionProcessor is case the target class is a boolean", boolean.class, BooleanConversionProcessor.class}, {"Tests that the method returns a BigIntegerConversionProcessor is case the target class is a BigInteger", BigInteger.class, BigIntegerConversionProcessor.class}, - {"Tests that the method returns a BigDecimalConversionProcessor is case the target class is a BigDecimal", BigDecimal.class, BigDecimalConversionProcessor.class} + {"Tests that the method returns a BigDecimalConversionProcessor is case the target class is a BigDecimal", BigDecimal.class, BigDecimalConversionProcessor.class}, + {"Tests that the method returns a ByteConversionProcessor is case the target class is a byte[]", byte[].class, ByteArrayConversionProcessor.class} }; } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java index 24ab17b17..376718f55 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java @@ -36,4 +36,6 @@ public abstract class AbstractConversionProcessorTest { static final Boolean BOOLEAN_VALUE = Boolean.TRUE; static final String STRING_VALUE = "10"; static final String TRUE_AS_STRING = "true"; + static final byte[] ONE_BYTE_BYTE_ARRAY = new byte[] {1}; + static final byte[] EIGHT_BYTE_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6, 7, 8}; } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java index 262bc9444..ccdb360fd 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.math.BigDecimal.valueOf; +import static java.nio.ByteBuffer.wrap; import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -30,6 +31,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.error.TypeConversionException; + /** * Unit test for {@link BigDecimalConversionProcessor}. */ @@ -60,6 +63,26 @@ public void testConvertByteShouldReturnProperResult() { assertEquals(expected, actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + BigDecimal expected = valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble()); + + // WHEN + BigDecimal actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(expected, actual); + } + + @Test(expectedExceptions = TypeConversionException.class) + public void testConvertByteArrayShouldThrowExceptionIfByteArrayIsTooSmall() { + // GIVEN + + // WHEN + underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + } + @Test public void testConvertShortShouldReturnProperResult() { // GIVEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java index 765320b18..dea03bfb4 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.math.BigInteger.valueOf; +import static java.nio.ByteBuffer.wrap; import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -30,6 +31,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.error.TypeConversionException; + /** * Unit test for {@link BigIntegerConversionProcessor}. */ @@ -60,6 +63,26 @@ public void testConvertByteShouldReturnProperResult() { assertEquals(expected, actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + BigInteger expected = valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getLong()); + + // WHEN + BigInteger actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(expected, actual); + } + + @Test(expectedExceptions = TypeConversionException.class) + public void testConvertByteArrayShouldThrowExceptionIfByteArrayIsTooSmall() { + // GIVEN + + // WHEN + underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + } + @Test public void testConvertShortShouldReturnProperResult() { // GIVEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java index 6df39f506..034214582 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java @@ -76,6 +76,35 @@ private Object[][] byteToBooleanConvertValueTesting() { }; } + /** + * Tests that the method {@code convertByteArray} returns the expected boolean. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "byteArrayToBooleanConvertValueTesting") + public void testConvertByteArrayShouldReturnProperResult(final String testCaseDescription, final byte[] valueToConvert, final boolean expectedResult) { + // GIVEN + + // WHEN + boolean actual = underTest.convertByteArray().apply(valueToConvert); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertByte} returns the expected result. + * @return parameters to be used for testing that the method {@code convertByte} returns the expected result. + */ + @DataProvider + private Object[][] byteArrayToBooleanConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns true if the value is not 0", new byte[] {BYTE_VALUE}, true}, + {"Tests that the method returns false if the value is 0", new byte[] {BYTE_VALUE_ZERO}, false} + }; + } + /** * Tests that the method {@code convertShort} returns the expected boolean. * @param testCaseDescription the test case description diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessorTest.java new file mode 100644 index 000000000..fa1860ba3 --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessorTest.java @@ -0,0 +1,210 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion.processor.impl; + +import static org.junit.Assert.assertArrayEquals; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Unit test for {@link ByteArrayConversionProcessor}. + */ +public class ByteArrayConversionProcessorTest extends AbstractConversionProcessorTest { + private static final byte TRUE_AS_BYTE = 1; + private static final byte FALSE_AS_BYTE = 0; + + /** + * The class to be tested. + */ + @InjectMocks + private ByteArrayConversionProcessor underTest; + + /** + * Initializes mock. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + @Test + public void testConvertByteShouldReturnProperResult() { + // GIVEN + byte[] expected = new byte[] {BYTE_VALUE}; + + // WHEN + byte[] actual = underTest.convertByte().apply(BYTE_VALUE); + + // THEN + assertArrayEquals(expected, actual); + } + + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + + // WHEN + byte[] actual = underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + + // THEN + assertArrayEquals(ONE_BYTE_BYTE_ARRAY, actual); + } + + @Test + public void testConvertShortShouldReturnProperResult() { + // GIVEN + byte[] expected = new byte[] {SHORT_VALUE.byteValue()}; + + // WHEN + byte[] actual = underTest.convertShort().apply(SHORT_VALUE); + + // THEN + assertArrayEquals(expected, actual); + } + + @Test + public void testConvertIntegerShouldReturnProperResult() { + // GIVEN + byte[] expected = new byte[] {INTEGER_VALUE.byteValue()}; + + // WHEN + byte[] actual = underTest.convertInteger().apply(INTEGER_VALUE); + + // THEN + assertArrayEquals(expected, actual); + } + + @Test + public void testConvertLongShouldReturnProperResult() { + // GIVEN + byte[] expected = new byte[] {LONG_VALUE.byteValue()}; + + // WHEN + byte[] actual = underTest.convertLong().apply(LONG_VALUE); + + // THEN + assertArrayEquals(expected, actual); + } + + @Test + public void testConvertFloatShouldReturnProperResult() { + // GIVEN + byte[] expected = new byte[] {FLOAT_VALUE.byteValue()}; + + // WHEN + byte[] actual = underTest.convertFloat().apply(FLOAT_VALUE); + + // THEN + assertArrayEquals(expected, actual); + } + + @Test + public void testConvertDoubleShouldReturnProperResult() { + // GIVEN + byte[] expected = new byte[] {DOUBLE_VALUE.byteValue()}; + + // WHEN + byte[] actual = underTest.convertDouble().apply(DOUBLE_VALUE); + + // THEN + assertArrayEquals(expected, actual); + } + + @Test + public void testConvertCharacterShouldReturnProperResult() { + // GIVEN + byte[] expected = new byte[] {CHAR_VALUE}; + + // WHEN + byte[] actual = underTest.convertCharacter().apply(CHAR_VALUE); + + // THEN + assertArrayEquals(expected, actual); + } + + /** + * Tests that the method {@code convertBoolean} returns the expected byte. + * @param testCaseDescription the test case description + * @param valueToConvert the value to be converted + * @param expectedResult the expected result + */ + @Test(dataProvider = "booleanToByteConvertValueTesting") + public void testConvertBooleanShouldReturnProperResult(final String testCaseDescription, final boolean valueToConvert, final byte[] expectedResult) { + // GIVEN + + // WHEN + byte[] actual = underTest.convertBoolean().apply(valueToConvert); + + // THEN + assertArrayEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + * @return parameters to be used for testing that the method {@code convertBoolean} returns the expected result. + */ + @DataProvider + private Object[][] booleanToByteConvertValueTesting() { + return new Object[][]{ + {"Tests that the method returns {1} if the value is true", BOOLEAN_VALUE, new byte[] {TRUE_AS_BYTE}}, + {"Tests that the method returns {0} if the value is false", Boolean.FALSE, new byte[] {FALSE_AS_BYTE}} + }; + } + + @Test + public void testConvertStringShouldReturnProperResult() { + // GIVEN + byte[] expected = STRING_VALUE.getBytes(); + + // WHEN + byte[] actual = underTest.convertString().apply(STRING_VALUE); + + // THEN + assertArrayEquals(expected, actual); + } + + @Test + public void testConvertBigIntegerShouldReturnProperResult() { + // GIVEN + byte[] expectedValue = new byte[] {BigInteger.ZERO.byteValue()}; + + // WHEN + byte[] actual = underTest.convertBigInteger().apply(BigInteger.ZERO); + + // THEN + assertArrayEquals(expectedValue, actual); + } + + @Test + public void testConvertBigDecimalShouldReturnProperResult() { + // GIVEN + byte[] expectedValue = new byte[] {BigDecimal.ZERO.byteValue()}; + + // WHEN + byte[] actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); + + // THEN + assertArrayEquals(expectedValue, actual); + } +} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java index 8d6f3fedd..8ae0c45fb 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java @@ -61,6 +61,17 @@ public void testConvertByteShouldReturnProperResult() { assertEquals(BYTE_VALUE, actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + + // WHEN + byte actual = underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(ONE_BYTE_BYTE_ARRAY[0], actual); + } + @Test public void testConvertShortShouldReturnProperResult() { // GIVEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java index c9ed9ed2f..2904cd9ee 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java @@ -16,6 +16,8 @@ package com.hotels.beans.conversion.processor.impl; +import static java.nio.ByteBuffer.wrap; + import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -27,6 +29,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.error.TypeConversionException; + /** * Unit test for {@link CharacterConversionProcessor}. */ @@ -59,6 +63,26 @@ public void testConvertByteShouldReturnProperResult() { assertEquals((char) BYTE_VALUE.byteValue(), actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + char expected = wrap(EIGHT_BYTE_BYTE_ARRAY).getChar(); + + // WHEN + char actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(expected, actual); + } + + @Test(expectedExceptions = TypeConversionException.class) + public void testConvertByteArrayShouldThrowExceptionIfByteArrayIsTooSmall() { + // GIVEN + + // WHEN + underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + } + @Test public void testConvertShortShouldReturnProperResult() { // GIVEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java index 912297c92..eff4b5b0b 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.lang.Double.valueOf; +import static java.nio.ByteBuffer.wrap; import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -30,6 +31,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.error.TypeConversionException; + /** * Unit test for {@link DoubleConversionProcessor}. */ @@ -63,6 +66,26 @@ public void testConvertByteShouldReturnProperResult() { assertEquals((Double) BYTE_VALUE.doubleValue(), actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + Double expected = wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble(); + + // WHEN + Double actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(expected, actual); + } + + @Test(expectedExceptions = TypeConversionException.class) + public void testConvertByteArrayShouldThrowExceptionIfByteArrayIsTooSmall() { + // GIVEN + + // WHEN + underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + } + @Test public void testConvertShortShouldReturnProperResult() { // GIVEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java index 686ac8f19..57f161afc 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.lang.Float.valueOf; +import static java.nio.ByteBuffer.wrap; import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -30,6 +31,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.error.TypeConversionException; + /** * Unit test for {@link FloatConversionProcessor}. */ @@ -63,6 +66,26 @@ public void testConvertByteShouldReturnProperResult() { assertEquals((Float) BYTE_VALUE.floatValue(), actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + Float expected = wrap(EIGHT_BYTE_BYTE_ARRAY).getFloat(); + + // WHEN + Float actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(expected, actual); + } + + @Test(expectedExceptions = TypeConversionException.class) + public void testConvertByteArrayShouldThrowExceptionIfByteArrayIsTooSmall() { + // GIVEN + + // WHEN + underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + } + @Test public void testConvertShortShouldReturnProperResult() { // GIVEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java index 3daab02ff..b7eae4b5a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.lang.Integer.valueOf; +import static java.nio.ByteBuffer.wrap; import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -30,6 +31,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.error.TypeConversionException; + /** * Unit test for {@link IntegerConversionProcessor}. */ @@ -62,6 +65,26 @@ public void testConvertByteShouldReturnProperResult() { assertEquals((Integer) BYTE_VALUE.intValue(), actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + Integer expected = wrap(EIGHT_BYTE_BYTE_ARRAY).getInt(); + + // WHEN + Integer actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(expected, actual); + } + + @Test(expectedExceptions = TypeConversionException.class) + public void testConvertByteArrayShouldThrowExceptionIfByteArrayIsTooSmall() { + // GIVEN + + // WHEN + underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + } + @Test public void testConvertShortShouldReturnProperResult() { // GIVEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java index 9b6ffba5d..4e1d554a6 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.lang.Long.valueOf; +import static java.nio.ByteBuffer.wrap; import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -30,6 +31,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.error.TypeConversionException; + /** * Unit test for {@link LongConversionProcessor}. */ @@ -62,6 +65,26 @@ public void testConvertByteShouldReturnProperResult() { assertEquals((Long) BYTE_VALUE.longValue(), actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + Long expected = wrap(EIGHT_BYTE_BYTE_ARRAY).getLong(); + + // WHEN + Long actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(expected, actual); + } + + @Test(expectedExceptions = TypeConversionException.class) + public void testConvertByteArrayShouldThrowExceptionIfByteArrayIsTooSmall() { + // GIVEN + + // WHEN + underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + } + @Test public void testConvertShortShouldReturnProperResult() { // GIVEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java index 3a14ab971..a242f43c2 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java @@ -18,6 +18,7 @@ import static java.lang.Character.getNumericValue; import static java.lang.Short.valueOf; +import static java.nio.ByteBuffer.wrap; import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -30,6 +31,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.error.TypeConversionException; + /** * Unit test for {@link ShortConversionProcessor}. */ @@ -73,6 +76,26 @@ public void testConvertShortShouldReturnProperResult() { assertEquals(SHORT_VALUE, actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + Short expected = wrap(EIGHT_BYTE_BYTE_ARRAY).getShort(); + + // WHEN + Short actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(expected, actual); + } + + @Test(expectedExceptions = TypeConversionException.class) + public void testConvertByteArrayShouldThrowExceptionIfByteArrayIsTooSmall() { + // GIVEN + + // WHEN + underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); + } + @Test public void testConvertIntegerShouldReturnProperResult() { // GIVEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java index 728fc8e23..6f43fde89 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java @@ -57,6 +57,18 @@ public void testConvertByteShouldReturnProperResult() { assertEquals(BYTE_VALUE.toString(), actual); } + @Test + public void testConvertByteArrayShouldReturnProperResult() { + // GIVEN + String expected = new String(EIGHT_BYTE_BYTE_ARRAY); + + // WHEN + String actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); + + // THEN + assertEquals(expected, actual); + } + @Test public void testConvertShortShouldReturnProperResult() { // GIVEN diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index bb918edde..79b21410d 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -49,7 +49,7 @@ The validation works with both the default `javax.constraints` provided by Java Converts a given primitive value into the given primitive type. The supported types, in which an object can be converted (from / to), are: -* `Byte` or `byte` +* `Byte`, `byte` or `byte[]` * `Short` or `short` * `Integer` or `int` * `Long` or `long` From 0f2686e9a87977477fe389ed68486c5fe036eed1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 1 Aug 2019 08:56:42 +0200 Subject: [PATCH 0773/1786] [skip travis] minor: code style improvements --- .../conversion/processor/impl/DoubleConversionProcessor.java | 1 - .../test/java/com/hotels/beans/conversion/ConverterTest.java | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index e3738b67c..b187e3c50 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -17,7 +17,6 @@ package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; -import static java.math.BigDecimal.valueOf; import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 7d73e1f97..49c1cb749 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -350,6 +350,7 @@ private Object[][] dataConvertValueTesting() { }; } + /** * Tests that the method {@code convertValue} returns the expected converted byte[] value. * @param testCaseDescription the test case description @@ -362,7 +363,7 @@ public void testConvertByteArrayValueWorksProperly(final String testCaseDesc // GIVEN // WHEN - byte[] actual = (byte[]) underTest.convertValue(valueToConvert, byte[].class); + byte[] actual = underTest.convertValue(valueToConvert, byte[].class); // THEN assertArrayEquals(expectedValue, actual); From 8ef15f44b268bd15e35ffdc4bb6106960a8cb58a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 1 Aug 2019 12:16:09 +0200 Subject: [PATCH 0774/1786] Conversion test refactoring --- .../conversion/AbstractConversionTest.java | 42 +++ .../beans/conversion/ConverterTest.java | 317 +++++++++--------- .../impl/AbstractConversionProcessorTest.java | 41 --- ...est.java => BigDecimalConversionTest.java} | 3 +- ...est.java => BigIntegerConversionTest.java} | 3 +- ...orTest.java => BooleanConversionTest.java} | 4 +- ...Test.java => ByteArrayConversionTest.java} | 4 +- ...essorTest.java => ByteConversionTest.java} | 4 +- ...Test.java => CharacterConversionTest.java} | 3 +- ...sorTest.java => DoubleConversionTest.java} | 3 +- ...ssorTest.java => FloatConversionTest.java} | 3 +- ...orTest.java => IntegerConversionTest.java} | 3 +- ...essorTest.java => LongConversionTest.java} | 3 +- ...ssorTest.java => ShortConversionTest.java} | 3 +- ...sorTest.java => StringConversionTest.java} | 4 +- 15 files changed, 226 insertions(+), 214 deletions(-) create mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java delete mode 100644 bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{BigDecimalConversionProcessorTest.java => BigDecimalConversionTest.java} (97%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{BigIntegerConversionProcessorTest.java => BigIntegerConversionTest.java} (97%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{BooleanConversionProcessorTest.java => BooleanConversionTest.java} (99%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{ByteArrayConversionProcessorTest.java => ByteArrayConversionTest.java} (97%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{ByteConversionProcessorTest.java => ByteConversionTest.java} (97%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{CharacterConversionProcessorTest.java => CharacterConversionTest.java} (97%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{DoubleConversionProcessorTest.java => DoubleConversionTest.java} (98%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{FloatConversionProcessorTest.java => FloatConversionTest.java} (98%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{IntegerConversionProcessorTest.java => IntegerConversionTest.java} (97%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{LongConversionProcessorTest.java => LongConversionTest.java} (97%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{ShortConversionProcessorTest.java => ShortConversionTest.java} (97%) rename bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/{StringConversionProcessorTest.java => StringConversionTest.java} (97%) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java new file mode 100644 index 000000000..bc2a85f5b --- /dev/null +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.conversion; + +/** + * Abstract class containing all methods/fields common to all Conversion test classes. + */ +public abstract class AbstractConversionTest { + public static final Byte BYTE_VALUE = 10; + public static final Short SHORT_VALUE = 10; + public static final Integer INTEGER_VALUE = 10; + public static final Long LONG_VALUE = 10L; + public static final Float FLOAT_VALUE = 10f; + public static final Double DOUBLE_VALUE = 10d; + public static final char CHAR_VALUE = '1'; + public static final Boolean BOOLEAN_VALUE = Boolean.TRUE; + public static final String STRING_VALUE = "10"; + public static final byte[] ONE_BYTE_BYTE_ARRAY = new byte[] {1}; + public static final byte[] EIGHT_BYTE_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6, 7, 8}; + + protected static final Byte BYTE_VALUE_ZERO = 0; + protected static final Short SHORT_VALUE_ZERO = 0; + protected static final Integer INTEGER_VALUE_ZERO = 0; + protected static final Long LONG_VALUE_ZERO = 0L; + protected static final Float FLOAT_VALUE_ZERO = 0f; + protected static final Double DOUBLE_VALUE_ZERO = 0d; + protected static final String TRUE_AS_STRING = "true"; +} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 49c1cb749..c08262d7c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -51,16 +51,13 @@ /** * Unit test for {@link Converter}. */ -public class ConverterTest { +public class ConverterTest extends AbstractConversionTest { private static final String ONE_AS_STRING = "1"; - private static final char CHAR_VALUE = 'T'; - private static final char CHAR_INT_VALUE = '1'; - private static final byte TRUE_AS_BYTE = 1; + private static final Character TRUE_AS_CHAR_VALUE = 'T'; + private static final Byte TRUE_AS_BYTE = 1; private static final int TRUE_AS_INT = 1; private static final char BIG_DECIMAL_ZERO_AS_CHAR = (char) BigDecimal.ZERO.doubleValue(); private static final char BIG_INTEGER_ZERO_AS_CHAR = (char) BigInteger.ZERO.intValue(); - private static final byte[] TRUE_AS_BYTE_ARRAY = new byte[]{1}; - private static final byte[] BYTE_ARRAY = new byte[]{1, 2, 3, 4, 5, 6, 7, 8}; /** * The class to be tested. @@ -202,155 +199,153 @@ public void testConvertValueWorksProperly(final String testCaseDescription, @DataProvider private Object[][] dataConvertValueTesting() { return new Object[][]{ - {"Tests that the method returns a null value in case the value to convert is null", null, BigInteger.class, null}, - // boolean conversion test cases - {"Tests that the method returns a boolean value from a byte", Byte.MIN_VALUE, boolean.class, Boolean.TRUE}, - {"Tests that the method returns a boolean value from a short", Short.MIN_VALUE, boolean.class, Boolean.TRUE}, - {"Tests that the method returns a boolean value from an Integer", Integer.MIN_VALUE, boolean.class, Boolean.TRUE}, - {"Tests that the method returns a boolean value from a Long", Long.MIN_VALUE, boolean.class, Boolean.TRUE}, - {"Tests that the method returns a boolean value from a Float", Float.MIN_VALUE, boolean.class, Boolean.TRUE}, - {"Tests that the method returns a boolean value from a Double", Double.MIN_VALUE, boolean.class, Boolean.TRUE}, - {"Tests that the method returns a boolean value from a char", CHAR_VALUE, boolean.class, Boolean.TRUE}, - {"Tests that the method returns a boolean value from a Boolean", Boolean.TRUE, boolean.class, Boolean.TRUE}, - {"Tests that the method returns a boolean value from a String", String.valueOf(Boolean.FALSE), boolean.class, Boolean.FALSE}, - {"Tests that the method returns a boolean value from a BigInteger", BigInteger.ZERO, boolean.class, Boolean.FALSE}, - {"Tests that the method returns a boolean value from a BigDecimal", BigDecimal.ZERO, boolean.class, Boolean.FALSE}, - {"Tests that the method returns a boolean value from a byte[]", TRUE_AS_BYTE_ARRAY, boolean.class, Boolean.TRUE}, - // byte conversion test cases - {"Tests that the method returns a byte value from a byte", Byte.MIN_VALUE, byte.class, Byte.MIN_VALUE}, - {"Tests that the method returns a byte value from a short", Short.MIN_VALUE, byte.class, Short.valueOf(Short.MIN_VALUE).byteValue()}, - {"Tests that the method returns a byte value from an Integer", Integer.MIN_VALUE, byte.class, Integer.valueOf(Integer.MIN_VALUE).byteValue()}, - {"Tests that the method returns a byte value from a Long", Long.MIN_VALUE, byte.class, Long.valueOf(Long.MIN_VALUE).byteValue()}, - {"Tests that the method returns a byte value from a Float", Float.MIN_VALUE, byte.class, Float.valueOf(Float.MIN_VALUE).byteValue()}, - {"Tests that the method returns a byte value from a Double", Double.MIN_VALUE, byte.class, Double.valueOf(Double.MIN_VALUE).byteValue()}, - {"Tests that the method returns a byte value from a char", CHAR_VALUE, byte.class, (byte) Character.valueOf(CHAR_VALUE).charValue()}, - {"Tests that the method returns a byte value from a Boolean", Boolean.TRUE, byte.class, TRUE_AS_BYTE}, - {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a byte value from a BigInteger", BigInteger.ZERO, byte.class, BigInteger.ZERO.byteValue()}, - {"Tests that the method returns a byte value from a BigDecimal", BigDecimal.ZERO, byte.class, BigDecimal.ZERO.byteValue()}, - {"Tests that the method returns a byte value from a byte[]", TRUE_AS_BYTE_ARRAY, byte.class, TRUE_AS_BYTE}, - // char conversion test cases - {"Tests that the method returns a char value from a byte", Byte.MIN_VALUE, char.class, (char) Byte.MIN_VALUE}, - {"Tests that the method returns a char value from a short", Short.MIN_VALUE, char.class, (char) Short.MIN_VALUE}, - {"Tests that the method returns a char value from an Integer", Integer.MIN_VALUE, char.class, (char) Integer.MIN_VALUE}, - {"Tests that the method returns a char value from a Long", Long.MIN_VALUE, char.class, (char) Long.MIN_VALUE}, - {"Tests that the method returns a char value from a Float", Float.MIN_VALUE, char.class, (char) Float.MIN_VALUE}, - {"Tests that the method returns a char value from a Double", Double.MIN_VALUE, char.class, (char) Double.MIN_VALUE}, - {"Tests that the method returns a char value from a char", CHAR_VALUE, char.class, CHAR_VALUE}, - {"Tests that the method returns a char value from a Boolean", Boolean.TRUE, char.class, CHAR_VALUE}, - {"Tests that the method returns a char value from a String", ONE_AS_STRING, char.class, ONE_AS_STRING.charAt(0)}, - {"Tests that the method returns a char value from a BigInteger", BigInteger.ZERO, char.class, BIG_INTEGER_ZERO_AS_CHAR}, - {"Tests that the method returns a char value from a BigDecimal", BigDecimal.ZERO, char.class, BIG_DECIMAL_ZERO_AS_CHAR}, - {"Tests that the method returns a char value from a byte[]", BYTE_ARRAY, char.class, wrap(BYTE_ARRAY).getChar()}, - // double conversion test cases - {"Tests that the method returns a double value from a byte", Byte.MIN_VALUE, double.class, Byte.valueOf(Byte.MIN_VALUE).doubleValue()}, - {"Tests that the method returns a double value from a short", Short.MIN_VALUE, double.class, Short.valueOf(Short.MIN_VALUE).doubleValue()}, - {"Tests that the method returns a double value from an Integer", Integer.MIN_VALUE, double.class, Integer.valueOf(Integer.MIN_VALUE).doubleValue()}, - {"Tests that the method returns a double value from a Long", Long.MIN_VALUE, double.class, Long.valueOf(Long.MIN_VALUE).doubleValue()}, - {"Tests that the method returns a double value from a Float", Float.MIN_VALUE, double.class, Float.valueOf(Float.MIN_VALUE).doubleValue()}, - {"Tests that the method returns a double value from a Double", Double.MIN_VALUE, double.class, Double.MIN_VALUE}, - {"Tests that the method returns a double value from a char", CHAR_INT_VALUE, double.class, Double.valueOf(String.valueOf(CHAR_INT_VALUE))}, - {"Tests that the method returns a double value from a Boolean", Boolean.TRUE, double.class, (double) TRUE_AS_INT}, - {"Tests that the method returns a double value from a String", ONE_AS_STRING, double.class, Double.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a double value from a BigInteger", BigInteger.ZERO, double.class, BigInteger.ZERO.doubleValue()}, - {"Tests that the method returns a double value from a BigDecimal", BigDecimal.ZERO, double.class, BigDecimal.ZERO.doubleValue()}, - {"Tests that the method returns a double value from a byte[]", BYTE_ARRAY, double.class, wrap(BYTE_ARRAY).getDouble()}, - // float conversion test cases - {"Tests that the method returns a float value from a byte", Byte.MIN_VALUE, float.class, Byte.valueOf(Byte.MIN_VALUE).floatValue()}, - {"Tests that the method returns a float value from a short", Short.MIN_VALUE, float.class, Short.valueOf(Short.MIN_VALUE).floatValue()}, - {"Tests that the method returns a float value from an Integer", Integer.MIN_VALUE, float.class, Integer.valueOf(Integer.MIN_VALUE).floatValue()}, - {"Tests that the method returns a float value from a Long", Long.MIN_VALUE, float.class, Long.valueOf(Long.MIN_VALUE).floatValue()}, - {"Tests that the method returns a float value from a Float", Float.MIN_VALUE, float.class, Float.MIN_VALUE}, - {"Tests that the method returns a float value from a Double", Double.MIN_VALUE, float.class, Double.valueOf(Double.MIN_VALUE).floatValue()}, - {"Tests that the method returns a float value from a char", CHAR_INT_VALUE, float.class, (float) getNumericValue(CHAR_INT_VALUE)}, - {"Tests that the method returns a float value from a Boolean", Boolean.TRUE, float.class, (float) TRUE_AS_INT}, - {"Tests that the method returns a float value from a String", ONE_AS_STRING, float.class, Float.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a float value from a BigInteger", BigInteger.ZERO, float.class, BigInteger.ZERO.floatValue()}, - {"Tests that the method returns a float value from a BigDecimal", BigDecimal.ZERO, float.class, BigDecimal.ZERO.floatValue()}, - {"Tests that the method returns a float value from a byte[]", BYTE_ARRAY, float.class, wrap(BYTE_ARRAY).getFloat()}, - // integer conversion test cases - {"Tests that the method returns an int value from a byte", Byte.MIN_VALUE, int.class, Byte.valueOf(Byte.MIN_VALUE).intValue()}, - {"Tests that the method returns an int value from a short", Short.MIN_VALUE, int.class, Short.valueOf(Short.MIN_VALUE).intValue()}, - {"Tests that the method returns an int value from an Integer", Integer.MIN_VALUE, int.class, Integer.MIN_VALUE}, - {"Tests that the method returns an int value from a Long", Long.MIN_VALUE, int.class, Long.valueOf(Long.MIN_VALUE).intValue()}, - {"Tests that the method returns an int value from a Float", Float.MIN_VALUE, int.class, Float.valueOf(Float.MIN_VALUE).intValue()}, - {"Tests that the method returns an int value from a Double", Double.MIN_VALUE, int.class, Double.valueOf(Double.MIN_VALUE).intValue()}, - {"Tests that the method returns an int value from a char", CHAR_INT_VALUE, int.class, getNumericValue(CHAR_INT_VALUE)}, - {"Tests that the method returns an int value from a Boolean", Boolean.TRUE, int.class, TRUE_AS_INT}, - {"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns an int value from a BigInteger", BigInteger.ZERO, int.class, BigInteger.ZERO.intValue()}, - {"Tests that the method returns an int value from a BigDecimal", BigDecimal.ZERO, int.class, BigDecimal.ZERO.intValue()}, - {"Tests that the method returns a int value from a byte[]", BYTE_ARRAY, int.class, wrap(BYTE_ARRAY).getInt()}, - // long conversion test cases - {"Tests that the method returns a long value from a byte", Byte.MIN_VALUE, long.class, Byte.valueOf(Byte.MIN_VALUE).longValue()}, - {"Tests that the method returns a long value from a short", Short.MIN_VALUE, long.class, Short.valueOf(Short.MIN_VALUE).longValue()}, - {"Tests that the method returns a long value from an Integer", Integer.MIN_VALUE, long.class, Integer.valueOf(Integer.MIN_VALUE).longValue()}, - {"Tests that the method returns a long value from a Long", Long.MIN_VALUE, long.class, Long.MIN_VALUE}, - {"Tests that the method returns a long value from a Float", Float.MIN_VALUE, long.class, Float.valueOf(Float.MIN_VALUE).longValue()}, - {"Tests that the method returns a long value from a Double", Double.MIN_VALUE, long.class, Double.valueOf(Double.MIN_VALUE).longValue()}, - {"Tests that the method returns a long value from a char", CHAR_INT_VALUE, long.class, (long) getNumericValue(CHAR_INT_VALUE)}, - {"Tests that the method returns a long value from a Boolean", Boolean.TRUE, long.class, (long) TRUE_AS_INT}, - {"Tests that the method returns a long value from a String", ONE_AS_STRING, long.class, Long.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a long value from a BigInteger", BigInteger.ZERO, long.class, BigInteger.ZERO.longValue()}, - {"Tests that the method returns a long value from a BigDecimal", BigDecimal.ZERO, long.class, BigDecimal.ZERO.longValue()}, - {"Tests that the method returns a long value from a byte[]", BYTE_ARRAY, long.class, wrap(BYTE_ARRAY).getLong()}, - // short conversion test cases - {"Tests that the method returns a short value from a byte", Byte.MIN_VALUE, short.class, Byte.valueOf(Byte.MIN_VALUE).shortValue()}, - {"Tests that the method returns a short value from a short", Short.MIN_VALUE, short.class, Short.MIN_VALUE}, - {"Tests that the method returns a short value from an Integer", Integer.MIN_VALUE, short.class, Integer.valueOf(Integer.MIN_VALUE).shortValue()}, - {"Tests that the method returns a short value from a Long", Long.MIN_VALUE, short.class, Long.valueOf(Long.MIN_VALUE).shortValue()}, - {"Tests that the method returns a short value from a Float", Float.MIN_VALUE, short.class, Float.valueOf(Float.MIN_VALUE).shortValue()}, - {"Tests that the method returns a short value from a Double", Double.MIN_VALUE, short.class, Double.valueOf(Double.MIN_VALUE).shortValue()}, - {"Tests that the method returns a short value from a char", CHAR_INT_VALUE, short.class, (short) getNumericValue(CHAR_INT_VALUE)}, - {"Tests that the method returns a short value from a Boolean", Boolean.TRUE, short.class, (short) TRUE_AS_INT}, - {"Tests that the method returns a short value from a String", ONE_AS_STRING, short.class, Short.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a short value from a BigInteger", BigInteger.ZERO, short.class, BigInteger.ZERO.shortValue()}, - {"Tests that the method returns a short value from a BigDecimal", BigDecimal.ZERO, short.class, BigDecimal.ZERO.shortValue()}, - {"Tests that the method returns a short value from a byte[]", BYTE_ARRAY, short.class, wrap(BYTE_ARRAY).getShort()}, - // string conversion test cases - {"Tests that the method returns a String value from a byte", Byte.MIN_VALUE, String.class, Byte.valueOf(Byte.MIN_VALUE).toString()}, - {"Tests that the method returns a String value from a short", Short.MIN_VALUE, String.class, Short.valueOf(Short.MIN_VALUE).toString()}, - {"Tests that the method returns a String value from an Integer", Integer.MIN_VALUE, String.class, String.valueOf(Integer.MIN_VALUE)}, - {"Tests that the method returns a String value from a Long", Long.MIN_VALUE, String.class, String.valueOf(Long.MIN_VALUE)}, - {"Tests that the method returns a String value from a Float", Float.MIN_VALUE, String.class, String.valueOf(Float.MIN_VALUE)}, - {"Tests that the method returns a String value from a Double", Double.MIN_VALUE, String.class, String.valueOf(Double.MIN_VALUE)}, - {"Tests that the method returns a String value from a char", CHAR_INT_VALUE, String.class, String.valueOf(CHAR_INT_VALUE)}, - {"Tests that the method returns a String value from a Boolean", Boolean.TRUE, String.class, String.valueOf(Boolean.TRUE)}, - {"Tests that the method returns a String value from a String", ONE_AS_STRING, String.class, ONE_AS_STRING}, - {"Tests that the method returns a String value from a BigInteger", BigInteger.ZERO, String.class, BigInteger.ZERO.toString()}, - {"Tests that the method returns a String value from a BigDecimal", BigDecimal.ZERO, String.class, BigDecimal.ZERO.toPlainString()}, - {"Tests that the method returns a String value from a byte[]", TRUE_AS_BYTE_ARRAY, String.class, new String(TRUE_AS_BYTE_ARRAY)}, - // BigInteger conversion test cases - {"Tests that the method returns a BigInteger value from a byte", Byte.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Byte.valueOf(Byte.MIN_VALUE).longValue())}, - {"Tests that the method returns a BigInteger value from a short", Short.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Short.MIN_VALUE)}, - {"Tests that the method returns a BigInteger value from an Integer", Integer.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Integer.MIN_VALUE)}, - {"Tests that the method returns a BigInteger value from a Long", Long.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Long.MIN_VALUE)}, - {"Tests that the method returns a BigInteger value from a Float", Float.MIN_VALUE, BigInteger.class, BigInteger.valueOf(Float.valueOf(Float.MIN_VALUE).intValue())}, - {"Tests that the method returns a BigInteger value from a Double", Double.MIN_VALUE, BigInteger.class, - BigInteger.valueOf(Double.valueOf(Double.MIN_VALUE).intValue())}, - {"Tests that the method returns a BigInteger value from a char", CHAR_INT_VALUE, BigInteger.class, BigInteger.valueOf(getNumericValue(CHAR_INT_VALUE))}, - {"Tests that the method returns a BigInteger value from a Boolean", Boolean.TRUE, BigInteger.class, BigInteger.valueOf(TRUE_AS_INT)}, - {"Tests that the method returns a BigInteger value from a String", ONE_AS_STRING, BigInteger.class, new BigInteger(ONE_AS_STRING)}, - {"Tests that the method returns a BigInteger value from a BigInteger", BigInteger.ZERO, BigInteger.class, BigInteger.ZERO}, - {"Tests that the method returns a BigInteger value from a BigDecimal", BigDecimal.ZERO, BigInteger.class, BigDecimal.ZERO.toBigInteger()}, - {"Tests that the method returns a BigInteger value from a byte[]", BYTE_ARRAY, BigInteger.class, BigInteger.valueOf(wrap(BYTE_ARRAY).getLong())}, - // BigDecimal conversion test cases - {"Tests that the method returns a BigDecimal value from a byte", Byte.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Byte.valueOf(Byte.MIN_VALUE).doubleValue())}, - {"Tests that the method returns a BigDecimal value from a short", Short.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Short.MIN_VALUE)}, - {"Tests that the method returns a BigDecimal value from an Integer", Integer.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Integer.MIN_VALUE)}, - {"Tests that the method returns a BigDecimal value from a Long", Long.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Long.MIN_VALUE)}, - {"Tests that the method returns a BigDecimal value from a Float", Float.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Float.MIN_VALUE)}, - {"Tests that the method returns a BigDecimal value from a Double", Double.MIN_VALUE, BigDecimal.class, BigDecimal.valueOf(Double.MIN_VALUE)}, - {"Tests that the method returns a BigDecimal value from a char", CHAR_INT_VALUE, BigDecimal.class, BigDecimal.valueOf(getNumericValue(CHAR_INT_VALUE))}, - {"Tests that the method returns a BigDecimal value from a Boolean", Boolean.TRUE, BigDecimal.class, BigDecimal.valueOf(TRUE_AS_INT)}, - {"Tests that the method returns a BigDecimal value from a String", ONE_AS_STRING, BigDecimal.class, new BigDecimal(ONE_AS_STRING)}, - {"Tests that the method returns a BigDecimal value from a BigInteger", BigInteger.ZERO, BigDecimal.class, BigDecimal.valueOf(BigInteger.ZERO.intValue())}, - {"Tests that the method returns a BigDecimal value from a BigDecimal", BigDecimal.ZERO, BigDecimal.class, BigDecimal.ZERO}, - {"Tests that the method returns a BigDecimal value from a byte[]", BYTE_ARRAY, BigDecimal.class, BigDecimal.valueOf(wrap(BYTE_ARRAY).getDouble())} + {"Tests that the method returns a null value in case the value to convert is null", null, BigInteger.class, null}, + // boolean conversion test cases + {"Tests that the method returns a boolean value from a byte", BYTE_VALUE, boolean.class, BOOLEAN_VALUE}, + {"Tests that the method returns a boolean value from a short", SHORT_VALUE, boolean.class, BOOLEAN_VALUE}, + {"Tests that the method returns a boolean value from an Integer", INTEGER_VALUE, boolean.class, BOOLEAN_VALUE}, + {"Tests that the method returns a boolean value from a Long", LONG_VALUE, boolean.class, BOOLEAN_VALUE}, + {"Tests that the method returns a boolean value from a Float", FLOAT_VALUE, boolean.class, BOOLEAN_VALUE}, + {"Tests that the method returns a boolean value from a Double", DOUBLE_VALUE, boolean.class, BOOLEAN_VALUE}, + {"Tests that the method returns a boolean value from a char", TRUE_AS_CHAR_VALUE, boolean.class, BOOLEAN_VALUE}, + {"Tests that the method returns a boolean value from a Boolean", BOOLEAN_VALUE, boolean.class, BOOLEAN_VALUE}, + {"Tests that the method returns a boolean value from a String", TRUE_AS_STRING, boolean.class, BOOLEAN_VALUE}, + {"Tests that the method returns a boolean value from a BigInteger", BigInteger.ZERO, boolean.class, Boolean.FALSE}, + {"Tests that the method returns a boolean value from a BigDecimal", BigDecimal.ZERO, boolean.class, Boolean.FALSE}, + {"Tests that the method returns a boolean value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, boolean.class, BOOLEAN_VALUE}, + // byte conversion test cases + {"Tests that the method returns a byte value from a byte", BYTE_VALUE, byte.class, BYTE_VALUE}, + {"Tests that the method returns a byte value from a short", SHORT_VALUE, byte.class, SHORT_VALUE.byteValue()}, + {"Tests that the method returns a byte value from an Integer", INTEGER_VALUE, byte.class, INTEGER_VALUE.byteValue()}, + {"Tests that the method returns a byte value from a Long", LONG_VALUE, byte.class, LONG_VALUE.byteValue()}, + {"Tests that the method returns a byte value from a Float", FLOAT_VALUE, byte.class, FLOAT_VALUE.byteValue()}, + {"Tests that the method returns a byte value from a Double", DOUBLE_VALUE, byte.class, DOUBLE_VALUE.byteValue()}, + {"Tests that the method returns a byte value from a char", TRUE_AS_CHAR_VALUE, byte.class, (byte) TRUE_AS_CHAR_VALUE.charValue()}, + {"Tests that the method returns a byte value from a Boolean", BOOLEAN_VALUE, byte.class, TRUE_AS_BYTE}, + {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a byte value from a BigInteger", BigInteger.ZERO, byte.class, BigInteger.ZERO.byteValue()}, + {"Tests that the method returns a byte value from a BigDecimal", BigDecimal.ZERO, byte.class, BigDecimal.ZERO.byteValue()}, + {"Tests that the method returns a byte value from a byte[]", ONE_BYTE_BYTE_ARRAY, byte.class, TRUE_AS_BYTE}, + // char conversion test cases + {"Tests that the method returns a char value from a byte", BYTE_VALUE, char.class, (char) BYTE_VALUE.byteValue()}, + {"Tests that the method returns a char value from a short", SHORT_VALUE, char.class, (char) SHORT_VALUE.byteValue()}, + {"Tests that the method returns a char value from an Integer", INTEGER_VALUE, char.class, (char) INTEGER_VALUE.byteValue()}, + {"Tests that the method returns a char value from a Long", LONG_VALUE, char.class, (char) LONG_VALUE.byteValue()}, + {"Tests that the method returns a char value from a Float", FLOAT_VALUE, char.class, (char) FLOAT_VALUE.byteValue()}, + {"Tests that the method returns a char value from a Double", DOUBLE_VALUE, char.class, (char) DOUBLE_VALUE.byteValue()}, + {"Tests that the method returns a char value from a char", TRUE_AS_CHAR_VALUE, char.class, TRUE_AS_CHAR_VALUE}, + {"Tests that the method returns a char value from a Boolean", BOOLEAN_VALUE, char.class, TRUE_AS_CHAR_VALUE}, + {"Tests that the method returns a char value from a String", ONE_AS_STRING, char.class, ONE_AS_STRING.charAt(0)}, + {"Tests that the method returns a char value from a BigInteger", BigInteger.ZERO, char.class, BIG_INTEGER_ZERO_AS_CHAR}, + {"Tests that the method returns a char value from a BigDecimal", BigDecimal.ZERO, char.class, BIG_DECIMAL_ZERO_AS_CHAR}, + {"Tests that the method returns a char value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, char.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getChar()}, + // double conversion test cases + {"Tests that the method returns a double value from a byte", BYTE_VALUE, double.class, BYTE_VALUE.doubleValue()}, + {"Tests that the method returns a double value from a short", SHORT_VALUE, double.class, SHORT_VALUE.doubleValue()}, + {"Tests that the method returns a double value from an Integer", INTEGER_VALUE, double.class, INTEGER_VALUE.doubleValue()}, + {"Tests that the method returns a double value from a Long", LONG_VALUE, double.class, LONG_VALUE.doubleValue()}, + {"Tests that the method returns a double value from a Float", FLOAT_VALUE, double.class, FLOAT_VALUE.doubleValue()}, + {"Tests that the method returns a double value from a Double", DOUBLE_VALUE, double.class, DOUBLE_VALUE}, + {"Tests that the method returns a double value from a char", CHAR_VALUE, double.class, Double.valueOf(String.valueOf(CHAR_VALUE))}, + {"Tests that the method returns a double value from a Boolean", BOOLEAN_VALUE, double.class, (double) TRUE_AS_INT}, + {"Tests that the method returns a double value from a String", ONE_AS_STRING, double.class, Double.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a double value from a BigInteger", BigInteger.ZERO, double.class, BigInteger.ZERO.doubleValue()}, + {"Tests that the method returns a double value from a BigDecimal", BigDecimal.ZERO, double.class, BigDecimal.ZERO.doubleValue()}, + {"Tests that the method returns a double value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, double.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble()}, + // float conversion test cases + {"Tests that the method returns a float value from a byte", BYTE_VALUE, float.class, BYTE_VALUE.floatValue()}, + {"Tests that the method returns a float value from a short", SHORT_VALUE, float.class, SHORT_VALUE.floatValue()}, + {"Tests that the method returns a float value from an Integer", INTEGER_VALUE, float.class, INTEGER_VALUE.floatValue()}, + {"Tests that the method returns a float value from a Long", LONG_VALUE, float.class, LONG_VALUE.floatValue()}, + {"Tests that the method returns a float value from a Float", FLOAT_VALUE, float.class, FLOAT_VALUE}, + {"Tests that the method returns a float value from a Double", DOUBLE_VALUE, float.class, DOUBLE_VALUE.floatValue()}, + {"Tests that the method returns a float value from a char", CHAR_VALUE, float.class, (float) getNumericValue(CHAR_VALUE)}, + {"Tests that the method returns a float value from a Boolean", BOOLEAN_VALUE, float.class, (float) TRUE_AS_INT}, + {"Tests that the method returns a float value from a String", ONE_AS_STRING, float.class, Float.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a float value from a BigInteger", BigInteger.ZERO, float.class, BigInteger.ZERO.floatValue()}, + {"Tests that the method returns a float value from a BigDecimal", BigDecimal.ZERO, float.class, BigDecimal.ZERO.floatValue()}, + {"Tests that the method returns a float value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, float.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getFloat()}, + // integer conversion test cases + {"Tests that the method returns an int value from a byte", BYTE_VALUE, int.class, BYTE_VALUE.intValue()}, + {"Tests that the method returns an int value from a short", SHORT_VALUE, int.class, SHORT_VALUE.intValue()}, + {"Tests that the method returns an int value from an Integer", INTEGER_VALUE, int.class, INTEGER_VALUE}, + {"Tests that the method returns an int value from a Long", LONG_VALUE, int.class, LONG_VALUE.intValue()}, + {"Tests that the method returns an int value from a Float", FLOAT_VALUE, int.class, FLOAT_VALUE.intValue()}, + {"Tests that the method returns an int value from a Double", DOUBLE_VALUE, int.class, DOUBLE_VALUE.intValue()}, + {"Tests that the method returns an int value from a char", CHAR_VALUE, int.class, getNumericValue(CHAR_VALUE)}, + {"Tests that the method returns an int value from a Boolean", BOOLEAN_VALUE, int.class, TRUE_AS_INT}, + {"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns an int value from a BigInteger", BigInteger.ZERO, int.class, BigInteger.ZERO.intValue()}, + {"Tests that the method returns an int value from a BigDecimal", BigDecimal.ZERO, int.class, BigDecimal.ZERO.intValue()}, + {"Tests that the method returns a int value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, int.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getInt()}, + // long conversion test cases + {"Tests that the method returns a long value from a byte", BYTE_VALUE, long.class, BYTE_VALUE.longValue()}, + {"Tests that the method returns a long value from a short", SHORT_VALUE, long.class, SHORT_VALUE.longValue()}, + {"Tests that the method returns a long value from an Integer", INTEGER_VALUE, long.class, INTEGER_VALUE.longValue()}, + {"Tests that the method returns a long value from a Long", LONG_VALUE, long.class, LONG_VALUE}, + {"Tests that the method returns a long value from a Float", FLOAT_VALUE, long.class, FLOAT_VALUE.longValue()}, + {"Tests that the method returns a long value from a Double", DOUBLE_VALUE, long.class, DOUBLE_VALUE.longValue()}, + {"Tests that the method returns a long value from a char", CHAR_VALUE, long.class, (long) getNumericValue(CHAR_VALUE)}, + {"Tests that the method returns a long value from a Boolean", BOOLEAN_VALUE, long.class, (long) TRUE_AS_INT}, + {"Tests that the method returns a long value from a String", ONE_AS_STRING, long.class, Long.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a long value from a BigInteger", BigInteger.ZERO, long.class, BigInteger.ZERO.longValue()}, + {"Tests that the method returns a long value from a BigDecimal", BigDecimal.ZERO, long.class, BigDecimal.ZERO.longValue()}, + {"Tests that the method returns a long value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, long.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getLong()}, + // short conversion test cases + {"Tests that the method returns a short value from a byte", BYTE_VALUE, short.class, BYTE_VALUE.shortValue()}, + {"Tests that the method returns a short value from a short", SHORT_VALUE, short.class, SHORT_VALUE}, + {"Tests that the method returns a short value from an Integer", INTEGER_VALUE, short.class, INTEGER_VALUE.shortValue()}, + {"Tests that the method returns a short value from a Long", LONG_VALUE, short.class, LONG_VALUE.shortValue()}, + {"Tests that the method returns a short value from a Float", FLOAT_VALUE, short.class, FLOAT_VALUE.shortValue()}, + {"Tests that the method returns a short value from a Double", DOUBLE_VALUE, short.class, DOUBLE_VALUE.shortValue()}, + {"Tests that the method returns a short value from a char", CHAR_VALUE, short.class, (short) getNumericValue(CHAR_VALUE)}, + {"Tests that the method returns a short value from a Boolean", BOOLEAN_VALUE, short.class, (short) TRUE_AS_INT}, + {"Tests that the method returns a short value from a String", ONE_AS_STRING, short.class, Short.valueOf(ONE_AS_STRING)}, + {"Tests that the method returns a short value from a BigInteger", BigInteger.ZERO, short.class, BigInteger.ZERO.shortValue()}, + {"Tests that the method returns a short value from a BigDecimal", BigDecimal.ZERO, short.class, BigDecimal.ZERO.shortValue()}, + {"Tests that the method returns a short value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, short.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getShort()}, + // string conversion test cases + {"Tests that the method returns a String value from a byte", BYTE_VALUE, String.class, BYTE_VALUE.toString()}, + {"Tests that the method returns a String value from a short", SHORT_VALUE, String.class, SHORT_VALUE.toString()}, + {"Tests that the method returns a String value from an Integer", INTEGER_VALUE, String.class, String.valueOf(INTEGER_VALUE)}, + {"Tests that the method returns a String value from a Long", LONG_VALUE, String.class, String.valueOf(LONG_VALUE)}, + {"Tests that the method returns a String value from a Float", FLOAT_VALUE, String.class, String.valueOf(FLOAT_VALUE)}, + {"Tests that the method returns a String value from a Double", DOUBLE_VALUE, String.class, String.valueOf(DOUBLE_VALUE)}, + {"Tests that the method returns a String value from a char", CHAR_VALUE, String.class, String.valueOf(CHAR_VALUE)}, + {"Tests that the method returns a String value from a Boolean", BOOLEAN_VALUE, String.class, String.valueOf(BOOLEAN_VALUE)}, + {"Tests that the method returns a String value from a String", ONE_AS_STRING, String.class, ONE_AS_STRING}, + {"Tests that the method returns a String value from a BigInteger", BigInteger.ZERO, String.class, BigInteger.ZERO.toString()}, + {"Tests that the method returns a String value from a BigDecimal", BigDecimal.ZERO, String.class, BigDecimal.ZERO.toPlainString()}, + {"Tests that the method returns a String value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, String.class, new String(EIGHT_BYTE_BYTE_ARRAY)}, + // BigInteger conversion test cases + {"Tests that the method returns a BigInteger value from a byte", BYTE_VALUE, BigInteger.class, BigInteger.valueOf(BYTE_VALUE.longValue())}, + {"Tests that the method returns a BigInteger value from a short", SHORT_VALUE, BigInteger.class, BigInteger.valueOf(SHORT_VALUE)}, + {"Tests that the method returns a BigInteger value from an Integer", INTEGER_VALUE, BigInteger.class, BigInteger.valueOf(INTEGER_VALUE)}, + {"Tests that the method returns a BigInteger value from a Long", LONG_VALUE, BigInteger.class, BigInteger.valueOf(LONG_VALUE)}, + {"Tests that the method returns a BigInteger value from a Float", FLOAT_VALUE, BigInteger.class, BigInteger.valueOf(FLOAT_VALUE.intValue())}, + {"Tests that the method returns a BigInteger value from a Double", DOUBLE_VALUE, BigInteger.class, BigInteger.valueOf(DOUBLE_VALUE.intValue())}, + {"Tests that the method returns a BigInteger value from a char", CHAR_VALUE, BigInteger.class, BigInteger.valueOf(getNumericValue(CHAR_VALUE))}, + {"Tests that the method returns a BigInteger value from a Boolean", BOOLEAN_VALUE, BigInteger.class, BigInteger.valueOf(TRUE_AS_INT)}, + {"Tests that the method returns a BigInteger value from a String", ONE_AS_STRING, BigInteger.class, new BigInteger(ONE_AS_STRING)}, + {"Tests that the method returns a BigInteger value from a BigInteger", BigInteger.ZERO, BigInteger.class, BigInteger.ZERO}, + {"Tests that the method returns a BigInteger value from a BigDecimal", BigDecimal.ZERO, BigInteger.class, BigDecimal.ZERO.toBigInteger()}, + {"Tests that the method returns a BigInteger value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigInteger.class, BigInteger.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getLong())}, + // BigDecimal conversion test cases + {"Tests that the method returns a BigDecimal value from a byte", BYTE_VALUE, BigDecimal.class, BigDecimal.valueOf(BYTE_VALUE.doubleValue())}, + {"Tests that the method returns a BigDecimal value from a short", SHORT_VALUE, BigDecimal.class, BigDecimal.valueOf(SHORT_VALUE)}, + {"Tests that the method returns a BigDecimal value from an Integer", INTEGER_VALUE, BigDecimal.class, BigDecimal.valueOf(INTEGER_VALUE)}, + {"Tests that the method returns a BigDecimal value from a Long", LONG_VALUE, BigDecimal.class, BigDecimal.valueOf(LONG_VALUE)}, + {"Tests that the method returns a BigDecimal value from a Float", FLOAT_VALUE, BigDecimal.class, BigDecimal.valueOf(FLOAT_VALUE)}, + {"Tests that the method returns a BigDecimal value from a Double", DOUBLE_VALUE, BigDecimal.class, BigDecimal.valueOf(DOUBLE_VALUE)}, + {"Tests that the method returns a BigDecimal value from a char", CHAR_VALUE, BigDecimal.class, BigDecimal.valueOf(getNumericValue(CHAR_VALUE))}, + {"Tests that the method returns a BigDecimal value from a Boolean", BOOLEAN_VALUE, BigDecimal.class, BigDecimal.valueOf(TRUE_AS_INT)}, + {"Tests that the method returns a BigDecimal value from a String", ONE_AS_STRING, BigDecimal.class, new BigDecimal(ONE_AS_STRING)}, + {"Tests that the method returns a BigDecimal value from a BigInteger", BigInteger.ZERO, BigDecimal.class, BigDecimal.valueOf(BigInteger.ZERO.intValue())}, + {"Tests that the method returns a BigDecimal value from a BigDecimal", BigDecimal.ZERO, BigDecimal.class, BigDecimal.ZERO}, + {"Tests that the method returns a BigDecimal value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigDecimal.class, BigDecimal.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble())} }; } - /** * Tests that the method {@code convertValue} returns the expected converted byte[] value. * @param testCaseDescription the test case description @@ -376,15 +371,15 @@ public void testConvertByteArrayValueWorksProperly(final String testCaseDesc @DataProvider private Object[][] dataConvertByteArrayValueTesting() { return new Object[][]{ - {"Tests that the method returns a byte[] value from a byte", Byte.MIN_VALUE, new byte[] {Byte.MIN_VALUE}}, - {"Tests that the method returns a byte[] value from a byte[]", TRUE_AS_BYTE_ARRAY, TRUE_AS_BYTE_ARRAY}, - {"Tests that the method returns a byte[] value from a short", Short.MIN_VALUE, new byte[] {Short.valueOf(Short.MIN_VALUE).byteValue()}}, - {"Tests that the method returns a byte[] value from an Integer", Integer.MIN_VALUE, new byte[] {Integer.valueOf(Integer.MIN_VALUE).byteValue()}}, - {"Tests that the method returns a byte[] value from a Long", Long.MIN_VALUE, new byte[] {Long.valueOf(Long.MIN_VALUE).byteValue()}}, - {"Tests that the method returns a byte[] value from a Float", Float.MIN_VALUE, new byte[] {Float.valueOf(Float.MIN_VALUE).byteValue()}}, - {"Tests that the method returns a byte[] value from a Double", Double.MIN_VALUE, new byte[] {Double.valueOf(Double.MIN_VALUE).byteValue()}}, - {"Tests that the method returns a byte[] value from a char", CHAR_VALUE, new byte[] {(byte) CHAR_VALUE}}, - {"Tests that the method returns a byte[] value from a Boolean", Boolean.TRUE, TRUE_AS_BYTE_ARRAY}, + {"Tests that the method returns a byte[] value from a byte", BYTE_VALUE, new byte[] {BYTE_VALUE}}, + {"Tests that the method returns a byte[] value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, EIGHT_BYTE_BYTE_ARRAY}, + {"Tests that the method returns a byte[] value from a short", SHORT_VALUE, new byte[] {SHORT_VALUE.byteValue()}}, + {"Tests that the method returns a byte[] value from an Integer", INTEGER_VALUE, new byte[] {INTEGER_VALUE.byteValue()}}, + {"Tests that the method returns a byte[] value from a Long", LONG_VALUE, new byte[] {LONG_VALUE.byteValue()}}, + {"Tests that the method returns a byte[] value from a Float", FLOAT_VALUE, new byte[] {FLOAT_VALUE.byteValue()}}, + {"Tests that the method returns a byte[] value from a Double", DOUBLE_VALUE, new byte[] {DOUBLE_VALUE.byteValue()}}, + {"Tests that the method returns a byte[] value from a char", TRUE_AS_CHAR_VALUE, new byte[] {(byte) TRUE_AS_CHAR_VALUE.charValue()}}, + {"Tests that the method returns a byte[] value from a Boolean", BOOLEAN_VALUE, ONE_BYTE_BYTE_ARRAY}, {"Tests that the method returns a byte[] value from a String", ONE_AS_STRING, ONE_AS_STRING.getBytes()}, {"Tests that the method returns a byte[] value from a BigInteger", BigInteger.ZERO, new byte[] {BigInteger.ZERO.byteValue()}}, {"Tests that the method returns a byte[] value from a BigDecimal", BigDecimal.ZERO, new byte[] {BigDecimal.ZERO.byteValue()}} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java deleted file mode 100644 index 376718f55..000000000 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/AbstractConversionProcessorTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.conversion.processor.impl; - -/** - * Abstract class containing all methods/fields common to all Conversion Processor test classes. - */ -public abstract class AbstractConversionProcessorTest { - static final Byte BYTE_VALUE = 10; - static final Byte BYTE_VALUE_ZERO = 0; - static final Short SHORT_VALUE = 10; - static final Short SHORT_VALUE_ZERO = 0; - static final Integer INTEGER_VALUE = 10; - static final Integer INTEGER_VALUE_ZERO = 0; - static final Long LONG_VALUE = 10L; - static final Long LONG_VALUE_ZERO = 0L; - static final Float FLOAT_VALUE = 10f; - static final Float FLOAT_VALUE_ZERO = 0f; - static final Double DOUBLE_VALUE = 10d; - static final Double DOUBLE_VALUE_ZERO = 0d; - static final char CHAR_VALUE = '1'; - static final Boolean BOOLEAN_VALUE = Boolean.TRUE; - static final String STRING_VALUE = "10"; - static final String TRUE_AS_STRING = "true"; - static final byte[] ONE_BYTE_BYTE_ARRAY = new byte[] {1}; - static final byte[] EIGHT_BYTE_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6, 7, 8}; -} diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java index ccdb360fd..2a6962222 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java @@ -31,12 +31,13 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; import com.hotels.beans.conversion.error.TypeConversionException; /** * Unit test for {@link BigDecimalConversionProcessor}. */ -public class BigDecimalConversionProcessorTest extends AbstractConversionProcessorTest { +public class BigDecimalConversionTest extends AbstractConversionTest { /** * The class to be tested. */ diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java index dea03bfb4..bc9dfd24c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java @@ -31,12 +31,13 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; import com.hotels.beans.conversion.error.TypeConversionException; /** * Unit test for {@link BigIntegerConversionProcessor}. */ -public class BigIntegerConversionProcessorTest extends AbstractConversionProcessorTest { +public class BigIntegerConversionTest extends AbstractConversionTest { /** * The class to be tested. */ diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java similarity index 99% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java index 034214582..5367ac88b 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java @@ -29,10 +29,12 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; + /** * Unit test for {@link BooleanConversionProcessor}. */ -public class BooleanConversionProcessorTest extends AbstractConversionProcessorTest { +public class BooleanConversionTest extends AbstractConversionTest { /** * The class to be tested. */ diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java index fa1860ba3..9599d31bd 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java @@ -27,10 +27,12 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; + /** * Unit test for {@link ByteArrayConversionProcessor}. */ -public class ByteArrayConversionProcessorTest extends AbstractConversionProcessorTest { +public class ByteArrayConversionTest extends AbstractConversionTest { private static final byte TRUE_AS_BYTE = 1; private static final byte FALSE_AS_BYTE = 0; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java index 8ae0c45fb..cb9efe8e8 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java @@ -29,10 +29,12 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; + /** * Unit test for {@link ByteConversionProcessor}. */ -public class ByteConversionProcessorTest extends AbstractConversionProcessorTest { +public class ByteConversionTest extends AbstractConversionTest { private static final byte TRUE_AS_BYTE = 1; private static final byte FALSE_AS_BYTE = 0; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java index 2904cd9ee..6fbf5cbaa 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java @@ -29,12 +29,13 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; import com.hotels.beans.conversion.error.TypeConversionException; /** * Unit test for {@link CharacterConversionProcessor}. */ -public class CharacterConversionProcessorTest extends AbstractConversionProcessorTest { +public class CharacterConversionTest extends AbstractConversionTest { private static final char TRUE_AS_CHAR = 'T'; private static final char FALSE_AS_CHAR = 'F'; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java similarity index 98% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index eff4b5b0b..f8ef5ac12 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -31,12 +31,13 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; import com.hotels.beans.conversion.error.TypeConversionException; /** * Unit test for {@link DoubleConversionProcessor}. */ -public class DoubleConversionProcessorTest extends AbstractConversionProcessorTest { +public class DoubleConversionTest extends AbstractConversionTest { private static final double TRUE_AS_DOUBLE = 1d; private static final double FALSE_AS_DOUBLE = 0d; private static final double DELTA = 0.0; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java similarity index 98% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 57f161afc..10ea201ca 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -31,12 +31,13 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; import com.hotels.beans.conversion.error.TypeConversionException; /** * Unit test for {@link FloatConversionProcessor}. */ -public class FloatConversionProcessorTest extends AbstractConversionProcessorTest { +public class FloatConversionTest extends AbstractConversionTest { private static final float TRUE_AS_FLOAT = 1f; private static final float FALSE_AS_FLOAT = 0f; private static final double DELTA = 0.0; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index b7eae4b5a..088535970 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -31,12 +31,13 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; import com.hotels.beans.conversion.error.TypeConversionException; /** * Unit test for {@link IntegerConversionProcessor}. */ -public class IntegerConversionProcessorTest extends AbstractConversionProcessorTest { +public class IntegerConversionTest extends AbstractConversionTest { private static final int TRUE_AS_INT = 1; private static final int FALSE_AS_INT = 0; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java index 4e1d554a6..cb3de5276 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java @@ -31,12 +31,13 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; import com.hotels.beans.conversion.error.TypeConversionException; /** * Unit test for {@link LongConversionProcessor}. */ -public class LongConversionProcessorTest extends AbstractConversionProcessorTest { +public class LongConversionTest extends AbstractConversionTest { private static final long TRUE_AS_LONG = 1L; private static final long FALSE_AS_LONG = 0L; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java index a242f43c2..08fc50368 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java @@ -31,12 +31,13 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; import com.hotels.beans.conversion.error.TypeConversionException; /** * Unit test for {@link ShortConversionProcessor}. */ -public class ShortConversionProcessorTest extends AbstractConversionProcessorTest { +public class ShortConversionTest extends AbstractConversionTest { private static final short TRUE_AS_SHORT = 1; private static final short FALSE_AS_SHORT = 0; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java rename to bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java index 6f43fde89..ce2faa917 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessorTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java @@ -28,10 +28,12 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import com.hotels.beans.conversion.AbstractConversionTest; + /** * Unit test for {@link StringConversionProcessor}. */ -public class StringConversionProcessorTest extends AbstractConversionProcessorTest { +public class StringConversionTest extends AbstractConversionTest { /** * The class to be tested. */ From ce6aa558cd65ebde5d4892d2812555bd2dda2ee3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 4 Aug 2019 06:59:51 +0200 Subject: [PATCH 0775/1786] minor: added javadoc link --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index 47aab19e2..b6dbfc43e 100644 --- a/pom.xml +++ b/pom.xml @@ -591,6 +591,9 @@ maven-javadoc-plugin ${javadoc.skip} + + https://www.javadoc.io/doc/com.hotels.beans/bean-utils-library + From 3552e303e8331019995dddd6c6ec361cc0732399 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 4 Aug 2019 07:02:09 +0200 Subject: [PATCH 0776/1786] removed javadoc link --- pom.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pom.xml b/pom.xml index b6dbfc43e..47aab19e2 100644 --- a/pom.xml +++ b/pom.xml @@ -591,9 +591,6 @@ maven-javadoc-plugin ${javadoc.skip} - - https://www.javadoc.io/doc/com.hotels.beans/bean-utils-library - From 040ad62259152416e8a39ea5f7c728312c728300 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 5 Aug 2019 17:22:49 +0200 Subject: [PATCH 0777/1786] Modified transformation value in order to improve the performances --- .../beans/transformer/TransformerImpl.java | 106 +++++++++--------- .../beans/transformer/TransformerTest.java | 65 ++++------- config/checkstyle/suppression.xml | 5 +- 3 files changed, 79 insertions(+), 97 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 6067c725e..b8878f4ac 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -38,7 +38,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Parameter; -import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -313,8 +312,8 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN return defaultValue(fieldType); } boolean primitiveType = classUtils.isPrimitiveType(fieldType); - List transformerFunction = getTransformerFunction(sourceObj.getClass(), sourceFieldName, targetClass, field, primitiveType, fieldBreadcrumb); - boolean isTransformerFunctionDefined = !transformerFunction.isEmpty(); + FieldTransformer transformerFunction = getTransformerFunction(field, fieldBreadcrumb); + boolean isTransformerFunctionDefined = nonNull(transformerFunction); Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function @@ -327,24 +326,33 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN } else if (primitiveType && settings.isDefaultValueSetEnabled() && !isTransformerFunctionDefined) { fieldValue = defaultValue(fieldType); // assign the default value } - fieldValue = getTransformedValue(transformerFunction, isTransformerFunctionDefined, fieldValue); + fieldValue = getTransformedValue(transformerFunction, fieldValue, sourceObj.getClass(), sourceFieldName, targetClass, field, primitiveType, fieldBreadcrumb); return fieldValue; } /** * Applies all the transformer function associated to the field and returns the results. - * @param transformerFunctions the transformer functions to be applied - * @param isTransformerFunctionDefined indicates whether there are transformed function defined - * @param fieldValue the value on which apply the transformer functions - * @return the transformed value + * If the field type is different and they are primitive a conversion function is automatically applied. + * @param transformerFunction the transformer function defined for the current field + * @param fieldValue the field value + * @param sourceObjectClass the source object class + * @param sourceFieldName the source field name + * @param targetClass the destination object class + * @param field the field on which the transformation should be applied + * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not + * @param breadcrumb The full field path on which the transformation should be applied + * @param the target object type + * @return the transformer function. */ @SuppressWarnings("unchecked") - private Object getTransformedValue(final List transformerFunctions, final boolean isTransformerFunctionDefined, final Object fieldValue) { + private Object getTransformedValue(final FieldTransformer transformerFunction, final Object fieldValue, + final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, final Field field, + final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { Object transformedValue = fieldValue; - if (isTransformerFunctionDefined) { - for (FieldTransformer transformerFunction : transformerFunctions) { - transformedValue = transformerFunction.getTransformedObject(transformedValue); - } + if (transformerFunction != null) { + transformedValue = transformerFunction.getTransformedObject(transformedValue); + } else if (settings.isPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType) { + transformedValue = applyPrimitiveTypeConversion(sourceObjectClass, sourceFieldName, targetClass, field, breadcrumb, transformedValue); } return transformedValue; } @@ -414,6 +422,16 @@ private Class getSourceFieldType(final Class sourceObjectClass, final Stri }); } + /** + * Retrieves the transformer function. + * @param field The field on which the transformation should be applied. + * @param breadcrumb The full field path on which the transformation should be applied. + * @return the transformer function. + */ + private FieldTransformer getTransformerFunction(final Field field, final String breadcrumb) { + return settings.getFieldsTransformers().get(settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb); + } + /** * Retrieves the transformer functions. If the field type is different and they are primitive * a conversion function is automatically added. @@ -421,26 +439,20 @@ private Class getSourceFieldType(final Class sourceObjectClass, final Stri * @param sourceFieldName the source field name * @param targetClass the destination object class * @param field the field on which the transformation should be applied - * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not - * @param breadcrumb The full field path on which the transformation should be applied + * @param fieldTransformerKey the field transformation key + * @param fieldValue the field value * @param the target object type * @return the transformer function. */ - private List getTransformerFunction(final Class sourceObjectClass, final String sourceFieldName, - final Class targetClass, final Field field, final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { - List fieldTransformers = new ArrayList<>(); - String fieldTransformerKey = settings.isFlatFieldNameTransformation() ? field.getName() : breadcrumb; - FieldTransformer fieldTransformer = settings.getFieldsTransformers().get(fieldTransformerKey); - boolean isFieldTransformerDefined = nonNull(fieldTransformer); - FieldTransformer primitiveTypeTransformer = getPrimitiveTypeTransformer(sourceObjectClass, sourceFieldName, targetClass, field, - isDestinationFieldPrimitiveType, fieldTransformerKey, isFieldTransformerDefined); + @SuppressWarnings("unchecked") + private Object applyPrimitiveTypeConversion(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, + final Field field, final String fieldTransformerKey, final Object fieldValue) { + Object transformedValue = fieldValue; + FieldTransformer primitiveTypeTransformer = getPrimitiveTypeTransformer(sourceObjectClass, sourceFieldName, targetClass, field, fieldTransformerKey); if (nonNull(primitiveTypeTransformer)) { - fieldTransformers.add(primitiveTypeTransformer); + transformedValue = primitiveTypeTransformer.getTransformedObject(fieldValue); } - if (isFieldTransformerDefined) { - fieldTransformers.add(fieldTransformer); - } - return fieldTransformers; + return transformedValue; } /** @@ -449,35 +461,25 @@ private List getTransformerFunction(final Class sourceO * @param sourceFieldName the source field name * @param targetClass the destination object class * @param field the field on which the transformation should be applied. - * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @param fieldTransformerKey the field name or the full path to the field to which assign the transformer - * @param isFieldTransformerDefined indicates if there is a transformer defined * @param the target object type * @return the default type transformer function */ private FieldTransformer getPrimitiveTypeTransformer(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, - final Field field, final boolean isDestinationFieldPrimitiveType, final String fieldTransformerKey, final boolean isFieldTransformerDefined) { - FieldTransformer fieldTransformer = null; - if (settings.isPrimitiveTypeConversionEnabled()) { - String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + targetClass.getName() - + "-" + fieldTransformerKey + "-" + isFieldTransformerDefined - + "-" + field.getName(); - fieldTransformer = cacheManager.getFromCache(cacheKey, FieldTransformer.class) - .orElseGet(() -> { - FieldTransformer primitiveTypeTransformer = null; - if (isDestinationFieldPrimitiveType && !isFieldTransformerDefined) { - Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); - if (nonNull(sourceFieldType)) { - primitiveTypeTransformer = conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) - .map(conversionFunction -> new FieldTransformer<>(fieldTransformerKey, conversionFunction)) - .orElse(null); - } - } - cacheManager.cacheObject(cacheKey, primitiveTypeTransformer); - return primitiveTypeTransformer; - }); - } - return fieldTransformer; + final Field field, final String fieldTransformerKey) { + String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + targetClass.getName() + "-" + fieldTransformerKey + "-" + field.getName(); + return cacheManager.getFromCache(cacheKey, FieldTransformer.class) + .orElseGet(() -> { + FieldTransformer primitiveTypeTransformer = null; + Class sourceFieldType = getSourceFieldType(sourceObjectClass, sourceFieldName); + if (nonNull(sourceFieldType)) { + primitiveTypeTransformer = conversionAnalyzer.getConversionFunction(sourceFieldType, field.getType()) + .map(conversionFunction -> new FieldTransformer<>(fieldTransformerKey, conversionFunction)) + .orElse(null); + } + cacheManager.cacheObject(cacheKey, primitiveTypeTransformer); + return primitiveTypeTransformer; + }); } /** diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 5bd24b6c6..cdb9bc01c 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -18,9 +18,7 @@ import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; -import static java.util.Collections.emptyMap; import static java.util.Optional.empty; -import static java.util.Optional.of; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -39,8 +37,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; -import java.util.List; -import java.util.Map; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -70,7 +66,7 @@ public class TransformerTest extends AbstractTransformerTest { private static final String CACHE_MANAGER_FIELD_NAME = "cacheManager"; private static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; - private static final String GET_TRANSFORMER_FUNCTION_METHOD_NAME = "getTransformerFunction"; + private static final String GET_TRANSFORMER_VALUE_METHOD_NAME = "getTransformedValue"; private static final String CONVERSION_ANALYZER_FIELD_NAME = "conversionAnalyzer"; private static final String GET_CONSTRUCTOR_ARGS_VALUES_METHOD_NAME = "getConstructorArgsValues"; @@ -166,6 +162,7 @@ public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() /** * Test that the method: {@code getSourceFieldValue} raises a {@link NullPointerException} in case any of the parameters null. + * @throws Exception uf the invocation fails */ @Test(expectedExceptions = Exception.class) public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() throws Exception { @@ -349,72 +346,52 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception } /** - * Test that the {@code getTransformerFunction} works as expected. + * Test that the {@code getTransformedValue} works as expected. * @param testCaseDescription the test case description * @param fieldName the field name to which the transformer function has to be applied + * @param fieldValue the field value before the transformation + * @param fieldTransformer the field transformer associated to the given field * @param isPrimitiveTypeConversionEnabled indicates if the automatic conversion function is enabled * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not - * @param fieldTransformers the field transformer associated to the given field - * @param sourceFieldType the source field type - * @param expectedFieldTransformerSize the total number of transformation function expected for the given field + * @param expectedValue the expected value after the transformation * @throws Exception if the method invocation fails */ @Test(dataProvider = "dataGetTransformerFunctionTesting") - @SuppressWarnings("unchecked") - public void testGetTransformerFunctionWorksProperly(final String testCaseDescription, final String fieldName, final boolean isPrimitiveTypeConversionEnabled, - final boolean isDestinationFieldPrimitiveType, final Map fieldTransformers, final Class sourceFieldType, final int expectedFieldTransformerSize) + public void testGetTransformedValueWorksProperly(final String testCaseDescription, final String fieldName, final Object fieldValue, final FieldTransformer fieldTransformer, + final boolean isPrimitiveTypeConversionEnabled, final boolean isDestinationFieldPrimitiveType, final Object expectedValue) throws Exception { //GIVEN Field field = mock(Field.class); - CacheManager cacheManager = mock(CacheManager.class); TransformerSettings settings = mock(TransformerSettings.class); - ConversionAnalyzer conversionAnalyzer = mock(ConversionAnalyzer.class); - ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); - - when(cacheManager.getFromCache(anyString(), any())).thenReturn(empty()); - when(settings.isFlatFieldNameTransformation()).thenReturn(false); when(settings.isPrimitiveTypeConversionEnabled()).thenReturn(isPrimitiveTypeConversionEnabled); - when(settings.getFieldsTransformers()).thenReturn(fieldTransformers); - when(conversionAnalyzer.getConversionFunction(any(Class.class), any(Class.class))).thenReturn(of(Object::toString)); - when(field.getName()).thenReturn(fieldName); - when(field.getType()).thenReturn(sourceFieldType); - when(reflectionUtils.getDeclaredFieldType(fieldName, FromFooSimple.class)).thenReturn(sourceFieldType); - - setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); setField(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); - setField(underTest, CONVERSION_ANALYZER_FIELD_NAME, conversionAnalyzer); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); - Method getTransformerFunctionMethod = underTest.getClass() - .getDeclaredMethod(GET_TRANSFORMER_FUNCTION_METHOD_NAME, Class.class, String.class, Class.class, Field.class, boolean.class, String.class); + Class[] transformedValueMethodParams = {FieldTransformer.class, Object.class, Class.class, String.class, Class.class, Field.class, boolean.class, String.class}; + Method getTransformerFunctionMethod = underTest.getClass().getDeclaredMethod(GET_TRANSFORMER_VALUE_METHOD_NAME, transformedValueMethodParams); getTransformerFunctionMethod.setAccessible(true); //WHEN - List actual = (List) - getTransformerFunctionMethod.invoke(underTest, FromFooSimple.class, fieldName, MutableToFooSimple.class, field, isDestinationFieldPrimitiveType, fieldName); + Object actual = getTransformerFunctionMethod + .invoke(underTest, fieldTransformer, fieldValue, FromFooSimple.class, fieldName, MutableToFooSimple.class, field, isDestinationFieldPrimitiveType, fieldName); //THEN - assertEquals(expectedFieldTransformerSize, actual.size()); + assertEquals(expectedValue, actual); restoreUnderTestObject(); } /** - * Creates the parameters to be used for testing method {@code getTransformerFunction}. - * @return parameters to be used for testing method {@code getTransformerFunction}. + * Creates the parameters to be used for testing method {@code getTransformedValue}. + * @return parameters to be used for testing method {@code getTransformedValue}. */ @DataProvider private Object[][] dataGetTransformerFunctionTesting() { return new Object[][] { - {"Test that a type conversion function is added to the existing one if all the conditions are met", - AGE_FIELD_NAME, true, true, emptyMap(), int.class, ONE.intValue()}, - {"Test that no type conversion function is added to the existing one if the source type field is null", - AGE_FIELD_NAME, true, true, emptyMap(), null, ZERO.intValue()}, - {"Test that no conversion function is added to the existing one if the primitive type conversion is disabled", - AGE_FIELD_NAME, false, true, emptyMap(), null, ZERO.intValue()}, - {"Test that no conversion function is added to the existing one if the destination field type is not primitive", - AGE_FIELD_NAME, true, false, emptyMap(), null, ZERO.intValue()}, - {"Test that no conversion function is added to the existing one if there is a field transformer function defined for the existing field", - AGE_FIELD_NAME, true, true, Map.of(AGE_FIELD_NAME, new FieldTransformer<>(AGE_FIELD_NAME, () -> null)), null, ONE.intValue()} + {"Test that the primitive type conversion function is not executed if the primitive type conversion is disabled", + AGE_FIELD_NAME, ZERO.intValue(), null, false, true, ZERO.intValue()}, + {"Test that the primitive type conversion function is not executed if the destination field type is not primitive", + AGE_FIELD_NAME, null, null, true, false, null}, + {"Test that the primitive type conversion function is not executed if a field transformer is defined for the given field", + AGE_FIELD_NAME, ZERO.intValue(), new FieldTransformer<>(AGE_FIELD_NAME, ONE::intValue), true, true, ONE.intValue()} }; } diff --git a/config/checkstyle/suppression.xml b/config/checkstyle/suppression.xml index cc863da25..fdb7b4bd8 100644 --- a/config/checkstyle/suppression.xml +++ b/config/checkstyle/suppression.xml @@ -10,7 +10,10 @@ files=".*[\\/]src[\\/](test|it)[\\/]|.*Test.java"/> - + + + + From 10edede49641ea1131b7f19b7fe95751e48396aa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 5 Aug 2019 17:59:34 +0200 Subject: [PATCH 0778/1786] Code style improvements --- .../beans/transformer/TransformerImpl.java | 22 +++++-------- .../beans/populator/PopulatorFactoryTest.java | 31 ++++++++++--------- .../beans/transformer/TransformerTest.java | 5 ++- .../beans/utils/ReflectionUtilsTest.java | 1 - config/checkstyle/suppression.xml | 6 ---- 5 files changed, 26 insertions(+), 39 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index b8878f4ac..8a909acc2 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -326,7 +326,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN } else if (primitiveType && settings.isDefaultValueSetEnabled() && !isTransformerFunctionDefined) { fieldValue = defaultValue(fieldType); // assign the default value } - fieldValue = getTransformedValue(transformerFunction, fieldValue, sourceObj.getClass(), sourceFieldName, targetClass, field, primitiveType, fieldBreadcrumb); + fieldValue = getTransformedValue(transformerFunction, fieldValue, sourceObj.getClass(), sourceFieldName, field, primitiveType, fieldBreadcrumb); return fieldValue; } @@ -337,22 +337,20 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN * @param fieldValue the field value * @param sourceObjectClass the source object class * @param sourceFieldName the source field name - * @param targetClass the destination object class * @param field the field on which the transformation should be applied * @param isDestinationFieldPrimitiveType indicates if the destination field type is primitive or not * @param breadcrumb The full field path on which the transformation should be applied - * @param the target object type * @return the transformer function. */ @SuppressWarnings("unchecked") - private Object getTransformedValue(final FieldTransformer transformerFunction, final Object fieldValue, - final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, final Field field, + private Object getTransformedValue(final FieldTransformer transformerFunction, final Object fieldValue, + final Class sourceObjectClass, final String sourceFieldName, final Field field, final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { Object transformedValue = fieldValue; if (transformerFunction != null) { transformedValue = transformerFunction.getTransformedObject(transformedValue); } else if (settings.isPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType) { - transformedValue = applyPrimitiveTypeConversion(sourceObjectClass, sourceFieldName, targetClass, field, breadcrumb, transformedValue); + transformedValue = applyPrimitiveTypeConversion(sourceObjectClass, sourceFieldName, field, breadcrumb, transformedValue); } return transformedValue; } @@ -437,18 +435,16 @@ private FieldTransformer getTransformerFunction(final Field field, final String * a conversion function is automatically added. * @param sourceObjectClass the source object class * @param sourceFieldName the source field name - * @param targetClass the destination object class * @param field the field on which the transformation should be applied * @param fieldTransformerKey the field transformation key * @param fieldValue the field value - * @param the target object type * @return the transformer function. */ @SuppressWarnings("unchecked") - private Object applyPrimitiveTypeConversion(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, + private Object applyPrimitiveTypeConversion(final Class sourceObjectClass, final String sourceFieldName, final Field field, final String fieldTransformerKey, final Object fieldValue) { Object transformedValue = fieldValue; - FieldTransformer primitiveTypeTransformer = getPrimitiveTypeTransformer(sourceObjectClass, sourceFieldName, targetClass, field, fieldTransformerKey); + FieldTransformer primitiveTypeTransformer = getPrimitiveTypeTransformer(sourceObjectClass, sourceFieldName, field, fieldTransformerKey); if (nonNull(primitiveTypeTransformer)) { transformedValue = primitiveTypeTransformer.getTransformedObject(fieldValue); } @@ -459,15 +455,13 @@ private Object applyPrimitiveTypeConversion(final Class sourceObjectClass * Verifies if a default type transformer function is required and in case returns it. * @param sourceObjectClass the source object class * @param sourceFieldName the source field name - * @param targetClass the destination object class * @param field the field on which the transformation should be applied. * @param fieldTransformerKey the field name or the full path to the field to which assign the transformer - * @param the target object type * @return the default type transformer function */ - private FieldTransformer getPrimitiveTypeTransformer(final Class sourceObjectClass, final String sourceFieldName, final Class targetClass, + private FieldTransformer getPrimitiveTypeTransformer(final Class sourceObjectClass, final String sourceFieldName, final Field field, final String fieldTransformerKey) { - String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + targetClass.getName() + "-" + fieldTransformerKey + "-" + field.getName(); + String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + field.getDeclaringClass().getName() + "-" + fieldTransformerKey + "-" + field.getName(); return cacheManager.getFromCache(cacheKey, FieldTransformer.class) .orElseGet(() -> { FieldTransformer primitiveTypeTransformer = null; diff --git a/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index cfedbce45..58656c3dd 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -58,12 +58,28 @@ public void beforeClass() { initMocks(this); } + /** + * Data provider for the required test cases. + * @return the test cases. + */ + @DataProvider + public Object[][] dataProvider() { + return new Object[][]{ + {String[].class, ArrayPopulator.class}, + {List.class, CollectionPopulator.class}, + {Map.class, MapPopulator.class}, + {FromFoo.class, null}, + {Optional.class, OptionalPopulator.class} + }; + } + /** * Tests that the method: {@code defaultValue} returns the expected result for the given type. * @param type the type for which a populator needs to be found * @param expectedResult the expected populator */ @Test(dataProvider = "dataProvider") + @SuppressWarnings("unchecked") public void testGetPopulatorReturnsTheExpectedResult(final Class type, final Class expectedResult) { // GIVEN @@ -77,19 +93,4 @@ public void testGetPopulatorReturnsTheExpectedResult(final Class type, final Cla assertEquals(expectedResult, populator.get().getClass()); } } - - /** - * Data provider for the required test cases. - * @return the test cases. - */ - @DataProvider - public Object[][] dataProvider() { - return new Object[][]{ - {String[].class, ArrayPopulator.class}, - {List.class, CollectionPopulator.class}, - {Map.class, MapPopulator.class}, - {FromFoo.class, null}, - {Optional.class, OptionalPopulator.class} - }; - } } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index cdb9bc01c..66ee1ae04 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -49,7 +49,6 @@ import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.mutable.MutableToFooAdvFields; -import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.utils.ClassUtils; import com.hotels.beans.utils.ReflectionUtils; @@ -366,13 +365,13 @@ public void testGetTransformedValueWorksProperly(final String testCaseDescriptio when(settings.isPrimitiveTypeConversionEnabled()).thenReturn(isPrimitiveTypeConversionEnabled); setField(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); - Class[] transformedValueMethodParams = {FieldTransformer.class, Object.class, Class.class, String.class, Class.class, Field.class, boolean.class, String.class}; + Class[] transformedValueMethodParams = {FieldTransformer.class, Object.class, Class.class, String.class, Field.class, boolean.class, String.class}; Method getTransformerFunctionMethod = underTest.getClass().getDeclaredMethod(GET_TRANSFORMER_VALUE_METHOD_NAME, transformedValueMethodParams); getTransformerFunctionMethod.setAccessible(true); //WHEN Object actual = getTransformerFunctionMethod - .invoke(underTest, fieldTransformer, fieldValue, FromFooSimple.class, fieldName, MutableToFooSimple.class, field, isDestinationFieldPrimitiveType, fieldName); + .invoke(underTest, fieldTransformer, fieldValue, FromFooSimple.class, fieldName, field, isDestinationFieldPrimitiveType, fieldName); //THEN assertEquals(expectedValue, actual); diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java index a6c158edd..bb8d60dc8 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java @@ -312,7 +312,6 @@ private Object[][] dataGetGetterMethodPrefixTesting() throws Exception { * @param testCaseDescription the test case description * @param annotationToGet the annotation to retrieve * @param expectNull true if it's expected to find it null, false otherwise - * @throws NoSuchFieldException if the field does not exists. */ @Test(dataProvider = "dataGetFieldAnnotationTesting") public void testGetFieldAnnotationWorksProperly(final String testCaseDescription, final Class annotationToGet, diff --git a/config/checkstyle/suppression.xml b/config/checkstyle/suppression.xml index fdb7b4bd8..5aa9cea07 100644 --- a/config/checkstyle/suppression.xml +++ b/config/checkstyle/suppression.xml @@ -9,12 +9,6 @@ - - - - - - From d5390b905503a066990f43345d4fda1a08287d36 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 6 Aug 2019 09:24:30 +0200 Subject: [PATCH 0779/1786] Enabled primitive type transformation also if a field transformer function is defined --- README.md | 3 +++ .../transformer/AbstractTransformer.java | 2 ++ .../beans/transformer/TransformerImpl.java | 5 ++-- .../transformer/AbstractTransformerTest.java | 2 +- .../MutableObjectTransformationTest.java | 24 +++++++++++++++++++ .../beans/transformer/TransformerTest.java | 5 +--- docs/site/markdown/converter/samples.md | 3 +++ 7 files changed, 37 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 98396c557..a0e86def5 100644 --- a/README.md +++ b/README.md @@ -559,6 +559,9 @@ Transformer transformer = beanUtils.getTransformer() ToBean toBean = transformer.transform(fromBean, ToBean.class); ~~~ +**IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function defined on a specific field. +This means that the once the `FieldTransformer` function will be executed the field value has already been transformed. + ## Constraints: * the class's fields that have to be copied must not be static diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 0a8bd37fe..9f3ac935c 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -194,6 +194,8 @@ public Transformer setPrimitiveTypeConversionEnabled(final boolean primitiveType settings.setPrimitiveTypeConversionEnabled(primitiveTypeConversionEnabled); if (primitiveTypeConversionEnabled) { conversionAnalyzer = new ConversionAnalyzer(); + } else { + cacheManager.removeMatchingKeys(TRANSFORMER_FUNCTION_REGEX); } return this; } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 8a909acc2..15c98bf1f 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -347,10 +347,11 @@ private Object getTransformedValue(final FieldTransformer transformerFunction, f final Class sourceObjectClass, final String sourceFieldName, final Field field, final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { Object transformedValue = fieldValue; + if (settings.isPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType) { + transformedValue = applyPrimitiveTypeConversion(sourceObjectClass, sourceFieldName, field, breadcrumb, transformedValue); + } if (transformerFunction != null) { transformedValue = transformerFunction.getTransformedObject(transformedValue); - } else if (settings.isPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType) { - transformedValue = applyPrimitiveTypeConversion(sourceObjectClass, sourceFieldName, field, breadcrumb, transformedValue); } return transformedValue; } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index dce9ccb91..c5f376ed5 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -69,6 +69,7 @@ public abstract class AbstractTransformerTest { static final String PHONE_NUMBER_DEST_FIELD_NAME = "phoneNumbers"; static final String PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME = "nestedObject.phoneNumbers"; static final String NAME_FIELD_NAME = "name"; + static final float PRICE = 10.0f; private static final String ITEM_1 = "donald"; private static final String ITEM_2 = "duck"; @@ -80,7 +81,6 @@ public abstract class AbstractTransformerTest { private static final BigDecimal AMOUNT = new BigDecimal(10); private static final String SUB_FOO_NAME = "Smith"; private static final int[] SUB_FOO_PHONE_NUMBERS = {12345, 6892, 10873}; - private static final float PRICE = 10.0f; private static final Map SAMPLE_MAP = new HashMap<>(); private static final Map> COMPLEX_MAP = new HashMap<>(); private static final Map> VERY_COMPLEX_MAP = new HashMap<>(); diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index c4f64c8c9..82833cb1d 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -48,6 +48,7 @@ */ public class MutableObjectTransformationTest extends AbstractTransformerTest { private static final boolean ACTIVE = true; + private static final String PRICE_FIELD_NAME = "price"; /** * Test that an exception is thrown if there is no default constructor defined for the mutable bean object. @@ -329,4 +330,27 @@ public void testAutomaticPrimitiveTypeTransformationWorksProperly() { assertEquals(ACTIVE, actual.isActive()); underTest.setPrimitiveTypeConversionEnabled(false); } + + /** + * Test that both primitive type transformation and custom transformation are executed. + */ + @Test + public void testThatBothPrimitiveTypeTransformationAndCustomTransformationAreExecuted() { + //GIVEN + double delta = 0d; + double newPrice = PRICE * PRICE; + FieldTransformer priceTransformer = new FieldTransformer<>(PRICE_FIELD_NAME, () -> newPrice); + underTest.setPrimitiveTypeConversionEnabled(true).withFieldTransformer(priceTransformer); + + //WHEN + MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); + + //THEN + assertEquals(parseInt(fromFooPrimitiveTypes.getCode()), actual.getCode()); + assertEquals(String.valueOf(fromFooPrimitiveTypes.getId()), actual.getId()); + assertEquals(newPrice, actual.getPrice(), delta); + assertEquals(ACTIVE, actual.isActive()); + underTest.setPrimitiveTypeConversionEnabled(false); + underTest.removeFieldTransformer(PRICE_FIELD_NAME); + } } diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java index 66ee1ae04..8d1666689 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java @@ -66,7 +66,6 @@ public class TransformerTest extends AbstractTransformerTest { private static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; private static final String GET_TRANSFORMER_VALUE_METHOD_NAME = "getTransformedValue"; - private static final String CONVERSION_ANALYZER_FIELD_NAME = "conversionAnalyzer"; private static final String GET_CONSTRUCTOR_ARGS_VALUES_METHOD_NAME = "getConstructorArgsValues"; /** @@ -388,9 +387,7 @@ private Object[][] dataGetTransformerFunctionTesting() { {"Test that the primitive type conversion function is not executed if the primitive type conversion is disabled", AGE_FIELD_NAME, ZERO.intValue(), null, false, true, ZERO.intValue()}, {"Test that the primitive type conversion function is not executed if the destination field type is not primitive", - AGE_FIELD_NAME, null, null, true, false, null}, - {"Test that the primitive type conversion function is not executed if a field transformer is defined for the given field", - AGE_FIELD_NAME, ZERO.intValue(), new FieldTransformer<>(AGE_FIELD_NAME, ONE::intValue), true, true, ONE.intValue()} + AGE_FIELD_NAME, null, null, true, false, null} }; } diff --git a/docs/site/markdown/converter/samples.md b/docs/site/markdown/converter/samples.md index 17d95fd42..5c5bfdff1 100644 --- a/docs/site/markdown/converter/samples.md +++ b/docs/site/markdown/converter/samples.md @@ -38,3 +38,6 @@ byte converted = conversionFunction.map(processor -> processor.apply(c)).orElse( * in case the conversion is not needed as the primitive type and the destination type are the same it will return an empty `Optional` * in case the conversion function is unavailable or no not possible the method throws a : `TypeConversionException` + +**IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function defined on a specific field. +This means that the once the `FieldTransformer` function will be executed the field value has already been transformed. \ No newline at end of file From 42dc0ad238d0e04aa87bc45f257800d7fa70cdcb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 6 Aug 2019 09:42:28 +0200 Subject: [PATCH 0780/1786] [skip travis] preparing release --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index cab804416..2e5fca8eb 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.1.23] TBD +### [1.1.23] 2019.08.06 #### Added * Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index 26038f395..134444600 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.5.0] TBD +### [1.5.0] 2019.08.06 #### Added * Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). #### Changed From 7cae71a67c776bf4c637c87f392c3df301dbb424 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 6 Aug 2019 10:53:18 +0200 Subject: [PATCH 0781/1786] [maven-release-plugin] prepare release 1.5.0 --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 6 ++---- pom.xml | 4 ++-- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index e0676efd9..2a4cae7da 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.0-SNAPSHOT + 1.5.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index dea4759a0..d23c5e278 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.0-SNAPSHOT + 1.5.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 2fdc20410..d34942a9d 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 BULL - Converter bull-converter @@ -11,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.0-SNAPSHOT + 1.5.0 diff --git a/pom.xml b/pom.xml index 47aab19e2..c168ab43d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.5.0-SNAPSHOT + 1.5.0 pom 2019 @@ -69,7 +69,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.5.0 From 9ce73d74cc1bdb045210f678cbc008e1fbaaf494 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 6 Aug 2019 10:53:26 +0200 Subject: [PATCH 0782/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- pom.xml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 2a4cae7da..7cc0f7388 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.0 + 1.5.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index d23c5e278..ca641935d 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.0 + 1.5.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index d34942a9d..b9907caad 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.0 + 1.5.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index c168ab43d..537f2fe16 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.5.0 + 1.5.1-SNAPSHOT pom 2019 @@ -69,7 +69,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.5.0 + HEAD From e84993c554b7752c66b3c5d50f0297f202914506 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2019 02:42:01 +0000 Subject: [PATCH 0783/1786] Bump slf4j-api from 1.7.26 to 1.7.27 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.26 to 1.7.27. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.26...v_1.7.27) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 537f2fe16..052d15229 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 2.0.1.Final 6.0.17.Final - 1.7.26 + 1.7.27 3.0.0 2.2.6 From 66d2429536f202af2213b04daf07c381516fa6c2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2019 02:42:25 +0000 Subject: [PATCH 0784/1786] Bump spring-boot-starter-test from 2.1.6.RELEASE to 2.1.7.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.1.6.RELEASE to 2.1.7.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.1.6.RELEASE...v2.1.7.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 537f2fe16..5d3e7693c 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ 11 ${jdk.version} ${jdk.version} - 2.1.6.RELEASE + 2.1.7.RELEASE 1.18.8 3.9 0.11 From 6b27486d8c47386610d7b174975f1331fe87cf94 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 7 Aug 2019 22:50:08 +0200 Subject: [PATCH 0785/1786] [skip travis] started splitting data provider for testing method convertValue --- .../beans/conversion/ConverterTest.java | 302 +++++++++--------- 1 file changed, 155 insertions(+), 147 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index c08262d7c..148075391 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -28,6 +28,10 @@ import java.math.BigDecimal; import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; import java.util.Optional; import java.util.function.Function; @@ -197,153 +201,157 @@ public void testConvertValueWorksProperly(final String testCaseDescription, * @return parameters to be used for testing that the method {@code convertValue} returns the expected result. */ @DataProvider - private Object[][] dataConvertValueTesting() { - return new Object[][]{ - {"Tests that the method returns a null value in case the value to convert is null", null, BigInteger.class, null}, - // boolean conversion test cases - {"Tests that the method returns a boolean value from a byte", BYTE_VALUE, boolean.class, BOOLEAN_VALUE}, - {"Tests that the method returns a boolean value from a short", SHORT_VALUE, boolean.class, BOOLEAN_VALUE}, - {"Tests that the method returns a boolean value from an Integer", INTEGER_VALUE, boolean.class, BOOLEAN_VALUE}, - {"Tests that the method returns a boolean value from a Long", LONG_VALUE, boolean.class, BOOLEAN_VALUE}, - {"Tests that the method returns a boolean value from a Float", FLOAT_VALUE, boolean.class, BOOLEAN_VALUE}, - {"Tests that the method returns a boolean value from a Double", DOUBLE_VALUE, boolean.class, BOOLEAN_VALUE}, - {"Tests that the method returns a boolean value from a char", TRUE_AS_CHAR_VALUE, boolean.class, BOOLEAN_VALUE}, - {"Tests that the method returns a boolean value from a Boolean", BOOLEAN_VALUE, boolean.class, BOOLEAN_VALUE}, - {"Tests that the method returns a boolean value from a String", TRUE_AS_STRING, boolean.class, BOOLEAN_VALUE}, - {"Tests that the method returns a boolean value from a BigInteger", BigInteger.ZERO, boolean.class, Boolean.FALSE}, - {"Tests that the method returns a boolean value from a BigDecimal", BigDecimal.ZERO, boolean.class, Boolean.FALSE}, - {"Tests that the method returns a boolean value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, boolean.class, BOOLEAN_VALUE}, - // byte conversion test cases - {"Tests that the method returns a byte value from a byte", BYTE_VALUE, byte.class, BYTE_VALUE}, - {"Tests that the method returns a byte value from a short", SHORT_VALUE, byte.class, SHORT_VALUE.byteValue()}, - {"Tests that the method returns a byte value from an Integer", INTEGER_VALUE, byte.class, INTEGER_VALUE.byteValue()}, - {"Tests that the method returns a byte value from a Long", LONG_VALUE, byte.class, LONG_VALUE.byteValue()}, - {"Tests that the method returns a byte value from a Float", FLOAT_VALUE, byte.class, FLOAT_VALUE.byteValue()}, - {"Tests that the method returns a byte value from a Double", DOUBLE_VALUE, byte.class, DOUBLE_VALUE.byteValue()}, - {"Tests that the method returns a byte value from a char", TRUE_AS_CHAR_VALUE, byte.class, (byte) TRUE_AS_CHAR_VALUE.charValue()}, - {"Tests that the method returns a byte value from a Boolean", BOOLEAN_VALUE, byte.class, TRUE_AS_BYTE}, - {"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a byte value from a BigInteger", BigInteger.ZERO, byte.class, BigInteger.ZERO.byteValue()}, - {"Tests that the method returns a byte value from a BigDecimal", BigDecimal.ZERO, byte.class, BigDecimal.ZERO.byteValue()}, - {"Tests that the method returns a byte value from a byte[]", ONE_BYTE_BYTE_ARRAY, byte.class, TRUE_AS_BYTE}, - // char conversion test cases - {"Tests that the method returns a char value from a byte", BYTE_VALUE, char.class, (char) BYTE_VALUE.byteValue()}, - {"Tests that the method returns a char value from a short", SHORT_VALUE, char.class, (char) SHORT_VALUE.byteValue()}, - {"Tests that the method returns a char value from an Integer", INTEGER_VALUE, char.class, (char) INTEGER_VALUE.byteValue()}, - {"Tests that the method returns a char value from a Long", LONG_VALUE, char.class, (char) LONG_VALUE.byteValue()}, - {"Tests that the method returns a char value from a Float", FLOAT_VALUE, char.class, (char) FLOAT_VALUE.byteValue()}, - {"Tests that the method returns a char value from a Double", DOUBLE_VALUE, char.class, (char) DOUBLE_VALUE.byteValue()}, - {"Tests that the method returns a char value from a char", TRUE_AS_CHAR_VALUE, char.class, TRUE_AS_CHAR_VALUE}, - {"Tests that the method returns a char value from a Boolean", BOOLEAN_VALUE, char.class, TRUE_AS_CHAR_VALUE}, - {"Tests that the method returns a char value from a String", ONE_AS_STRING, char.class, ONE_AS_STRING.charAt(0)}, - {"Tests that the method returns a char value from a BigInteger", BigInteger.ZERO, char.class, BIG_INTEGER_ZERO_AS_CHAR}, - {"Tests that the method returns a char value from a BigDecimal", BigDecimal.ZERO, char.class, BIG_DECIMAL_ZERO_AS_CHAR}, - {"Tests that the method returns a char value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, char.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getChar()}, - // double conversion test cases - {"Tests that the method returns a double value from a byte", BYTE_VALUE, double.class, BYTE_VALUE.doubleValue()}, - {"Tests that the method returns a double value from a short", SHORT_VALUE, double.class, SHORT_VALUE.doubleValue()}, - {"Tests that the method returns a double value from an Integer", INTEGER_VALUE, double.class, INTEGER_VALUE.doubleValue()}, - {"Tests that the method returns a double value from a Long", LONG_VALUE, double.class, LONG_VALUE.doubleValue()}, - {"Tests that the method returns a double value from a Float", FLOAT_VALUE, double.class, FLOAT_VALUE.doubleValue()}, - {"Tests that the method returns a double value from a Double", DOUBLE_VALUE, double.class, DOUBLE_VALUE}, - {"Tests that the method returns a double value from a char", CHAR_VALUE, double.class, Double.valueOf(String.valueOf(CHAR_VALUE))}, - {"Tests that the method returns a double value from a Boolean", BOOLEAN_VALUE, double.class, (double) TRUE_AS_INT}, - {"Tests that the method returns a double value from a String", ONE_AS_STRING, double.class, Double.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a double value from a BigInteger", BigInteger.ZERO, double.class, BigInteger.ZERO.doubleValue()}, - {"Tests that the method returns a double value from a BigDecimal", BigDecimal.ZERO, double.class, BigDecimal.ZERO.doubleValue()}, - {"Tests that the method returns a double value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, double.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble()}, - // float conversion test cases - {"Tests that the method returns a float value from a byte", BYTE_VALUE, float.class, BYTE_VALUE.floatValue()}, - {"Tests that the method returns a float value from a short", SHORT_VALUE, float.class, SHORT_VALUE.floatValue()}, - {"Tests that the method returns a float value from an Integer", INTEGER_VALUE, float.class, INTEGER_VALUE.floatValue()}, - {"Tests that the method returns a float value from a Long", LONG_VALUE, float.class, LONG_VALUE.floatValue()}, - {"Tests that the method returns a float value from a Float", FLOAT_VALUE, float.class, FLOAT_VALUE}, - {"Tests that the method returns a float value from a Double", DOUBLE_VALUE, float.class, DOUBLE_VALUE.floatValue()}, - {"Tests that the method returns a float value from a char", CHAR_VALUE, float.class, (float) getNumericValue(CHAR_VALUE)}, - {"Tests that the method returns a float value from a Boolean", BOOLEAN_VALUE, float.class, (float) TRUE_AS_INT}, - {"Tests that the method returns a float value from a String", ONE_AS_STRING, float.class, Float.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a float value from a BigInteger", BigInteger.ZERO, float.class, BigInteger.ZERO.floatValue()}, - {"Tests that the method returns a float value from a BigDecimal", BigDecimal.ZERO, float.class, BigDecimal.ZERO.floatValue()}, - {"Tests that the method returns a float value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, float.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getFloat()}, - // integer conversion test cases - {"Tests that the method returns an int value from a byte", BYTE_VALUE, int.class, BYTE_VALUE.intValue()}, - {"Tests that the method returns an int value from a short", SHORT_VALUE, int.class, SHORT_VALUE.intValue()}, - {"Tests that the method returns an int value from an Integer", INTEGER_VALUE, int.class, INTEGER_VALUE}, - {"Tests that the method returns an int value from a Long", LONG_VALUE, int.class, LONG_VALUE.intValue()}, - {"Tests that the method returns an int value from a Float", FLOAT_VALUE, int.class, FLOAT_VALUE.intValue()}, - {"Tests that the method returns an int value from a Double", DOUBLE_VALUE, int.class, DOUBLE_VALUE.intValue()}, - {"Tests that the method returns an int value from a char", CHAR_VALUE, int.class, getNumericValue(CHAR_VALUE)}, - {"Tests that the method returns an int value from a Boolean", BOOLEAN_VALUE, int.class, TRUE_AS_INT}, - {"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns an int value from a BigInteger", BigInteger.ZERO, int.class, BigInteger.ZERO.intValue()}, - {"Tests that the method returns an int value from a BigDecimal", BigDecimal.ZERO, int.class, BigDecimal.ZERO.intValue()}, - {"Tests that the method returns a int value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, int.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getInt()}, - // long conversion test cases - {"Tests that the method returns a long value from a byte", BYTE_VALUE, long.class, BYTE_VALUE.longValue()}, - {"Tests that the method returns a long value from a short", SHORT_VALUE, long.class, SHORT_VALUE.longValue()}, - {"Tests that the method returns a long value from an Integer", INTEGER_VALUE, long.class, INTEGER_VALUE.longValue()}, - {"Tests that the method returns a long value from a Long", LONG_VALUE, long.class, LONG_VALUE}, - {"Tests that the method returns a long value from a Float", FLOAT_VALUE, long.class, FLOAT_VALUE.longValue()}, - {"Tests that the method returns a long value from a Double", DOUBLE_VALUE, long.class, DOUBLE_VALUE.longValue()}, - {"Tests that the method returns a long value from a char", CHAR_VALUE, long.class, (long) getNumericValue(CHAR_VALUE)}, - {"Tests that the method returns a long value from a Boolean", BOOLEAN_VALUE, long.class, (long) TRUE_AS_INT}, - {"Tests that the method returns a long value from a String", ONE_AS_STRING, long.class, Long.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a long value from a BigInteger", BigInteger.ZERO, long.class, BigInteger.ZERO.longValue()}, - {"Tests that the method returns a long value from a BigDecimal", BigDecimal.ZERO, long.class, BigDecimal.ZERO.longValue()}, - {"Tests that the method returns a long value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, long.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getLong()}, - // short conversion test cases - {"Tests that the method returns a short value from a byte", BYTE_VALUE, short.class, BYTE_VALUE.shortValue()}, - {"Tests that the method returns a short value from a short", SHORT_VALUE, short.class, SHORT_VALUE}, - {"Tests that the method returns a short value from an Integer", INTEGER_VALUE, short.class, INTEGER_VALUE.shortValue()}, - {"Tests that the method returns a short value from a Long", LONG_VALUE, short.class, LONG_VALUE.shortValue()}, - {"Tests that the method returns a short value from a Float", FLOAT_VALUE, short.class, FLOAT_VALUE.shortValue()}, - {"Tests that the method returns a short value from a Double", DOUBLE_VALUE, short.class, DOUBLE_VALUE.shortValue()}, - {"Tests that the method returns a short value from a char", CHAR_VALUE, short.class, (short) getNumericValue(CHAR_VALUE)}, - {"Tests that the method returns a short value from a Boolean", BOOLEAN_VALUE, short.class, (short) TRUE_AS_INT}, - {"Tests that the method returns a short value from a String", ONE_AS_STRING, short.class, Short.valueOf(ONE_AS_STRING)}, - {"Tests that the method returns a short value from a BigInteger", BigInteger.ZERO, short.class, BigInteger.ZERO.shortValue()}, - {"Tests that the method returns a short value from a BigDecimal", BigDecimal.ZERO, short.class, BigDecimal.ZERO.shortValue()}, - {"Tests that the method returns a short value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, short.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getShort()}, - // string conversion test cases - {"Tests that the method returns a String value from a byte", BYTE_VALUE, String.class, BYTE_VALUE.toString()}, - {"Tests that the method returns a String value from a short", SHORT_VALUE, String.class, SHORT_VALUE.toString()}, - {"Tests that the method returns a String value from an Integer", INTEGER_VALUE, String.class, String.valueOf(INTEGER_VALUE)}, - {"Tests that the method returns a String value from a Long", LONG_VALUE, String.class, String.valueOf(LONG_VALUE)}, - {"Tests that the method returns a String value from a Float", FLOAT_VALUE, String.class, String.valueOf(FLOAT_VALUE)}, - {"Tests that the method returns a String value from a Double", DOUBLE_VALUE, String.class, String.valueOf(DOUBLE_VALUE)}, - {"Tests that the method returns a String value from a char", CHAR_VALUE, String.class, String.valueOf(CHAR_VALUE)}, - {"Tests that the method returns a String value from a Boolean", BOOLEAN_VALUE, String.class, String.valueOf(BOOLEAN_VALUE)}, - {"Tests that the method returns a String value from a String", ONE_AS_STRING, String.class, ONE_AS_STRING}, - {"Tests that the method returns a String value from a BigInteger", BigInteger.ZERO, String.class, BigInteger.ZERO.toString()}, - {"Tests that the method returns a String value from a BigDecimal", BigDecimal.ZERO, String.class, BigDecimal.ZERO.toPlainString()}, - {"Tests that the method returns a String value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, String.class, new String(EIGHT_BYTE_BYTE_ARRAY)}, - // BigInteger conversion test cases - {"Tests that the method returns a BigInteger value from a byte", BYTE_VALUE, BigInteger.class, BigInteger.valueOf(BYTE_VALUE.longValue())}, - {"Tests that the method returns a BigInteger value from a short", SHORT_VALUE, BigInteger.class, BigInteger.valueOf(SHORT_VALUE)}, - {"Tests that the method returns a BigInteger value from an Integer", INTEGER_VALUE, BigInteger.class, BigInteger.valueOf(INTEGER_VALUE)}, - {"Tests that the method returns a BigInteger value from a Long", LONG_VALUE, BigInteger.class, BigInteger.valueOf(LONG_VALUE)}, - {"Tests that the method returns a BigInteger value from a Float", FLOAT_VALUE, BigInteger.class, BigInteger.valueOf(FLOAT_VALUE.intValue())}, - {"Tests that the method returns a BigInteger value from a Double", DOUBLE_VALUE, BigInteger.class, BigInteger.valueOf(DOUBLE_VALUE.intValue())}, - {"Tests that the method returns a BigInteger value from a char", CHAR_VALUE, BigInteger.class, BigInteger.valueOf(getNumericValue(CHAR_VALUE))}, - {"Tests that the method returns a BigInteger value from a Boolean", BOOLEAN_VALUE, BigInteger.class, BigInteger.valueOf(TRUE_AS_INT)}, - {"Tests that the method returns a BigInteger value from a String", ONE_AS_STRING, BigInteger.class, new BigInteger(ONE_AS_STRING)}, - {"Tests that the method returns a BigInteger value from a BigInteger", BigInteger.ZERO, BigInteger.class, BigInteger.ZERO}, - {"Tests that the method returns a BigInteger value from a BigDecimal", BigDecimal.ZERO, BigInteger.class, BigDecimal.ZERO.toBigInteger()}, - {"Tests that the method returns a BigInteger value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigInteger.class, BigInteger.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getLong())}, - // BigDecimal conversion test cases - {"Tests that the method returns a BigDecimal value from a byte", BYTE_VALUE, BigDecimal.class, BigDecimal.valueOf(BYTE_VALUE.doubleValue())}, - {"Tests that the method returns a BigDecimal value from a short", SHORT_VALUE, BigDecimal.class, BigDecimal.valueOf(SHORT_VALUE)}, - {"Tests that the method returns a BigDecimal value from an Integer", INTEGER_VALUE, BigDecimal.class, BigDecimal.valueOf(INTEGER_VALUE)}, - {"Tests that the method returns a BigDecimal value from a Long", LONG_VALUE, BigDecimal.class, BigDecimal.valueOf(LONG_VALUE)}, - {"Tests that the method returns a BigDecimal value from a Float", FLOAT_VALUE, BigDecimal.class, BigDecimal.valueOf(FLOAT_VALUE)}, - {"Tests that the method returns a BigDecimal value from a Double", DOUBLE_VALUE, BigDecimal.class, BigDecimal.valueOf(DOUBLE_VALUE)}, - {"Tests that the method returns a BigDecimal value from a char", CHAR_VALUE, BigDecimal.class, BigDecimal.valueOf(getNumericValue(CHAR_VALUE))}, - {"Tests that the method returns a BigDecimal value from a Boolean", BOOLEAN_VALUE, BigDecimal.class, BigDecimal.valueOf(TRUE_AS_INT)}, - {"Tests that the method returns a BigDecimal value from a String", ONE_AS_STRING, BigDecimal.class, new BigDecimal(ONE_AS_STRING)}, - {"Tests that the method returns a BigDecimal value from a BigInteger", BigInteger.ZERO, BigDecimal.class, BigDecimal.valueOf(BigInteger.ZERO.intValue())}, - {"Tests that the method returns a BigDecimal value from a BigDecimal", BigDecimal.ZERO, BigDecimal.class, BigDecimal.ZERO}, - {"Tests that the method returns a BigDecimal value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigDecimal.class, BigDecimal.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble())} - }; + private Iterator dataConvertValueTesting() { + List testCases = new ArrayList<>( + new Object[]{"Tests that the method returns a null value in case the value to convert is null", null, BigInteger.class, null}, + // byte conversion test cases + new Object[]{"Tests that the method returns a byte value from a byte", BYTE_VALUE, byte.class, BYTE_VALUE}, + new Object[]{"Tests that the method returns a byte value from a short", SHORT_VALUE, byte.class, SHORT_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a byte value from an Integer", INTEGER_VALUE, byte.class, INTEGER_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a byte value from a Long", LONG_VALUE, byte.class, LONG_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a byte value from a Float", FLOAT_VALUE, byte.class, FLOAT_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a byte value from a Double", DOUBLE_VALUE, byte.class, DOUBLE_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a byte value from a char", TRUE_AS_CHAR_VALUE, byte.class, (byte) TRUE_AS_CHAR_VALUE.charValue()}, + new Object[]{"Tests that the method returns a byte value from a Boolean", BOOLEAN_VALUE, byte.class, TRUE_AS_BYTE}, + new Object[]{"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, + new Object[]{"Tests that the method returns a byte value from a BigInteger", ZERO, byte.class, ZERO.byteValue()}, + new Object[]{"Tests that the method returns a byte value from a BigDecimal", BigDecimal.ZERO, byte.class, BigDecimal.ZERO.byteValue()}, + new Object[]{"Tests that the method returns a byte value from a byte[]", ONE_BYTE_BYTE_ARRAY, byte.class, TRUE_AS_BYTE}, + // char conversion test cases + new Object[]{"Tests that the method returns a char value from a byte", BYTE_VALUE, char.class, (char) BYTE_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a char value from a short", SHORT_VALUE, char.class, (char) SHORT_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a char value from an Integer", INTEGER_VALUE, char.class, (char) INTEGER_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a char value from a Long", LONG_VALUE, char.class, (char) LONG_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a char value from a Float", FLOAT_VALUE, char.class, (char) FLOAT_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a char value from a Double", DOUBLE_VALUE, char.class, (char) DOUBLE_VALUE.byteValue()}, + new Object[]{"Tests that the method returns a char value from a char", TRUE_AS_CHAR_VALUE, char.class, TRUE_AS_CHAR_VALUE}, + new Object[]{"Tests that the method returns a char value from a Boolean", BOOLEAN_VALUE, char.class, TRUE_AS_CHAR_VALUE}, + new Object[]{"Tests that the method returns a char value from a String", ONE_AS_STRING, char.class, ONE_AS_STRING.charAt(0)}, + new Object[]{"Tests that the method returns a char value from a BigInteger", ZERO, char.class, BIG_INTEGER_ZERO_AS_CHAR}, + new Object[]{"Tests that the method returns a char value from a BigDecimal", BigDecimal.ZERO, char.class, BIG_DECIMAL_ZERO_AS_CHAR}, + new Object[]{"Tests that the method returns a char value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, char.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getChar()}, + // double conversion test cases + new Object[]{"Tests that the method returns a double value from a byte", BYTE_VALUE, double.class, BYTE_VALUE.doubleValue()}, + new Object[]{"Tests that the method returns a double value from a short", SHORT_VALUE, double.class, SHORT_VALUE.doubleValue()}, + new Object[]{"Tests that the method returns a double value from an Integer", INTEGER_VALUE, double.class, INTEGER_VALUE.doubleValue()}, + new Object[]{"Tests that the method returns a double value from a Long", LONG_VALUE, double.class, LONG_VALUE.doubleValue()}, + new Object[]{"Tests that the method returns a double value from a Float", FLOAT_VALUE, double.class, FLOAT_VALUE.doubleValue()}, + new Object[]{"Tests that the method returns a double value from a Double", DOUBLE_VALUE, double.class, DOUBLE_VALUE}, + new Object[]{"Tests that the method returns a double value from a char", CHAR_VALUE, double.class, Double.valueOf(String.valueOf(CHAR_VALUE))}, + new Object[]{"Tests that the method returns a double value from a Boolean", BOOLEAN_VALUE, double.class, (double) TRUE_AS_INT}, + new Object[]{"Tests that the method returns a double value from a String", ONE_AS_STRING, double.class, Double.valueOf(ONE_AS_STRING)}, + new Object[]{"Tests that the method returns a double value from a BigInteger", ZERO, double.class, ZERO.doubleValue()}, + new Object[]{"Tests that the method returns a double value from a BigDecimal", BigDecimal.ZERO, double.class, BigDecimal.ZERO.doubleValue()}, + new Object[]{"Tests that the method returns a double value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, double.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble()}, + // float conversion test cases + new Object[]{"Tests that the method returns a float value from a byte", BYTE_VALUE, float.class, BYTE_VALUE.floatValue()}, + new Object[]{"Tests that the method returns a float value from a short", SHORT_VALUE, float.class, SHORT_VALUE.floatValue()}, + new Object[]{"Tests that the method returns a float value from an Integer", INTEGER_VALUE, float.class, INTEGER_VALUE.floatValue()}, + new Object[]{"Tests that the method returns a float value from a Long", LONG_VALUE, float.class, LONG_VALUE.floatValue()}, + new Object[]{"Tests that the method returns a float value from a Float", FLOAT_VALUE, float.class, FLOAT_VALUE}, + new Object[]{"Tests that the method returns a float value from a Double", DOUBLE_VALUE, float.class, DOUBLE_VALUE.floatValue()}, + new Object[]{"Tests that the method returns a float value from a char", CHAR_VALUE, float.class, (float) getNumericValue(CHAR_VALUE)}, + new Object[]{"Tests that the method returns a float value from a Boolean", BOOLEAN_VALUE, float.class, (float) TRUE_AS_INT}, + new Object[]{"Tests that the method returns a float value from a String", ONE_AS_STRING, float.class, Float.valueOf(ONE_AS_STRING)}, + new Object[]{"Tests that the method returns a float value from a BigInteger", ZERO, float.class, ZERO.floatValue()}, + new Object[]{"Tests that the method returns a float value from a BigDecimal", BigDecimal.ZERO, float.class, BigDecimal.ZERO.floatValue()}, + new Object[]{"Tests that the method returns a float value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, float.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getFloat()}, + // integer conversion test cases + new Object[]{"Tests that the method returns an int value from a byte", BYTE_VALUE, int.class, BYTE_VALUE.intValue()}, + new Object[]{"Tests that the method returns an int value from a short", SHORT_VALUE, int.class, SHORT_VALUE.intValue()}, + new Object[]{"Tests that the method returns an int value from an Integer", INTEGER_VALUE, int.class, INTEGER_VALUE}, + new Object[]{"Tests that the method returns an int value from a Long", LONG_VALUE, int.class, LONG_VALUE.intValue()}, + new Object[]{"Tests that the method returns an int value from a Float", FLOAT_VALUE, int.class, FLOAT_VALUE.intValue()}, + new Object[]{"Tests that the method returns an int value from a Double", DOUBLE_VALUE, int.class, DOUBLE_VALUE.intValue()}, + new Object[]{"Tests that the method returns an int value from a char", CHAR_VALUE, int.class, getNumericValue(CHAR_VALUE)}, + new Object[]{"Tests that the method returns an int value from a Boolean", BOOLEAN_VALUE, int.class, TRUE_AS_INT}, + new Object[]{"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.valueOf(ONE_AS_STRING)}, + new Object[]{"Tests that the method returns an int value from a BigInteger", ZERO, int.class, ZERO.intValue()}, + new Object[]{"Tests that the method returns an int value from a BigDecimal", BigDecimal.ZERO, int.class, BigDecimal.ZERO.intValue()}, + new Object[]{"Tests that the method returns a int value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, int.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getInt()}, + // long conversion test cases + new Object[]{"Tests that the method returns a long value from a byte", BYTE_VALUE, long.class, BYTE_VALUE.longValue()}, + new Object[]{"Tests that the method returns a long value from a short", SHORT_VALUE, long.class, SHORT_VALUE.longValue()}, + new Object[]{"Tests that the method returns a long value from an Integer", INTEGER_VALUE, long.class, INTEGER_VALUE.longValue()}, + new Object[]{"Tests that the method returns a long value from a Long", LONG_VALUE, long.class, LONG_VALUE}, + new Object[]{"Tests that the method returns a long value from a Float", FLOAT_VALUE, long.class, FLOAT_VALUE.longValue()}, + new Object[]{"Tests that the method returns a long value from a Double", DOUBLE_VALUE, long.class, DOUBLE_VALUE.longValue()}, + new Object[]{"Tests that the method returns a long value from a char", CHAR_VALUE, long.class, (long) getNumericValue(CHAR_VALUE)}, + new Object[]{"Tests that the method returns a long value from a Boolean", BOOLEAN_VALUE, long.class, (long) TRUE_AS_INT}, + new Object[]{"Tests that the method returns a long value from a String", ONE_AS_STRING, long.class, Long.valueOf(ONE_AS_STRING)}, + new Object[]{"Tests that the method returns a long value from a BigInteger", ZERO, long.class, ZERO.longValue()}, + new Object[]{"Tests that the method returns a long value from a BigDecimal", BigDecimal.ZERO, long.class, BigDecimal.ZERO.longValue()}, + new Object[]{"Tests that the method returns a long value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, long.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getLong()}, + // short conversion test cases + new Object[]{"Tests that the method returns a short value from a byte", BYTE_VALUE, short.class, BYTE_VALUE.shortValue()}, + new Object[]{"Tests that the method returns a short value from a short", SHORT_VALUE, short.class, SHORT_VALUE}, + new Object[]{"Tests that the method returns a short value from an Integer", INTEGER_VALUE, short.class, INTEGER_VALUE.shortValue()}, + new Object[]{"Tests that the method returns a short value from a Long", LONG_VALUE, short.class, LONG_VALUE.shortValue()}, + new Object[]{"Tests that the method returns a short value from a Float", FLOAT_VALUE, short.class, FLOAT_VALUE.shortValue()}, + new Object[]{"Tests that the method returns a short value from a Double", DOUBLE_VALUE, short.class, DOUBLE_VALUE.shortValue()}, + new Object[]{"Tests that the method returns a short value from a char", CHAR_VALUE, short.class, (short) getNumericValue(CHAR_VALUE)}, + new Object[]{"Tests that the method returns a short value from a Boolean", BOOLEAN_VALUE, short.class, (short) TRUE_AS_INT}, + new Object[]{"Tests that the method returns a short value from a String", ONE_AS_STRING, short.class, Short.valueOf(ONE_AS_STRING)}, + new Object[]{"Tests that the method returns a short value from a BigInteger", ZERO, short.class, ZERO.shortValue()}, + new Object[]{"Tests that the method returns a short value from a BigDecimal", BigDecimal.ZERO, short.class, BigDecimal.ZERO.shortValue()}, + new Object[]{"Tests that the method returns a short value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, short.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getShort()}, + // string conversion test cases + new Object[]{"Tests that the method returns a String value from a byte", BYTE_VALUE, String.class, BYTE_VALUE.toString()}, + new Object[]{"Tests that the method returns a String value from a short", SHORT_VALUE, String.class, SHORT_VALUE.toString()}, + new Object[]{"Tests that the method returns a String value from an Integer", INTEGER_VALUE, String.class, String.valueOf(INTEGER_VALUE)}, + new Object[]{"Tests that the method returns a String value from a Long", LONG_VALUE, String.class, String.valueOf(LONG_VALUE)}, + new Object[]{"Tests that the method returns a String value from a Float", FLOAT_VALUE, String.class, String.valueOf(FLOAT_VALUE)}, + new Object[]{"Tests that the method returns a String value from a Double", DOUBLE_VALUE, String.class, String.valueOf(DOUBLE_VALUE)}, + new Object[]{"Tests that the method returns a String value from a char", CHAR_VALUE, String.class, String.valueOf(CHAR_VALUE)}, + new Object[]{"Tests that the method returns a String value from a Boolean", BOOLEAN_VALUE, String.class, String.valueOf(BOOLEAN_VALUE)}, + new Object[]{"Tests that the method returns a String value from a String", ONE_AS_STRING, String.class, ONE_AS_STRING}, + new Object[]{"Tests that the method returns a String value from a BigInteger", ZERO, String.class, ZERO.toString()}, + new Object[]{"Tests that the method returns a String value from a BigDecimal", BigDecimal.ZERO, String.class, BigDecimal.ZERO.toPlainString()}, + new Object[]{"Tests that the method returns a String value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, String.class, new String(EIGHT_BYTE_BYTE_ARRAY)}, + // BigInteger conversion test cases + new Object[]{"Tests that the method returns a BigInteger value from a byte", BYTE_VALUE, BigInteger.class, BigInteger.valueOf(BYTE_VALUE.longValue())}, + new Object[]{"Tests that the method returns a BigInteger value from a short", SHORT_VALUE, BigInteger.class, BigInteger.valueOf(SHORT_VALUE)}, + new Object[]{"Tests that the method returns a BigInteger value from an Integer", INTEGER_VALUE, BigInteger.class, BigInteger.valueOf(INTEGER_VALUE)}, + new Object[]{"Tests that the method returns a BigInteger value from a Long", LONG_VALUE, BigInteger.class, BigInteger.valueOf(LONG_VALUE)}, + new Object[]{"Tests that the method returns a BigInteger value from a Float", FLOAT_VALUE, BigInteger.class, BigInteger.valueOf(FLOAT_VALUE.intValue())}, + new Object[]{"Tests that the method returns a BigInteger value from a Double", DOUBLE_VALUE, BigInteger.class, BigInteger.valueOf(DOUBLE_VALUE.intValue())}, + new Object[]{"Tests that the method returns a BigInteger value from a char", CHAR_VALUE, BigInteger.class, BigInteger.valueOf(getNumericValue(CHAR_VALUE))}, + new Object[]{"Tests that the method returns a BigInteger value from a Boolean", BOOLEAN_VALUE, BigInteger.class, BigInteger.valueOf(TRUE_AS_INT)}, + new Object[]{"Tests that the method returns a BigInteger value from a String", ONE_AS_STRING, BigInteger.class, new BigInteger(ONE_AS_STRING)}, + new Object[]{"Tests that the method returns a BigInteger value from a BigInteger", ZERO, BigInteger.class, ZERO}, + new Object[]{"Tests that the method returns a BigInteger value from a BigDecimal", BigDecimal.ZERO, BigInteger.class, BigDecimal.ZERO.toBigInteger()}, + new Object[]{"Tests that the method returns a BigInteger value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigInteger.class, BigInteger.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getLong())}, + // BigDecimal conversion test cases + new Object[]{"Tests that the method returns a BigDecimal value from a byte", BYTE_VALUE, BigDecimal.class, BigDecimal.valueOf(BYTE_VALUE.doubleValue())}, + new Object[]{"Tests that the method returns a BigDecimal value from a short", SHORT_VALUE, BigDecimal.class, BigDecimal.valueOf(SHORT_VALUE)}, + new Object[]{"Tests that the method returns a BigDecimal value from an Integer", INTEGER_VALUE, BigDecimal.class, BigDecimal.valueOf(INTEGER_VALUE)}, + new Object[]{"Tests that the method returns a BigDecimal value from a Long", LONG_VALUE, BigDecimal.class, BigDecimal.valueOf(LONG_VALUE)}, + new Object[]{"Tests that the method returns a BigDecimal value from a Float", FLOAT_VALUE, BigDecimal.class, BigDecimal.valueOf(FLOAT_VALUE)}, + new Object[]{"Tests that the method returns a BigDecimal value from a Double", DOUBLE_VALUE, BigDecimal.class, BigDecimal.valueOf(DOUBLE_VALUE)}, + new Object[]{"Tests that the method returns a BigDecimal value from a char", CHAR_VALUE, BigDecimal.class, BigDecimal.valueOf(getNumericValue(CHAR_VALUE))}, + new Object[]{"Tests that the method returns a BigDecimal value from a Boolean", BOOLEAN_VALUE, BigDecimal.class, BigDecimal.valueOf(TRUE_AS_INT)}, + new Object[]{"Tests that the method returns a BigDecimal value from a String", ONE_AS_STRING, BigDecimal.class, new BigDecimal(ONE_AS_STRING)}, + new Object[]{"Tests that the method returns a BigDecimal value from a BigInteger", ZERO, BigDecimal.class, BigDecimal.valueOf(ZERO.intValue())}, + new Object[]{"Tests that the method returns a BigDecimal value from a BigDecimal", BigDecimal.ZERO, BigDecimal.class, BigDecimal.ZERO}, + new Object[]{"Tests that the method returns a BigDecimal value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigDecimal.class, BigDecimal.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble())}); + Collections.addAll(testCases, dataConvertByteArrayValueTesting()); + return testCases.iterator(); + } + + private List dataConvertBooleanValueTesting() { + return List.of( + new Object[]{"Tests that the method returns a boolean value from a byte", BYTE_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a short", SHORT_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from an Integer", INTEGER_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a Long", LONG_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a Float", FLOAT_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a Double", DOUBLE_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a char", TRUE_AS_CHAR_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a Boolean", BOOLEAN_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a String", TRUE_AS_STRING, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a BigInteger", BigInteger.ZERO, boolean.class, Boolean.FALSE}, + new Object[]{"Tests that the method returns a boolean value from a BigDecimal", BigDecimal.ZERO, boolean.class, Boolean.FALSE}, + new Object[]{"Tests that the method returns a boolean value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, boolean.class, BOOLEAN_VALUE}); } /** From 2cb700fba5a380fc92e0773ebd470d66885102ca Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 8 Aug 2019 06:56:16 +0200 Subject: [PATCH 0786/1786] Diveded convertValue test cases in smallest methods in order to improve debugging and maintenance --- .../beans/conversion/ConverterTest.java | 168 +++++++++++++----- 1 file changed, 127 insertions(+), 41 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 148075391..da3c2b969 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -29,7 +29,6 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Optional; @@ -202,9 +201,48 @@ public void testConvertValueWorksProperly(final String testCaseDescription, */ @DataProvider private Iterator dataConvertValueTesting() { - List testCases = new ArrayList<>( - new Object[]{"Tests that the method returns a null value in case the value to convert is null", null, BigInteger.class, null}, - // byte conversion test cases + List testCases = new ArrayList<>(); + testCases.add(new Object[]{"Tests that the method returns a null value in case the value to convert is null", null, BigInteger.class, null}); + testCases.addAll(dataConvertBooleanValueTesting()); + testCases.addAll(dataConvertByteValueTesting()); + testCases.addAll(dataConvertCharValueTesting()); + testCases.addAll(dataConvertDoubleValueTesting()); + testCases.addAll(dataConvertFloatValueTesting()); + testCases.addAll(dataConvertIntValueTesting()); + testCases.addAll(dataConvertLongValueTesting()); + testCases.addAll(dataConvertShortValueTesting()); + testCases.addAll(dataConvertStringValueTesting()); + testCases.addAll(dataConvertBigIntegerValueTesting()); + testCases.addAll(dataConvertBigDecimalValueTesting()); + return testCases.iterator(); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for boolean type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for boolean type. + */ + private List dataConvertBooleanValueTesting() { + return List.of( + new Object[]{"Tests that the method returns a boolean value from a byte", BYTE_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a short", SHORT_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from an Integer", INTEGER_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a Long", LONG_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a Float", FLOAT_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a Double", DOUBLE_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a char", TRUE_AS_CHAR_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a Boolean", BOOLEAN_VALUE, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a String", TRUE_AS_STRING, boolean.class, BOOLEAN_VALUE}, + new Object[]{"Tests that the method returns a boolean value from a BigInteger", BigInteger.ZERO, boolean.class, Boolean.FALSE}, + new Object[]{"Tests that the method returns a boolean value from a BigDecimal", BigDecimal.ZERO, boolean.class, Boolean.FALSE}, + new Object[]{"Tests that the method returns a boolean value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, boolean.class, BOOLEAN_VALUE}); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for byte type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for byte type. + */ + private List dataConvertByteValueTesting() { + return List.of( new Object[]{"Tests that the method returns a byte value from a byte", BYTE_VALUE, byte.class, BYTE_VALUE}, new Object[]{"Tests that the method returns a byte value from a short", SHORT_VALUE, byte.class, SHORT_VALUE.byteValue()}, new Object[]{"Tests that the method returns a byte value from an Integer", INTEGER_VALUE, byte.class, INTEGER_VALUE.byteValue()}, @@ -216,8 +254,16 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns a byte value from a String", ONE_AS_STRING, byte.class, Byte.valueOf(ONE_AS_STRING)}, new Object[]{"Tests that the method returns a byte value from a BigInteger", ZERO, byte.class, ZERO.byteValue()}, new Object[]{"Tests that the method returns a byte value from a BigDecimal", BigDecimal.ZERO, byte.class, BigDecimal.ZERO.byteValue()}, - new Object[]{"Tests that the method returns a byte value from a byte[]", ONE_BYTE_BYTE_ARRAY, byte.class, TRUE_AS_BYTE}, - // char conversion test cases + new Object[]{"Tests that the method returns a byte value from a byte[]", ONE_BYTE_BYTE_ARRAY, byte.class, TRUE_AS_BYTE} + ); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for char type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for char type. + */ + private List dataConvertCharValueTesting() { + return List.of( new Object[]{"Tests that the method returns a char value from a byte", BYTE_VALUE, char.class, (char) BYTE_VALUE.byteValue()}, new Object[]{"Tests that the method returns a char value from a short", SHORT_VALUE, char.class, (char) SHORT_VALUE.byteValue()}, new Object[]{"Tests that the method returns a char value from an Integer", INTEGER_VALUE, char.class, (char) INTEGER_VALUE.byteValue()}, @@ -229,8 +275,15 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns a char value from a String", ONE_AS_STRING, char.class, ONE_AS_STRING.charAt(0)}, new Object[]{"Tests that the method returns a char value from a BigInteger", ZERO, char.class, BIG_INTEGER_ZERO_AS_CHAR}, new Object[]{"Tests that the method returns a char value from a BigDecimal", BigDecimal.ZERO, char.class, BIG_DECIMAL_ZERO_AS_CHAR}, - new Object[]{"Tests that the method returns a char value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, char.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getChar()}, - // double conversion test cases + new Object[]{"Tests that the method returns a char value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, char.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getChar()}); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for double type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for double type. + */ + private List dataConvertDoubleValueTesting() { + return List.of( new Object[]{"Tests that the method returns a double value from a byte", BYTE_VALUE, double.class, BYTE_VALUE.doubleValue()}, new Object[]{"Tests that the method returns a double value from a short", SHORT_VALUE, double.class, SHORT_VALUE.doubleValue()}, new Object[]{"Tests that the method returns a double value from an Integer", INTEGER_VALUE, double.class, INTEGER_VALUE.doubleValue()}, @@ -242,8 +295,15 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns a double value from a String", ONE_AS_STRING, double.class, Double.valueOf(ONE_AS_STRING)}, new Object[]{"Tests that the method returns a double value from a BigInteger", ZERO, double.class, ZERO.doubleValue()}, new Object[]{"Tests that the method returns a double value from a BigDecimal", BigDecimal.ZERO, double.class, BigDecimal.ZERO.doubleValue()}, - new Object[]{"Tests that the method returns a double value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, double.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble()}, - // float conversion test cases + new Object[]{"Tests that the method returns a double value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, double.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble()}); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for float type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for float type. + */ + private List dataConvertFloatValueTesting() { + return List.of( new Object[]{"Tests that the method returns a float value from a byte", BYTE_VALUE, float.class, BYTE_VALUE.floatValue()}, new Object[]{"Tests that the method returns a float value from a short", SHORT_VALUE, float.class, SHORT_VALUE.floatValue()}, new Object[]{"Tests that the method returns a float value from an Integer", INTEGER_VALUE, float.class, INTEGER_VALUE.floatValue()}, @@ -255,8 +315,15 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns a float value from a String", ONE_AS_STRING, float.class, Float.valueOf(ONE_AS_STRING)}, new Object[]{"Tests that the method returns a float value from a BigInteger", ZERO, float.class, ZERO.floatValue()}, new Object[]{"Tests that the method returns a float value from a BigDecimal", BigDecimal.ZERO, float.class, BigDecimal.ZERO.floatValue()}, - new Object[]{"Tests that the method returns a float value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, float.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getFloat()}, - // integer conversion test cases + new Object[]{"Tests that the method returns a float value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, float.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getFloat()}); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for int type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for int type. + */ + private List dataConvertIntValueTesting() { + return List.of( new Object[]{"Tests that the method returns an int value from a byte", BYTE_VALUE, int.class, BYTE_VALUE.intValue()}, new Object[]{"Tests that the method returns an int value from a short", SHORT_VALUE, int.class, SHORT_VALUE.intValue()}, new Object[]{"Tests that the method returns an int value from an Integer", INTEGER_VALUE, int.class, INTEGER_VALUE}, @@ -268,8 +335,15 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns an int value from a String", ONE_AS_STRING, int.class, Integer.valueOf(ONE_AS_STRING)}, new Object[]{"Tests that the method returns an int value from a BigInteger", ZERO, int.class, ZERO.intValue()}, new Object[]{"Tests that the method returns an int value from a BigDecimal", BigDecimal.ZERO, int.class, BigDecimal.ZERO.intValue()}, - new Object[]{"Tests that the method returns a int value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, int.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getInt()}, - // long conversion test cases + new Object[]{"Tests that the method returns a int value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, int.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getInt()}); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for long type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for long type. + */ + private List dataConvertLongValueTesting() { + return List.of( new Object[]{"Tests that the method returns a long value from a byte", BYTE_VALUE, long.class, BYTE_VALUE.longValue()}, new Object[]{"Tests that the method returns a long value from a short", SHORT_VALUE, long.class, SHORT_VALUE.longValue()}, new Object[]{"Tests that the method returns a long value from an Integer", INTEGER_VALUE, long.class, INTEGER_VALUE.longValue()}, @@ -281,8 +355,15 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns a long value from a String", ONE_AS_STRING, long.class, Long.valueOf(ONE_AS_STRING)}, new Object[]{"Tests that the method returns a long value from a BigInteger", ZERO, long.class, ZERO.longValue()}, new Object[]{"Tests that the method returns a long value from a BigDecimal", BigDecimal.ZERO, long.class, BigDecimal.ZERO.longValue()}, - new Object[]{"Tests that the method returns a long value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, long.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getLong()}, - // short conversion test cases + new Object[]{"Tests that the method returns a long value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, long.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getLong()}); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for short type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for short type. + */ + private List dataConvertShortValueTesting() { + return List.of( new Object[]{"Tests that the method returns a short value from a byte", BYTE_VALUE, short.class, BYTE_VALUE.shortValue()}, new Object[]{"Tests that the method returns a short value from a short", SHORT_VALUE, short.class, SHORT_VALUE}, new Object[]{"Tests that the method returns a short value from an Integer", INTEGER_VALUE, short.class, INTEGER_VALUE.shortValue()}, @@ -294,8 +375,15 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns a short value from a String", ONE_AS_STRING, short.class, Short.valueOf(ONE_AS_STRING)}, new Object[]{"Tests that the method returns a short value from a BigInteger", ZERO, short.class, ZERO.shortValue()}, new Object[]{"Tests that the method returns a short value from a BigDecimal", BigDecimal.ZERO, short.class, BigDecimal.ZERO.shortValue()}, - new Object[]{"Tests that the method returns a short value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, short.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getShort()}, - // string conversion test cases + new Object[]{"Tests that the method returns a short value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, short.class, wrap(EIGHT_BYTE_BYTE_ARRAY).getShort()}); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for String type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for String type. + */ + private List dataConvertStringValueTesting() { + return List.of( new Object[]{"Tests that the method returns a String value from a byte", BYTE_VALUE, String.class, BYTE_VALUE.toString()}, new Object[]{"Tests that the method returns a String value from a short", SHORT_VALUE, String.class, SHORT_VALUE.toString()}, new Object[]{"Tests that the method returns a String value from an Integer", INTEGER_VALUE, String.class, String.valueOf(INTEGER_VALUE)}, @@ -307,8 +395,15 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns a String value from a String", ONE_AS_STRING, String.class, ONE_AS_STRING}, new Object[]{"Tests that the method returns a String value from a BigInteger", ZERO, String.class, ZERO.toString()}, new Object[]{"Tests that the method returns a String value from a BigDecimal", BigDecimal.ZERO, String.class, BigDecimal.ZERO.toPlainString()}, - new Object[]{"Tests that the method returns a String value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, String.class, new String(EIGHT_BYTE_BYTE_ARRAY)}, - // BigInteger conversion test cases + new Object[]{"Tests that the method returns a String value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, String.class, new String(EIGHT_BYTE_BYTE_ARRAY)}); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for BigInteger type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for BigInteger type. + */ + private List dataConvertBigIntegerValueTesting() { + return List.of( new Object[]{"Tests that the method returns a BigInteger value from a byte", BYTE_VALUE, BigInteger.class, BigInteger.valueOf(BYTE_VALUE.longValue())}, new Object[]{"Tests that the method returns a BigInteger value from a short", SHORT_VALUE, BigInteger.class, BigInteger.valueOf(SHORT_VALUE)}, new Object[]{"Tests that the method returns a BigInteger value from an Integer", INTEGER_VALUE, BigInteger.class, BigInteger.valueOf(INTEGER_VALUE)}, @@ -320,8 +415,16 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns a BigInteger value from a String", ONE_AS_STRING, BigInteger.class, new BigInteger(ONE_AS_STRING)}, new Object[]{"Tests that the method returns a BigInteger value from a BigInteger", ZERO, BigInteger.class, ZERO}, new Object[]{"Tests that the method returns a BigInteger value from a BigDecimal", BigDecimal.ZERO, BigInteger.class, BigDecimal.ZERO.toBigInteger()}, - new Object[]{"Tests that the method returns a BigInteger value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigInteger.class, BigInteger.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getLong())}, - // BigDecimal conversion test cases + new Object[]{"Tests that the method returns a BigInteger value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigInteger.class, + BigInteger.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getLong())}); + } + + /** + * Creates the parameters to be used for testing that the method {@code convertValue} returns the expected result for BigDecimal type. + * @return parameters to be used for testing that the method {@code convertValue} returns the expected result for BigDecimal type. + */ + private List dataConvertBigDecimalValueTesting() { + return List.of( new Object[]{"Tests that the method returns a BigDecimal value from a byte", BYTE_VALUE, BigDecimal.class, BigDecimal.valueOf(BYTE_VALUE.doubleValue())}, new Object[]{"Tests that the method returns a BigDecimal value from a short", SHORT_VALUE, BigDecimal.class, BigDecimal.valueOf(SHORT_VALUE)}, new Object[]{"Tests that the method returns a BigDecimal value from an Integer", INTEGER_VALUE, BigDecimal.class, BigDecimal.valueOf(INTEGER_VALUE)}, @@ -333,25 +436,8 @@ private Iterator dataConvertValueTesting() { new Object[]{"Tests that the method returns a BigDecimal value from a String", ONE_AS_STRING, BigDecimal.class, new BigDecimal(ONE_AS_STRING)}, new Object[]{"Tests that the method returns a BigDecimal value from a BigInteger", ZERO, BigDecimal.class, BigDecimal.valueOf(ZERO.intValue())}, new Object[]{"Tests that the method returns a BigDecimal value from a BigDecimal", BigDecimal.ZERO, BigDecimal.class, BigDecimal.ZERO}, - new Object[]{"Tests that the method returns a BigDecimal value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigDecimal.class, BigDecimal.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble())}); - Collections.addAll(testCases, dataConvertByteArrayValueTesting()); - return testCases.iterator(); - } - - private List dataConvertBooleanValueTesting() { - return List.of( - new Object[]{"Tests that the method returns a boolean value from a byte", BYTE_VALUE, boolean.class, BOOLEAN_VALUE}, - new Object[]{"Tests that the method returns a boolean value from a short", SHORT_VALUE, boolean.class, BOOLEAN_VALUE}, - new Object[]{"Tests that the method returns a boolean value from an Integer", INTEGER_VALUE, boolean.class, BOOLEAN_VALUE}, - new Object[]{"Tests that the method returns a boolean value from a Long", LONG_VALUE, boolean.class, BOOLEAN_VALUE}, - new Object[]{"Tests that the method returns a boolean value from a Float", FLOAT_VALUE, boolean.class, BOOLEAN_VALUE}, - new Object[]{"Tests that the method returns a boolean value from a Double", DOUBLE_VALUE, boolean.class, BOOLEAN_VALUE}, - new Object[]{"Tests that the method returns a boolean value from a char", TRUE_AS_CHAR_VALUE, boolean.class, BOOLEAN_VALUE}, - new Object[]{"Tests that the method returns a boolean value from a Boolean", BOOLEAN_VALUE, boolean.class, BOOLEAN_VALUE}, - new Object[]{"Tests that the method returns a boolean value from a String", TRUE_AS_STRING, boolean.class, BOOLEAN_VALUE}, - new Object[]{"Tests that the method returns a boolean value from a BigInteger", BigInteger.ZERO, boolean.class, Boolean.FALSE}, - new Object[]{"Tests that the method returns a boolean value from a BigDecimal", BigDecimal.ZERO, boolean.class, Boolean.FALSE}, - new Object[]{"Tests that the method returns a boolean value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, boolean.class, BOOLEAN_VALUE}); + new Object[]{"Tests that the method returns a BigDecimal value from a byte[]", EIGHT_BYTE_BYTE_ARRAY, BigDecimal.class, + BigDecimal.valueOf(wrap(EIGHT_BYTE_BYTE_ARRAY).getDouble())}); } /** From 0fe6f91227d28bb439014eb57cf0bf35796c2015 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 8 Aug 2019 07:04:30 +0200 Subject: [PATCH 0787/1786] removed redundant suppression --- config/checkstyle/suppression.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/config/checkstyle/suppression.xml b/config/checkstyle/suppression.xml index 5aa9cea07..d9856d598 100644 --- a/config/checkstyle/suppression.xml +++ b/config/checkstyle/suppression.xml @@ -9,7 +9,7 @@ - + @@ -20,7 +20,4 @@ - - - \ No newline at end of file From f81e34a837747eb36ea980ff20ec629ae6a00f47 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 8 Aug 2019 14:09:01 +0200 Subject: [PATCH 0788/1786] - Cleaned-up code - Removed redundant method --- .../hotels/beans/populator/MapPopulator.java | 13 ++++++- .../beans/transformer/TransformerImpl.java | 19 +++++++++- .../com/hotels/beans/utils/ClassUtils.java | 37 +++++++------------ .../hotels/beans/validator/ValidatorImpl.java | 25 ++++++++----- .../hotels/beans/utils/ClassUtilsTest.java | 33 +---------------- 5 files changed, 58 insertions(+), 69 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java index 02bb81705..882a2c3bb 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -57,8 +57,8 @@ class MapPopulator extends Populator> { private Map getPopulatedObject(final Map fieldValue, final MapType mapType) { final MapElemType keyType = mapType.getKeyType(); final MapElemType elemType = mapType.getElemType(); - final boolean keyIsPrimitive = keyType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) keyType).getObjectClass()); - final boolean elemIsPrimitive = elemType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) elemType).getObjectClass()); + final boolean keyIsPrimitive = isPrimitive(keyType); + final boolean elemIsPrimitive = isPrimitive(elemType); Map populatedObject; if (keyIsPrimitive && elemIsPrimitive) { populatedObject = fieldValue; @@ -73,6 +73,15 @@ class MapPopulator extends Populator> { return populatedObject; } + /** + * Checks if the map element type is primitive or not. + * @param mapElemType the map element to check + * @return true if it's primitive, false otherwise + */ + private boolean isPrimitive(final MapElemType mapElemType) { + return mapElemType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) mapElemType).getObjectClass()); + } + /** * Gets the value of a given key/elem (including complex types). * @param the object type diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 15c98bf1f..6b09080cf 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -40,6 +40,7 @@ import java.lang.reflect.Parameter; import java.util.List; import java.util.Optional; +import java.util.function.Consumer; import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.constant.ClassType; @@ -258,7 +259,21 @@ private void injectAllFields(final T sourceObj, final K targetObject, fin final Class targetObjectClass = targetObject.getClass(); classUtils.getDeclaredFields(targetObjectClass, true) //.parallelStream() - .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); + .forEach(setFieldValue(sourceObj, targetObject, breadcrumb, targetObjectClass)); + } + + /** + * Creates a {@link Consumer} that sets the field value in the given class. + * @param sourceObj sourceObj the source object + * @param targetObject the destination object instance + * @param breadcrumb the full path of the current field starting from his ancestor + * @param targetObjectClass the target object class + * @param the sourceObj object type + * @param the target object type + * @return a {@link Consumer} that sets the field value in the target object + */ + private Consumer setFieldValue(final T sourceObj, final K targetObject, final String breadcrumb, final Class targetObjectClass) { + return field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb)); } /** @@ -274,7 +289,7 @@ private void injectNotFinalFields(final T sourceObj, final K targetObject final Class targetObjectClass = targetObject.getClass(); classUtils.getNotFinalFields(targetObjectClass, true) //.parallelStream() - .forEach(field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb))); + .forEach(setFieldValue(sourceObj, targetObject, breadcrumb, targetObjectClass)); } /** diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java index 36d3df6cf..9a6f2033c 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java @@ -28,7 +28,6 @@ import static java.util.Arrays.stream; import static java.util.Collections.max; import static java.util.Comparator.comparing; -import static java.util.Objects.isNull; import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; import static java.util.Set.of; @@ -99,7 +98,6 @@ public final class ClassUtils { */ private final ReflectionUtils reflectionUtils; - /** * Default constructor. */ @@ -284,7 +282,7 @@ public List getPrivateFinalFields(final Class clazz) { final String cacheKey = "PrivateFinalFields-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); - if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { + if (hasSuperclass(clazz.getSuperclass())) { res.addAll(getPrivateFinalFields(clazz.getSuperclass())); } res.addAll(stream(getDeclaredFields(clazz)) @@ -296,6 +294,15 @@ public List getPrivateFinalFields(final Class clazz) { }); } + /** + * Checks if a class has a clazz different from {@link Object}. + * @param clazz the class to check. + * @return true if the given class extends another class different from object + */ + private boolean hasSuperclass(final Class clazz) { + return nonNull(clazz) && !clazz.equals(Object.class); + } + /** * Return the total fields matching with the given predicate. * @param clazz class from which gets the field @@ -336,7 +343,7 @@ public List getPrivateFields(final Class clazz, final boolean skipFina final String cacheKey = "PrivateFields-" + clazz.getName() + "-skipFinal-" + skipFinal; return CACHE_MANAGER.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); - if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { + if (hasSuperclass(clazz.getSuperclass())) { res.addAll(getPrivateFields(clazz.getSuperclass(), skipFinal)); } res.addAll(stream(getDeclaredFields(clazz)) @@ -361,7 +368,7 @@ public List getDeclaredFields(final Class clazz, final boolean skipSta final String cacheKey = "DeclaredFields-" + clazz.getName() + "-skipStatic-" + skipStatic; return CACHE_MANAGER.getFromCache(cacheKey, List.class).orElseGet(() -> { final List res = new ArrayList<>(); - if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { + if (hasSuperclass(clazz.getSuperclass())) { res.addAll(getDeclaredFields(clazz.getSuperclass(), skipStatic)); } stream(getDeclaredFields(clazz)) @@ -507,7 +514,7 @@ public boolean hasField(final Object target, final String fieldName) { } catch (final NoSuchFieldException e) { hasField = false; final Class superclass = target.getClass().getSuperclass(); - if (nonNull(superclass) && !superclass.equals(Object.class)) { + if (hasSuperclass(superclass)) { hasField = hasField(superclass, fieldName); } } @@ -589,22 +596,6 @@ private boolean hasFieldsMatchingCondition(final Class clazz, final Predicate }); } - /** - * Checks if the class constructor's parameters are annotated with the given class. - * @param constructor the constructor to check. - * @param annotationClass the annotation class to retrieve - * @return true if any of the parameter contains the annotation, false otherwise. - */ - public boolean containsAnnotation(final Constructor constructor, final Class annotationClass) { - final String cacheKey = "ConstructorHasAnnotation-" + constructor.getDeclaringClass().getName() + '-' + annotationClass.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final boolean containsAnnotation = stream(constructor.getParameters()) - .noneMatch(parameter -> isNull(parameter.getAnnotation(annotationClass))); - CACHE_MANAGER.cacheObject(cacheKey, containsAnnotation); - return containsAnnotation; - }); - } - /** * Checks if any of the class constructor's parameters are not annotated with the given class. * @param constructor the constructor to check. @@ -672,7 +663,7 @@ public List getSetterMethods(final Class clazz) { final String cacheKey = "SetterMethods-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, List.class).orElseGet(() -> { final List setterMethods = new LinkedList<>(); - if (nonNull(clazz.getSuperclass()) && !clazz.getSuperclass().equals(Object.class)) { + if (hasSuperclass(clazz.getSuperclass())) { setterMethods.addAll(getSetterMethods(clazz.getSuperclass())); } setterMethods.addAll(stream(getDeclaredMethods(clazz)) diff --git a/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java index 13ab2a9ae..1d3668e3f 100644 --- a/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java @@ -29,6 +29,7 @@ import java.util.List; import java.util.Set; +import java.util.function.Function; import javax.validation.ConstraintViolation; @@ -66,11 +67,7 @@ public final Set> getConstraintViolations(final @Override public final List getConstraintViolationsMessages(final K k) { return getConstraintViolations(k).stream() - .map(cv -> cv.getRootBeanClass().getName() - + DOT.getSymbol() - + cv.getPropertyPath() - + SPACE - + cv.getMessage()) + .map(getConstraintViolationMessage()) .collect(toList()); } @@ -82,16 +79,24 @@ public final void validate(final K k) { final Set> constraintViolations = getConstraintViolations(k); if (!constraintViolations.isEmpty()) { final String errors = constraintViolations.stream() - .map(cv -> cv.getRootBeanClass().getName() - + DOT.getSymbol() - + cv.getPropertyPath() - + SPACE - + cv.getMessage()) + .map(getConstraintViolationMessage()) .collect(joining(SEMICOLON.getSymbol())); throw new InvalidBeanException(errors); } } + /** + * Creates a function that, given a constraint error, builds a violation message. + * @return the constaint violation message + */ + private Function, String> getConstraintViolationMessage() { + return cv -> cv.getRootBeanClass().getName() + + DOT.getSymbol() + + cv.getPropertyPath() + + SPACE + + cv.getMessage(); + } + /** * Creates the validator. * @return a {@link javax.validation.Validator} instance. diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java index 18a2782b7..a89b915d8 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java @@ -641,37 +641,6 @@ private Object[][] dataHasSetterMethodsTesting() { }; } - /** - * Tests that the method {@code containsAnnotation} works as expected. - * @param testCaseDescription the test case description - * @param annotationClass the annotation to search - * @param expectedResult the expected result - */ - @Test(dataProvider = "dataContainsAnnotationTesting") - public void testContainsAnnotationWorksAsExpected(final String testCaseDescription, final Class annotationClass, final boolean expectedResult) { - // GIVEN - Constructor constructor = ImmutableToFooCustomAnnotation.class.getConstructors()[0]; - - - // WHEN - boolean actual = underTest.containsAnnotation(constructor, annotationClass); - - // THEN - assertEquals(expectedResult, actual); - } - - /** - * Creates the parameters to be used for testing the method {@code containsAnnotation}. - * @return parameters to be used for testing the the method {@code containsAnnotation}. - */ - @DataProvider - private Object[][] dataContainsAnnotationTesting() { - return new Object[][] { - {"Tests that the method returns true if the constructor contains parameters annotated with @ConstructorArg", ConstructorArg.class, true}, - {"Tests that the method returns false if the constructor does not contain parameters annotated with @NotNull", NotNull.class, false}, - }; - } - /** * Tests that the method {@code notAllParameterAnnotatedWith} works as expected. * @param testCaseDescription the test case description @@ -699,7 +668,7 @@ public void testAllParameterAnnotatedWithWorksAsExpected(final String testCaseDe private Object[][] dataNotAllParameterAnnotatedWithTesting() { return new Object[][] { {"Tests that the method returns true if all constructor's parameter are annotated with @ConstructorArg", ConstructorArg.class, true}, - {"Tests that the method returns false if not all constructor's parameter are annotated with @NotNull", NotNull.class, false}, + {"Tests that the method returns false if not all constructor's parameter are annotated with @NotNull", NotNull.class, false} }; } From f0564a3c1a9d4c6b6327c00067d164e08278888b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2019 02:44:59 +0000 Subject: [PATCH 0789/1786] Bump slf4j-api from 1.7.27 to 1.7.28 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.27 to 1.7.28. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.27...v_1.7.28) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4dcab1cfe..a20c322af 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 2.0.1.Final 6.0.17.Final - 1.7.27 + 1.7.28 3.0.0 2.2.6 From 01fc4229705bc97c913728a19c12c999c1c78391 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Aug 2019 17:23:44 +0200 Subject: [PATCH 0790/1786] Fixed Populator class methods javadoc --- .../src/main/java/com/hotels/beans/populator/Populator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java index c7a9c883f..a8d1a122e 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java @@ -56,7 +56,7 @@ public abstract class Populator { } /** - * Populates the array of the target object with the values into the source object. + * Populates the target object with the values into the source object. * @param field the field to be populated * @param fieldValue the source object from which extract the values * @return a populated list of elements @@ -64,7 +64,7 @@ public abstract class Populator { protected abstract O getPopulatedObject(Field field, O fieldValue); /** - * Populates the array of the target object with the values into the source object. + * Populates the target object with the values into the source object. * @param the target object type * @param targetClass the destination object class * @param fieldName the field to be populated @@ -76,7 +76,7 @@ public final O getPopulatedObject(final Class targetClass, final String f } /** - * Wrapper method for BeanUtil transform method. + * Wrapper method for {@link com.hotels.beans.BeanUtils} transform method. * @param sourceObj the source object * @param targetClass the destination object class * @param the Source object type From 7bb607be2a353f677488da55e4ae3cb119048228 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2019 02:47:18 +0000 Subject: [PATCH 0791/1786] Bump testng from 6.14.3 to 7.0.0 Bumps [testng](https://github.com/cbeust/testng) from 6.14.3 to 7.0.0. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/compare/6.14.3...7.0.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a20c322af..229a4611d 100644 --- a/pom.xml +++ b/pom.xml @@ -37,7 +37,7 @@ 3.9 0.11 2.8.5 - 6.14.3 + 7.0.0 2.0.1.Final 6.0.17.Final From d8240013ae8225b601c6ee0343ddb44451ef7115 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 19 Aug 2019 07:03:00 +0200 Subject: [PATCH 0792/1786] Updated dependencies --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 229a4611d..118f0c22d 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,7 @@ 0.11 2.8.5 7.0.0 + 1.3.0 2.0.1.Final 6.0.17.Final @@ -56,6 +57,7 @@ 3.3.3 0.12 github + 3.8.2 false true From 86c344453851aa72f0e054b225a53fba1e4bb9b8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 19 Aug 2019 08:42:52 +0200 Subject: [PATCH 0793/1786] Excluded duplicated dependency --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 118f0c22d..80967461c 100644 --- a/pom.xml +++ b/pom.xml @@ -135,6 +135,10 @@ junit junit + + com.google.guava + guava + From 782b38450597e323a3c92e16c4b5098b44335945 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 19 Aug 2019 08:57:53 +0200 Subject: [PATCH 0794/1786] Removed duplicated dependency with different versions --- pom.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 80967461c..8619db669 100644 --- a/pom.xml +++ b/pom.xml @@ -135,10 +135,6 @@ junit junit - - com.google.guava - guava - @@ -152,6 +148,12 @@ testng ${testng.version} test + + + com.google.guava + guava + + From 84d70d79a21daf1ef189e23bc1d585cd3e4048f9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Aug 2019 15:50:03 +0200 Subject: [PATCH 0795/1786] - Created new module for transforming Map object. The build has to be triggered using the profile: map-transformer - Moved common object among different transformer in a common module --- bean-utils-library/pom.xml | 2 +- .../main/java/com/hotels/beans/BeanUtils.java | 16 ++--- .../beans/populator/ArrayPopulator.java | 4 +- .../beans/populator/CollectionPopulator.java | 4 +- .../hotels/beans/populator/MapPopulator.java | 10 +-- .../beans/populator/OptionalPopulator.java | 4 +- .../com/hotels/beans/populator/Populator.java | 12 ++-- .../beans/populator/PopulatorFactory.java | 4 +- .../transformer/AbstractTransformer.java | 38 +++++------ ...{Transformer.java => BeanTransformer.java} | 68 +++++++------------ .../beans/transformer/TransformerImpl.java | 24 +++---- .../transformer/TransformerSettings.java | 4 +- .../java/com/hotels/beans/BeanUtilsTest.java | 6 +- .../beans/performance/PerformanceTest.java | 4 +- .../beans/populator/ArrayPopulatorTest.java | 4 +- .../beans/populator/PopulatorFactoryTest.java | 4 +- ....java => AbstractBeanTransformerTest.java} | 6 +- ...rmerTest.java => BeanTransformerTest.java} | 32 ++++----- .../BuilderObjectTransformationTest.java | 4 +- .../ImmutableObjectTransformationTest.java | 26 +++---- .../MixedObjectTransformationTest.java | 12 ++-- .../MutableObjectTransformationTest.java | 10 +-- .../com/hotels/beans/model/package-info.java | 20 ------ .../java/com/hotels/beans/package-info.java | 20 ------ .../com/hotels/transformer/Transformer.java | 43 ++++++++++++ .../annotation/ConstructorArg.java | 2 +- .../annotation/package-info.java | 2 +- .../{beans => transformer}/base/Defaults.java | 18 ++--- .../base/package-info.java | 2 +- .../cache/CacheManager.java | 2 +- .../cache/CacheManagerFactory.java | 4 +- .../transformer}/cache/package-info.java | 2 +- .../constant/ClassType.java | 2 +- .../constant/Filters.java | 2 +- .../constant/MethodPrefix.java | 2 +- .../constant/Punctuation.java | 2 +- .../constant/package-info.java | 2 +- .../error/InstanceCreationException.java | 2 +- .../error/InvalidBeanException.java | 2 +- .../error/MissingFieldException.java | 2 +- .../error/MissingMethodException.java | 2 +- .../error/package-info.java | 2 +- .../model/EmptyValue.java | 2 +- .../transformer}/model/FieldMapping.java | 2 +- .../transformer}/model/FieldTransformer.java | 2 +- .../model/ItemType.java | 2 +- .../model/MapElemType.java | 2 +- .../{beans => transformer}/model/MapType.java | 2 +- .../transformer}/model/package-info.java | 2 +- .../com/hotels/transformer/package-info.java | 20 ++++++ .../utils/ClassUtils.java | 28 ++++---- .../utils/ReflectionUtils.java | 26 +++---- .../utils/package-info.java | 2 +- .../validator/Validator.java | 4 +- .../validator/ValidatorImpl.java | 12 ++-- .../validator/package-info.java | 2 +- .../hotels/beans/sample/FromFooAdvFields.java | 2 +- .../immutable/ImmutableToFooAdvFields.java | 2 +- .../ImmutableToFooCustomAnnotation.java | 2 +- ...ImmutableToFooMissingCustomAnnotation.java | 2 +- .../ImmutableToSubFooCustomAnnotation.java | 2 +- .../sample/mixed/MixedToFooDiffFields.java | 2 +- .../sample/mutable/MutableToFooAdvFields.java | 2 +- .../base/DefaultsTest.java | 2 +- .../base/package-info.java | 2 +- .../cache/CacheManagerFactoryTest.java | 2 +- .../cache/CacheManagerTest.java | 2 +- .../transformer}/cache/package-info.java | 2 +- .../utils/ClassUtilsTest.java | 10 +-- .../utils/ReflectionUtilsTest.java | 16 ++--- .../utils/package-info.java | 2 +- .../validator/ValidatorTest.java | 4 +- .../validator/package-info.java | 2 +- .../beans/conversion/ConverterImpl.java | 2 +- .../analyzer/ConversionAnalyzer.java | 30 ++++---- .../processor/ConversionProcessorFactory.java | 24 +++---- bull-map-transformer/pom.xml | 16 +++++ docs/site/markdown/transformer/testing.md | 8 +-- pom.xml | 19 +++++- 79 files changed, 366 insertions(+), 332 deletions(-) rename bean-utils-library/src/main/java/com/hotels/beans/transformer/{Transformer.java => BeanTransformer.java} (60%) rename bean-utils-library/src/test/java/com/hotels/beans/transformer/{AbstractTransformerTest.java => AbstractBeanTransformerTest.java} (97%) rename bean-utils-library/src/test/java/com/hotels/beans/transformer/{TransformerTest.java => BeanTransformerTest.java} (94%) delete mode 100644 bull-common/src/main/java/com/hotels/beans/model/package-info.java delete mode 100644 bull-common/src/main/java/com/hotels/beans/package-info.java create mode 100644 bull-common/src/main/java/com/hotels/transformer/Transformer.java rename bull-common/src/main/java/com/hotels/{beans => transformer}/annotation/ConstructorArg.java (97%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/annotation/package-info.java (93%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/base/Defaults.java (73%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/base/package-info.java (94%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/cache/CacheManager.java (98%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/cache/CacheManagerFactory.java (93%) rename bull-common/src/{test/java/com/hotels/beans => main/java/com/hotels/transformer}/cache/package-info.java (94%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/constant/ClassType.java (96%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/constant/Filters.java (97%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/constant/MethodPrefix.java (96%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/constant/Punctuation.java (96%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/constant/package-info.java (93%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/error/InstanceCreationException.java (97%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/error/InvalidBeanException.java (98%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/error/MissingFieldException.java (96%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/error/MissingMethodException.java (97%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/error/package-info.java (94%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/model/EmptyValue.java (95%) rename {bean-utils-library/src/main/java/com/hotels/beans => bull-common/src/main/java/com/hotels/transformer}/model/FieldMapping.java (96%) rename {bean-utils-library/src/main/java/com/hotels/beans => bull-common/src/main/java/com/hotels/transformer}/model/FieldTransformer.java (98%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/model/ItemType.java (96%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/model/MapElemType.java (94%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/model/MapType.java (96%) rename {bean-utils-library/src/main/java/com/hotels/beans => bull-common/src/main/java/com/hotels/transformer}/model/package-info.java (94%) create mode 100644 bull-common/src/main/java/com/hotels/transformer/package-info.java rename bull-common/src/main/java/com/hotels/{beans => transformer}/utils/ClassUtils.java (96%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/utils/ReflectionUtils.java (97%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/utils/package-info.java (94%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/validator/Validator.java (93%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/validator/ValidatorImpl.java (90%) rename bull-common/src/main/java/com/hotels/{beans => transformer}/validator/package-info.java (93%) rename bull-common/src/test/java/com/hotels/{beans => transformer}/base/DefaultsTest.java (98%) rename bull-common/src/test/java/com/hotels/{beans => transformer}/base/package-info.java (94%) rename bull-common/src/test/java/com/hotels/{beans => transformer}/cache/CacheManagerFactoryTest.java (98%) rename bull-common/src/test/java/com/hotels/{beans => transformer}/cache/CacheManagerTest.java (98%) rename bull-common/src/{main/java/com/hotels/beans => test/java/com/hotels/transformer}/cache/package-info.java (94%) rename bull-common/src/test/java/com/hotels/{beans => transformer}/utils/ClassUtilsTest.java (99%) rename bull-common/src/test/java/com/hotels/{beans => transformer}/utils/ReflectionUtilsTest.java (98%) rename bull-common/src/test/java/com/hotels/{beans => transformer}/utils/package-info.java (94%) rename bull-common/src/test/java/com/hotels/{beans => transformer}/validator/ValidatorTest.java (98%) rename bull-common/src/test/java/com/hotels/{beans => transformer}/validator/package-info.java (93%) create mode 100644 bull-map-transformer/pom.xml diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 7cc0f7388..c44e9dae2 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - BULL - Core + BULL - Bean Transformer bean-utils-library jar diff --git a/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java b/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java index ac41b0162..3aac1360c 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java @@ -16,16 +16,16 @@ package com.hotels.beans; -import static com.hotels.beans.validator.Validator.notNull; +import static com.hotels.transformer.validator.Validator.notNull; import java.util.function.Function; import com.hotels.beans.conversion.Converter; import com.hotels.beans.conversion.ConverterImpl; -import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.BeanTransformer; import com.hotels.beans.transformer.TransformerImpl; -import com.hotels.beans.validator.Validator; -import com.hotels.beans.validator.ValidatorImpl; +import com.hotels.transformer.validator.Validator; +import com.hotels.transformer.validator.ValidatorImpl; /** * Set of Bean utilities. @@ -47,22 +47,22 @@ public static Function getTransformer(final Class targetClass) { /** * Returns a function that transforms an object T in an object K. * @param beanTransformer the transformer to be used. - * @param targetClass the destination object class + * @param targetClass the destination object classClassUtilsTest.java * @param the Source object type * @param the target object type * @return a function that copies of the source object into the destination object * @throws IllegalArgumentException if any parameter is invalid */ - public static Function getTransformer(final Transformer beanTransformer, final Class targetClass) { + public static Function getTransformer(final BeanTransformer beanTransformer, final Class targetClass) { notNull(beanTransformer, "beanTransformer cannot be null!"); return fromBean -> beanTransformer.transform(fromBean, targetClass); } /** * Returns a Bean Transformer. - * @return a {@link Transformer} instance. + * @return a {@link BeanTransformer} instance. */ - public final Transformer getTransformer() { + public final BeanTransformer getTransformer() { return new TransformerImpl(); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index 5ea3e38fb..afa9c0bd3 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -20,7 +20,7 @@ import java.lang.reflect.Field; -import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.BeanTransformer; /** * Populator for primitive types array. @@ -31,7 +31,7 @@ class ArrayPopulator extends Populator implements ICollectionPopulator extends Populator implements ICollectio * Default constructor. * @param beanTransformer the bean transformer containing the field name mapping and transformation functions */ - CollectionPopulator(final Transformer beanTransformer) { + CollectionPopulator(final BeanTransformer beanTransformer) { super(beanTransformer); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java index 882a2c3bb..10fb1d250 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -21,10 +21,10 @@ import java.lang.reflect.Field; import java.util.Map; -import com.hotels.beans.model.ItemType; -import com.hotels.beans.model.MapElemType; -import com.hotels.beans.model.MapType; -import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.BeanTransformer; +import com.hotels.transformer.model.ItemType; +import com.hotels.transformer.model.MapElemType; +import com.hotels.transformer.model.MapType; /** * Populator for Map types object {@link Map}. @@ -35,7 +35,7 @@ class MapPopulator extends Populator> { * Default constructor. * @param beanTransformer the bean transformer containing the field name mapping and transformation functions */ - MapPopulator(final Transformer beanTransformer) { + MapPopulator(final BeanTransformer beanTransformer) { super(beanTransformer); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index cf484731c..b33ac4717 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -21,7 +21,7 @@ import java.lang.reflect.Field; import java.util.Optional; -import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.BeanTransformer; /** * Populator for {@link Optional} type. @@ -32,7 +32,7 @@ class OptionalPopulator extends Populator { * Default constructor. * @param beanTransformer the bean transformer containing the field name mapping and transformation functions */ - OptionalPopulator(final Transformer beanTransformer) { + OptionalPopulator(final BeanTransformer beanTransformer) { super(beanTransformer); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java index a8d1a122e..9791a8054 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java @@ -21,9 +21,9 @@ import java.lang.reflect.Field; import java.util.Optional; -import com.hotels.beans.transformer.Transformer; -import com.hotels.beans.utils.ClassUtils; -import com.hotels.beans.utils.ReflectionUtils; +import com.hotels.beans.transformer.BeanTransformer; +import com.hotels.transformer.utils.ClassUtils; +import com.hotels.transformer.utils.ReflectionUtils; /** * Populator for collection or map objects. @@ -41,15 +41,15 @@ public abstract class Populator { final ClassUtils classUtils; /** - * Transformer class instance {@link Transformer} containing the field mapping and transformation functions. + * Transformer class instance {@link BeanTransformer} containing the field mapping and transformation functions. */ - private final Transformer transformer; + private final BeanTransformer transformer; /** * Default constructor. * @param beanTransformer the bean transformer containing the field name mapping and transformation functions */ - Populator(final Transformer beanTransformer) { + Populator(final BeanTransformer beanTransformer) { transformer = beanTransformer; reflectionUtils = new ReflectionUtils(); classUtils = new ClassUtils(); diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/bean-utils-library/src/main/java/com/hotels/beans/populator/PopulatorFactory.java index 721006d24..eaddc5ad0 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/populator/PopulatorFactory.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/populator/PopulatorFactory.java @@ -25,7 +25,7 @@ import java.util.Map; import java.util.Optional; -import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.BeanTransformer; import lombok.NoArgsConstructor; @@ -43,7 +43,7 @@ public final class PopulatorFactory { * @param transformer the bean transformer containing the field name mapping and transformation functions * @return the populator instance */ - public static Optional getPopulator(final Class destObjectClass, final Class sourceObjectClass, final Transformer transformer) { + public static Optional getPopulator(final Class destObjectClass, final Class sourceObjectClass, final BeanTransformer transformer) { Optional populator = empty(); if (destObjectClass.isArray()) { populator = of(new ArrayPopulator(transformer)); diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index 9f3ac935c..b8a2412b3 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -18,25 +18,25 @@ import static java.util.Arrays.asList; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.validator.Validator.notNull; +import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.transformer.validator.Validator.notNull; import java.util.Map; -import com.hotels.beans.cache.CacheManager; import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; -import com.hotels.beans.model.FieldMapping; -import com.hotels.beans.model.FieldTransformer; -import com.hotels.beans.utils.ClassUtils; -import com.hotels.beans.utils.ReflectionUtils; -import com.hotels.beans.validator.Validator; -import com.hotels.beans.validator.ValidatorImpl; +import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.model.FieldMapping; +import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.utils.ClassUtils; +import com.hotels.transformer.utils.ReflectionUtils; +import com.hotels.transformer.validator.Validator; +import com.hotels.transformer.validator.ValidatorImpl; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. - * Contains all method implementation that will be common to any {@link Transformer} implementation. + * Contains all method implementation that will be common to any {@link BeanTransformer} implementation. */ -abstract class AbstractTransformer implements Transformer { +abstract class AbstractTransformer implements BeanTransformer { /** * The cache key prefix for the Transformer Functions. */ @@ -91,7 +91,7 @@ abstract class AbstractTransformer implements Transformer { * {@inheritDoc} */ @Override - public final Transformer withFieldMapping(final FieldMapping... fieldMapping) { + public final BeanTransformer withFieldMapping(final FieldMapping... fieldMapping) { final Map fieldsNameMapping = settings.getFieldsNameMapping(); for (FieldMapping mapping : fieldMapping) { fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); @@ -120,7 +120,7 @@ public final void resetFieldsMapping() { * {@inheritDoc} */ @Override - public final Transformer withFieldTransformer(final FieldTransformer... fieldTransformer) { + public final BeanTransformer withFieldTransformer(final FieldTransformer... fieldTransformer) { Map fieldsTransformers = settings.getFieldsTransformers(); for (FieldTransformer transformer : fieldTransformer) { fieldsTransformers.put(transformer.getDestFieldName(), transformer); @@ -151,7 +151,7 @@ public final void resetFieldsTransformer() { * {@inheritDoc} */ @Override - public final Transformer setDefaultValueForMissingField(final boolean useDefaultValue) { + public final BeanTransformer setDefaultValueForMissingField(final boolean useDefaultValue) { settings.setSetDefaultValueForMissingField(useDefaultValue); return this; } @@ -160,7 +160,7 @@ public final Transformer setDefaultValueForMissingField(final boolean useDefault * {@inheritDoc} */ @Override - public final Transformer setFlatFieldNameTransformation(final boolean useFlatTransformation) { + public final BeanTransformer setFlatFieldNameTransformation(final boolean useFlatTransformation) { settings.setFlatFieldNameTransformation(useFlatTransformation); return this; } @@ -169,7 +169,7 @@ public final Transformer setFlatFieldNameTransformation(final boolean useFlatTra * {@inheritDoc} */ @Override - public Transformer setValidationEnabled(final boolean validationEnabled) { + public BeanTransformer setValidationEnabled(final boolean validationEnabled) { settings.setValidationEnabled(validationEnabled); if (validationEnabled) { validator = new ValidatorImpl(); @@ -181,7 +181,7 @@ public Transformer setValidationEnabled(final boolean validationEnabled) { * {@inheritDoc} */ @Override - public Transformer setDefaultValueSetEnabled(final boolean defaultValueSetEnabled) { + public BeanTransformer setDefaultValueSetEnabled(final boolean defaultValueSetEnabled) { settings.setDefaultValueSetEnabled(defaultValueSetEnabled); return this; } @@ -190,7 +190,7 @@ public Transformer setDefaultValueSetEnabled(final boolean defaultValueSetEnable * {@inheritDoc} */ @Override - public Transformer setPrimitiveTypeConversionEnabled(final boolean primitiveTypeConversionEnabled) { + public BeanTransformer setPrimitiveTypeConversionEnabled(final boolean primitiveTypeConversionEnabled) { settings.setPrimitiveTypeConversionEnabled(primitiveTypeConversionEnabled); if (primitiveTypeConversionEnabled) { conversionAnalyzer = new ConversionAnalyzer(); @@ -235,7 +235,7 @@ public final void transform(final T sourceObj, final K targetObject) { * {@inheritDoc} */ @Override - public Transformer skipTransformationForField(final String... fieldName) { + public BeanTransformer skipTransformationForField(final String... fieldName) { if (fieldName.length != 0) { settings.getFieldsToSkip().addAll(asList(fieldName)); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/BeanTransformer.java similarity index 60% rename from bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java rename to bean-utils-library/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index 3983d9c6e..a208c2309 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -16,41 +16,21 @@ package com.hotels.beans.transformer; -import com.hotels.beans.model.FieldMapping; -import com.hotels.beans.model.FieldTransformer; +import com.hotels.transformer.Transformer; +import com.hotels.transformer.model.FieldMapping; +import com.hotels.transformer.model.FieldTransformer; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * The implementations are provided by BeanUtils. */ -public interface Transformer { - /** - * Copies all properties from an object to a new one. - * @param sourceObj the source object - * @param targetClass the destination object class - * @param the Source object type - * @param the target object type - * @return a copy of the source object into the destination object - * @throws IllegalArgumentException if any parameter is invalid - */ - K transform(T sourceObj, Class targetClass); - - /** - * Copies all properties from an object to a new one. - * @param sourceObj the source object - * @param targetObject the destination object - * @param the Source object type - * @param the target object type - * @throws IllegalArgumentException if any parameter is invalid - */ - void transform(T sourceObj, K targetObject); - +public interface BeanTransformer extends Transformer { /** * Initializes the mapping between fields in the source object and the destination one. * @param fieldMapping the field mapping - * @return the {@link Transformer} instance + * @return the {@link BeanTransformer} instance */ - Transformer withFieldMapping(FieldMapping... fieldMapping); + BeanTransformer withFieldMapping(FieldMapping... fieldMapping); /** * Removes the field mapping for the given field. @@ -66,9 +46,9 @@ public interface Transformer { /** * Initializes the field transformer functions. The transformer function returns directly the field value. * @param fieldTransformer the fields transformer function - * @return the {@link Transformer} instance + * @return the {@link BeanTransformer} instance */ - Transformer withFieldTransformer(FieldTransformer... fieldTransformer); + BeanTransformer withFieldTransformer(FieldTransformer... fieldTransformer); /** * Removes the field transformer for the given field. @@ -83,35 +63,35 @@ public interface Transformer { /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. - * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. - * @param useDefaultValue true in case the default value should be set, false if it should raise a: {@link com.hotels.beans.error.MissingFieldException} in case of missing - * field. - * @return the {@link Transformer} instance + * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. + * @param useDefaultValue true in case the default value should be set, false if it should raise a: + * {@link com.hotels.transformer.error.MissingFieldException} in case of missing field. + * @return the {@link BeanTransformer} instance */ - Transformer setDefaultValueForMissingField(boolean useDefaultValue); + BeanTransformer setDefaultValueForMissingField(boolean useDefaultValue); /** * It allows to configure the transformer in order to apply a transformation function on all fields matching the given name without keeping in consideration their full path. - * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. + * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. * @param useFlatTransformation indicates if the transformer function has to be performed on all fields matching the given name without keeping in consideration their full * path. - * @return the {@link Transformer} instance + * @return the {@link BeanTransformer} instance */ - Transformer setFlatFieldNameTransformation(boolean useFlatTransformation); + BeanTransformer setFlatFieldNameTransformation(boolean useFlatTransformation); /** * It allows to enable the object validation. * @param validationEnabled if true the validation is performed. - * @return the {@link Transformer} instance + * @return the {@link BeanTransformer} instance */ - Transformer setValidationEnabled(boolean validationEnabled); + BeanTransformer setValidationEnabled(boolean validationEnabled); /** * Allows to specify all the fields for which the transformation have to be skipped. * @param fieldName the destination object's field(s) name that have to be skipped - * @return the {@link Transformer} instance + * @return the {@link BeanTransformer} instance */ - Transformer skipTransformationForField(String... fieldName); + BeanTransformer skipTransformationForField(String... fieldName); /** * Removes all the configured fields to skip. @@ -121,14 +101,14 @@ public interface Transformer { /** * It allows to enable/disable the set of the default value for primitive types in case they are null. * @param defaultValueSetEnabled if true the default value for the primitive type is set. By default it's true. - * @return the {@link Transformer} instance + * @return the {@link BeanTransformer} instance */ - Transformer setDefaultValueSetEnabled(boolean defaultValueSetEnabled); + BeanTransformer setDefaultValueSetEnabled(boolean defaultValueSetEnabled); /** * It allows to enable/disable the automatic conversion of primitive types. * @param primitiveTypeConversionEnabled if true primitive types are transformed automatically. By default it's false. - * @return the {@link Transformer} instance + * @return the {@link BeanTransformer} instance */ - Transformer setPrimitiveTypeConversionEnabled(boolean primitiveTypeConversionEnabled); + BeanTransformer setPrimitiveTypeConversionEnabled(boolean primitiveTypeConversionEnabled); } diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 6b09080cf..f9eb00645 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -26,13 +26,13 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static com.hotels.beans.base.Defaults.defaultValue; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.Punctuation.COMMA; -import static com.hotels.beans.constant.Punctuation.DOT; -import static com.hotels.beans.constant.Punctuation.LPAREN; -import static com.hotels.beans.constant.Punctuation.RPAREN; +import static com.hotels.transformer.base.Defaults.defaultValue; +import static com.hotels.transformer.constant.ClassType.MIXED; +import static com.hotels.transformer.constant.ClassType.MUTABLE; +import static com.hotels.transformer.constant.Punctuation.COMMA; +import static com.hotels.transformer.constant.Punctuation.DOT; +import static com.hotels.transformer.constant.Punctuation.LPAREN; +import static com.hotels.transformer.constant.Punctuation.RPAREN; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; @@ -42,11 +42,11 @@ import java.util.Optional; import java.util.function.Consumer; -import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.constant.ClassType; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.error.MissingFieldException; -import com.hotels.beans.model.FieldTransformer; +import com.hotels.transformer.annotation.ConstructorArg; +import com.hotels.transformer.constant.ClassType; +import com.hotels.transformer.error.InvalidBeanException; +import com.hotels.transformer.error.MissingFieldException; +import com.hotels.transformer.model.FieldTransformer; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java index 902131bb3..7eddbb6bd 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java @@ -21,7 +21,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import com.hotels.beans.model.FieldTransformer; +import com.hotels.transformer.model.FieldTransformer; import lombok.Getter; import lombok.Setter; @@ -57,7 +57,7 @@ final class TransformerSettings { /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. - * If set to true the default value is set, if false if it raises a: {@link com.hotels.beans.error.MissingFieldException} in case of missing fields. + * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. */ @Setter private boolean setDefaultValueForMissingField; diff --git a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java index 8fd3b0f7f..b54784bdd 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -35,12 +35,12 @@ import org.testng.annotations.Test; import com.hotels.beans.conversion.Converter; -import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooSimple; -import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.BeanTransformer; +import com.hotels.transformer.error.InvalidBeanException; /** * Unit test for {@link BeanUtils}. @@ -72,7 +72,7 @@ public void testGetTransformerWorksProperly() { //GIVEN //WHEN - final Transformer transformer = underTest.getTransformer(); + final BeanTransformer transformer = underTest.getTransformer(); //THEN assertNotNull(transformer); diff --git a/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java index 2bdae6618..354eb7d58 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -48,7 +48,7 @@ import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.sample.mutable.MutableToFooSubClass; -import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.BeanTransformer; import lombok.extern.slf4j.Slf4j; @@ -116,7 +116,7 @@ public void testCopyPropertiesGetsCompletedInTheExpectedTime(final double totalT //WHEN StopWatch stopWatch = new StopWatch(); stopWatch.start(); - Transformer transformer = underTest.getTransformer(); + BeanTransformer transformer = underTest.getTransformer(); for (int i = 0; i <= totalTransformation; i++) { stopWatch.suspend(); sleep(waitInterval); diff --git a/bean-utils-library/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bean-utils-library/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 0d93745a6..f4d7e3094 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -35,7 +35,7 @@ import org.testng.annotations.Test; import com.hotels.beans.sample.mixed.MixedToFooStaticField; -import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.BeanTransformer; /** * Unit test for class: {@link ArrayPopulator}. @@ -51,7 +51,7 @@ public class ArrayPopulatorTest { private static final MixedToFooStaticField MIXED_TO_FOO_STATIC_FIELDS_OBJECTS = new MixedToFooStaticField(); @Mock - private Transformer transformer; + private BeanTransformer transformer; /** * The class to be tested. diff --git a/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index 58656c3dd..9e190d399 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -32,7 +32,7 @@ import org.testng.annotations.Test; import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.transformer.Transformer; +import com.hotels.beans.transformer.BeanTransformer; /** * Unit test for class: {@link PopulatorFactory}. @@ -48,7 +48,7 @@ public class PopulatorFactoryTest { * Transformer object. */ @Mock - private Transformer transformer; + private BeanTransformer transformer; /** * Initializes mock. diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java similarity index 97% rename from bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index c5f376ed5..585afa555 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -21,7 +21,7 @@ import static org.mockito.MockitoAnnotations.initMocks; -import static com.hotels.beans.constant.ClassType.IMMUTABLE; +import static com.hotels.transformer.constant.ClassType.IMMUTABLE; import java.math.BigDecimal; import java.math.BigInteger; @@ -45,9 +45,9 @@ import com.hotels.beans.sample.FromSubFoo; /** - * Unit test for {@link Transformer}. + * Unit test for {@link BeanTransformer}. */ -public abstract class AbstractTransformerTest { +public abstract class AbstractBeanTransformerTest { static final BigInteger ID = new BigInteger("1234"); static final String NAME = "Goofy"; static FromFoo fromFoo; diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java similarity index 94% rename from bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java rename to bean-utils-library/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 8d1666689..5ea9ab86f 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/TransformerTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -41,21 +41,21 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.cache.CacheManager; import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.error.MissingFieldException; -import com.hotels.beans.model.FieldMapping; -import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.mutable.MutableToFooAdvFields; -import com.hotels.beans.utils.ClassUtils; -import com.hotels.beans.utils.ReflectionUtils; +import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.error.InvalidBeanException; +import com.hotels.transformer.error.MissingFieldException; +import com.hotels.transformer.model.FieldMapping; +import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.utils.ClassUtils; +import com.hotels.transformer.utils.ReflectionUtils; /** - * Unit test for class: {@link Transformer}. + * Unit test for class: {@link BeanTransformer}. */ -public class TransformerTest extends AbstractTransformerTest { +public class BeanTransformerTest extends AbstractBeanTransformerTest { private static final String SOURCE_FIELD_NAME = "sourceFieldName"; private static final String SOURCE_FIELD_NAME_2 = "sourceFieldName2"; private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; @@ -74,7 +74,7 @@ public class TransformerTest extends AbstractTransformerTest { @Test public void testRemoveFieldMappingWorksProperly() { //GIVEN - Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); + BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); //WHEN beanTransformer.removeFieldMapping(DEST_FIELD_NAME); @@ -90,7 +90,7 @@ public void testRemoveFieldMappingWorksProperly() { @Test(expectedExceptions = IllegalArgumentException.class) public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { //GIVEN - Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); + BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); //WHEN beanTransformer.removeFieldMapping(null); @@ -102,7 +102,7 @@ public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { @Test public void testResetFieldsMappingWorksProperly() { //GIVEN - Transformer beanTransformer = underTest + BeanTransformer beanTransformer = underTest .withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME), new FieldMapping(SOURCE_FIELD_NAME_2, DEST_FIELD_NAME)); //WHEN @@ -119,7 +119,7 @@ public void testResetFieldsMappingWorksProperly() { @Test public void testResetFieldsTransformerWorksProperly() { //GIVEN - Transformer beanTransformer = underTest + BeanTransformer beanTransformer = underTest .withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val), new FieldTransformer<>(REFLECTION_UTILS_FIELD_NAME, val -> val)); //WHEN @@ -136,7 +136,7 @@ public void testResetFieldsTransformerWorksProperly() { @Test public void testRemoveFieldTransformerWorksProperly() { //GIVEN - Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); + BeanTransformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); //WHEN beanTransformer.removeFieldTransformer(DEST_FIELD_NAME); @@ -152,7 +152,7 @@ public void testRemoveFieldTransformerWorksProperly() { @Test(expectedExceptions = IllegalArgumentException.class) public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() { //GIVEN - Transformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); + BeanTransformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); //WHEN beanTransformer.removeFieldTransformer(null); @@ -438,7 +438,7 @@ private void restoreUnderTestObject() { } /** - * Tests that an instance fo {@link com.hotels.beans.validator.Validator} is created only if the validation is enabled. + * Tests that an instance fo {@link com.hotels.transformer.validator.Validator} is created only if the validation is enabled. * @param testCaseDescription the test case description * @param validationEnabled true if the validation is enabled, false otherwise * @param expectedNull the expected result diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 4bfbf9e80..3aa15de5c 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -29,9 +29,9 @@ import com.hotels.beans.sample.mutable.MutableToFooWithBuilderMultipleConstructor; /** - * Unit test for all {@link Transformer} functions related to Object based on Builder Pattern. + * Unit test for all {@link BeanTransformer} functions related to Object based on Builder Pattern. */ -public class BuilderObjectTransformationTest extends AbstractTransformerTest { +public class BuilderObjectTransformationTest extends AbstractBeanTransformerTest { /** * Test mutable,immutable,mixed beans are correctly copied through builder. * @param testDescription the test case description diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 0402c34e6..7c23abb45 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -43,11 +43,6 @@ import org.testng.annotations.Test; import com.hotels.beans.BeanUtils; -import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.model.FieldMapping; -import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooAdvFields; import com.hotels.beans.sample.FromFooSimple; @@ -65,12 +60,17 @@ import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.beans.utils.ReflectionUtils; +import com.hotels.transformer.annotation.ConstructorArg; +import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.error.InvalidBeanException; +import com.hotels.transformer.model.FieldMapping; +import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.utils.ReflectionUtils; /** - * Unit test for all {@link Transformer} functions related to Immutable Java Beans. + * Unit test for all {@link BeanTransformer} functions related to Immutable Java Beans. */ -public class ImmutableObjectTransformationTest extends AbstractTransformerTest { +public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTest { private static final int TOTAL_ADV_CLASS_FIELDS = 6; private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; @@ -92,8 +92,8 @@ public void afterMethod() { * @param targetObjectClass the target object class */ @Test(dataProvider = "dataDefaultTransformationTesting") - public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, final Transformer transformer, final Object sourceObject, - final Class targetObjectClass) { + public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, final BeanTransformer transformer, final Object sourceObject, + final Class targetObjectClass) { //GIVEN //WHEN @@ -227,7 +227,7 @@ public void testTransformThrowsExceptionWhenImmutableIsInvalid(final String test */ @DataProvider(parallel = true) private Object[][] dataInvalidBeanExceptionTesting() throws CloneNotSupportedException { - FromFoo fromFooNullId = AbstractTransformerTest.fromFoo.clone(); + FromFoo fromFooNullId = AbstractBeanTransformerTest.fromFoo.clone(); fromFooNullId.setId(null); return new Object[][] { {"Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object.", @@ -260,7 +260,7 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); + final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); //THEN @@ -285,7 +285,7 @@ public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String te //GIVEN //WHEN - final Transformer beanTransformer = underTest + final BeanTransformer beanTransformer = underTest .withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)) .withFieldMapping(new FieldMapping(PRICE_FIELD_NAME, NET_PRICE_FIELD_NAME)) .withFieldMapping(new FieldMapping(PRICE_FIELD_NAME, GROSS_PRICE_FIELD_NAME)) diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 53f193eee..a68687a8f 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -29,20 +29,20 @@ import org.testng.annotations.Test; -import com.hotels.beans.error.MissingFieldException; -import com.hotels.beans.model.FieldMapping; -import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.mixed.MixedToFoo; import com.hotels.beans.sample.mixed.MixedToFooDiffFields; import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; import com.hotels.beans.sample.mixed.MixedToFooMissingField; import com.hotels.beans.sample.mixed.MixedToFooNotExistingFields; +import com.hotels.transformer.error.MissingFieldException; +import com.hotels.transformer.model.FieldMapping; +import com.hotels.transformer.model.FieldTransformer; /** - * Unit test for all {@link Transformer} functions related to Mixed type Java Beans. + * Unit test for all {@link BeanTransformer} functions related to Mixed type Java Beans. */ -public class MixedObjectTransformationTest extends AbstractTransformerTest { +public class MixedObjectTransformationTest extends AbstractBeanTransformerTest { private static final boolean ACTIVE = true; /** @@ -81,7 +81,7 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); + final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); //THEN diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 82833cb1d..fd45bf6b7 100644 --- a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -29,9 +29,6 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.error.MissingFieldException; -import com.hotels.beans.model.FieldTransformer; import com.hotels.beans.sample.FromFooNoField; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSimpleNoGetters; @@ -42,11 +39,14 @@ import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; import com.hotels.beans.sample.mutable.MutableToFooSubClass; +import com.hotels.transformer.error.InvalidBeanException; +import com.hotels.transformer.error.MissingFieldException; +import com.hotels.transformer.model.FieldTransformer; /** - * Unit test for all {@link Transformer} functions related to Mutable type Java Beans. + * Unit test for all {@link BeanTransformer} functions related to Mutable type Java Beans. */ -public class MutableObjectTransformationTest extends AbstractTransformerTest { +public class MutableObjectTransformationTest extends AbstractBeanTransformerTest { private static final boolean ACTIVE = true; private static final String PRICE_FIELD_NAME = "price"; diff --git a/bull-common/src/main/java/com/hotels/beans/model/package-info.java b/bull-common/src/main/java/com/hotels/beans/model/package-info.java deleted file mode 100644 index 610dabb69..000000000 --- a/bull-common/src/main/java/com/hotels/beans/model/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Pojo package. - */ - -package com.hotels.beans.model; diff --git a/bull-common/src/main/java/com/hotels/beans/package-info.java b/bull-common/src/main/java/com/hotels/beans/package-info.java deleted file mode 100644 index 99cdebc36..000000000 --- a/bull-common/src/main/java/com/hotels/beans/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Main package. - */ - -package com.hotels.beans; diff --git a/bull-common/src/main/java/com/hotels/transformer/Transformer.java b/bull-common/src/main/java/com/hotels/transformer/Transformer.java new file mode 100644 index 000000000..c95420bda --- /dev/null +++ b/bull-common/src/main/java/com/hotels/transformer/Transformer.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.transformer; + +/** + * Utility methods for all objects transformation. + */ +public interface Transformer { + /** + * Copies all properties from an object to a new one. + * @param sourceObj the source object + * @param targetClass the destination object class + * @param the Source object type + * @param the target object type + * @return a copy of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + K transform(T sourceObj, Class targetClass); + + /** + * Copies all properties from an object to a new one. + * @param sourceObj the source object + * @param targetObject the destination object + * @param the Source object type + * @param the target object type + * @throws IllegalArgumentException if any parameter is invalid + */ + void transform(T sourceObj, K targetObject); +} diff --git a/bull-common/src/main/java/com/hotels/beans/annotation/ConstructorArg.java b/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java similarity index 97% rename from bull-common/src/main/java/com/hotels/beans/annotation/ConstructorArg.java rename to bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java index 5fda73ba1..3ab4cf5ae 100644 --- a/bull-common/src/main/java/com/hotels/beans/annotation/ConstructorArg.java +++ b/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.annotation; +package com.hotels.transformer.annotation; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; diff --git a/bull-common/src/main/java/com/hotels/beans/annotation/package-info.java b/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java similarity index 93% rename from bull-common/src/main/java/com/hotels/beans/annotation/package-info.java rename to bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java index 4710319a7..ff7c79ae5 100644 --- a/bull-common/src/main/java/com/hotels/beans/annotation/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java @@ -17,4 +17,4 @@ * Annotations package. */ -package com.hotels.beans.annotation; +package com.hotels.transformer.annotation; diff --git a/bull-common/src/main/java/com/hotels/beans/base/Defaults.java b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java similarity index 73% rename from bull-common/src/main/java/com/hotels/beans/base/Defaults.java rename to bull-common/src/main/java/com/hotels/transformer/base/Defaults.java index 62b5c96fe..d8876c939 100644 --- a/bull-common/src/main/java/com/hotels/beans/base/Defaults.java +++ b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.hotels.beans.base; +package com.hotels.transformer.base; import static java.lang.Boolean.FALSE; -import static com.hotels.beans.utils.ClassUtils.isBoolean; -import static com.hotels.beans.utils.ClassUtils.isByte; -import static com.hotels.beans.utils.ClassUtils.isChar; -import static com.hotels.beans.utils.ClassUtils.isDouble; -import static com.hotels.beans.utils.ClassUtils.isFloat; -import static com.hotels.beans.utils.ClassUtils.isInt; -import static com.hotels.beans.utils.ClassUtils.isLong; -import static com.hotels.beans.utils.ClassUtils.isShort; +import static com.hotels.transformer.utils.ClassUtils.isBoolean; +import static com.hotels.transformer.utils.ClassUtils.isByte; +import static com.hotels.transformer.utils.ClassUtils.isChar; +import static com.hotels.transformer.utils.ClassUtils.isDouble; +import static com.hotels.transformer.utils.ClassUtils.isFloat; +import static com.hotels.transformer.utils.ClassUtils.isInt; +import static com.hotels.transformer.utils.ClassUtils.isLong; +import static com.hotels.transformer.utils.ClassUtils.isShort; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-common/src/main/java/com/hotels/beans/base/package-info.java b/bull-common/src/main/java/com/hotels/transformer/base/package-info.java similarity index 94% rename from bull-common/src/main/java/com/hotels/beans/base/package-info.java rename to bull-common/src/main/java/com/hotels/transformer/base/package-info.java index aacbb7e4f..76a751413 100644 --- a/bull-common/src/main/java/com/hotels/beans/base/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/base/package-info.java @@ -17,4 +17,4 @@ * Base package. */ -package com.hotels.beans.base; +package com.hotels.transformer.base; diff --git a/bull-common/src/main/java/com/hotels/beans/cache/CacheManager.java b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java similarity index 98% rename from bull-common/src/main/java/com/hotels/beans/cache/CacheManager.java rename to bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java index 5f3667704..0fe22e4c4 100644 --- a/bull-common/src/main/java/com/hotels/beans/cache/CacheManager.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.cache; +package com.hotels.transformer.cache; import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; diff --git a/bull-common/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java similarity index 93% rename from bull-common/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java rename to bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java index 8a4fdd476..a9fc933b0 100644 --- a/bull-common/src/main/java/com/hotels/beans/cache/CacheManagerFactory.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.hotels.beans.cache; +package com.hotels.transformer.cache; -import static com.hotels.beans.validator.Validator.notNull; +import static com.hotels.transformer.validator.Validator.notNull; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-common/src/test/java/com/hotels/beans/cache/package-info.java b/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/cache/package-info.java rename to bull-common/src/main/java/com/hotels/transformer/cache/package-info.java index d9e881424..0b7cc17dc 100644 --- a/bull-common/src/test/java/com/hotels/beans/cache/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java @@ -17,4 +17,4 @@ * cache package. */ -package com.hotels.beans.cache; +package com.hotels.transformer.cache; diff --git a/bull-common/src/main/java/com/hotels/beans/constant/ClassType.java b/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java similarity index 96% rename from bull-common/src/main/java/com/hotels/beans/constant/ClassType.java rename to bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java index 0560eb236..50c2e1e61 100644 --- a/bull-common/src/main/java/com/hotels/beans/constant/ClassType.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.constant; +package com.hotels.transformer.constant; /** * Class type definition. diff --git a/bull-common/src/main/java/com/hotels/beans/constant/Filters.java b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java similarity index 97% rename from bull-common/src/main/java/com/hotels/beans/constant/Filters.java rename to bull-common/src/main/java/com/hotels/transformer/constant/Filters.java index f13ab1e2e..eb1cc6b4a 100644 --- a/bull-common/src/main/java/com/hotels/beans/constant/Filters.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.constant; +package com.hotels.transformer.constant; import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isStatic; diff --git a/bull-common/src/main/java/com/hotels/beans/constant/MethodPrefix.java b/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java similarity index 96% rename from bull-common/src/main/java/com/hotels/beans/constant/MethodPrefix.java rename to bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java index 6609fb8e5..1ed7c16ac 100644 --- a/bull-common/src/main/java/com/hotels/beans/constant/MethodPrefix.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.constant; +package com.hotels.transformer.constant; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-common/src/main/java/com/hotels/beans/constant/Punctuation.java b/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java similarity index 96% rename from bull-common/src/main/java/com/hotels/beans/constant/Punctuation.java rename to bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java index 4eb27ef58..0ec5ae661 100644 --- a/bull-common/src/main/java/com/hotels/beans/constant/Punctuation.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.constant; +package com.hotels.transformer.constant; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-common/src/main/java/com/hotels/beans/constant/package-info.java b/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java similarity index 93% rename from bull-common/src/main/java/com/hotels/beans/constant/package-info.java rename to bull-common/src/main/java/com/hotels/transformer/constant/package-info.java index 18642252b..5e9781572 100644 --- a/bull-common/src/main/java/com/hotels/beans/constant/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java @@ -17,4 +17,4 @@ * Constants package. */ -package com.hotels.beans.constant; +package com.hotels.transformer.constant; diff --git a/bull-common/src/main/java/com/hotels/beans/error/InstanceCreationException.java b/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java similarity index 97% rename from bull-common/src/main/java/com/hotels/beans/error/InstanceCreationException.java rename to bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java index 923af26a3..2efcecce3 100644 --- a/bull-common/src/main/java/com/hotels/beans/error/InstanceCreationException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.error; +package com.hotels.transformer.error; /** * Instance creation exception class. diff --git a/bull-common/src/main/java/com/hotels/beans/error/InvalidBeanException.java b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java similarity index 98% rename from bull-common/src/main/java/com/hotels/beans/error/InvalidBeanException.java rename to bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java index 443165071..2c98a450f 100644 --- a/bull-common/src/main/java/com/hotels/beans/error/InvalidBeanException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.error; +package com.hotels.transformer.error; /** * Invalid Bean exception class. diff --git a/bull-common/src/main/java/com/hotels/beans/error/MissingFieldException.java b/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java similarity index 96% rename from bull-common/src/main/java/com/hotels/beans/error/MissingFieldException.java rename to bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java index b25ae7dd6..ba8c2ce80 100644 --- a/bull-common/src/main/java/com/hotels/beans/error/MissingFieldException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.error; +package com.hotels.transformer.error; /** * Exception thrown if not the field not exists in the source object and no mapping has been specified. diff --git a/bull-common/src/main/java/com/hotels/beans/error/MissingMethodException.java b/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java similarity index 97% rename from bull-common/src/main/java/com/hotels/beans/error/MissingMethodException.java rename to bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java index f226027ff..5cccb4474 100644 --- a/bull-common/src/main/java/com/hotels/beans/error/MissingMethodException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.error; +package com.hotels.transformer.error; /** * Exception thrown if not a method not exists in the source object and no mapping has been specified. diff --git a/bull-common/src/main/java/com/hotels/beans/error/package-info.java b/bull-common/src/main/java/com/hotels/transformer/error/package-info.java similarity index 94% rename from bull-common/src/main/java/com/hotels/beans/error/package-info.java rename to bull-common/src/main/java/com/hotels/transformer/error/package-info.java index e11154bf2..505a0c6ee 100644 --- a/bull-common/src/main/java/com/hotels/beans/error/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/package-info.java @@ -17,4 +17,4 @@ * Exceptions package. */ -package com.hotels.beans.error; +package com.hotels.transformer.error; diff --git a/bull-common/src/main/java/com/hotels/beans/model/EmptyValue.java b/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java similarity index 95% rename from bull-common/src/main/java/com/hotels/beans/model/EmptyValue.java rename to bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java index d75442e74..6d411e6b0 100644 --- a/bull-common/src/main/java/com/hotels/beans/model/EmptyValue.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.model; +package com.hotels.transformer.model; /** * Needed in order to put in cache an empty value. diff --git a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldMapping.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java similarity index 96% rename from bean-utils-library/src/main/java/com/hotels/beans/model/FieldMapping.java rename to bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java index fa17b8d8c..a201eb486 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldMapping.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.model; +package com.hotels.transformer.model; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java similarity index 98% rename from bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java rename to bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java index 07f6a43bd..92dcda4d1 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/model/FieldTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.model; +package com.hotels.transformer.model; import static java.util.Objects.nonNull; diff --git a/bull-common/src/main/java/com/hotels/beans/model/ItemType.java b/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java similarity index 96% rename from bull-common/src/main/java/com/hotels/beans/model/ItemType.java rename to bull-common/src/main/java/com/hotels/transformer/model/ItemType.java index f24de56b5..a4b9069b5 100644 --- a/bull-common/src/main/java/com/hotels/beans/model/ItemType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.model; +package com.hotels.transformer.model; import lombok.Builder; import lombok.Getter; diff --git a/bull-common/src/main/java/com/hotels/beans/model/MapElemType.java b/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java similarity index 94% rename from bull-common/src/main/java/com/hotels/beans/model/MapElemType.java rename to bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java index 431c4b7c0..b530da9e4 100644 --- a/bull-common/src/main/java/com/hotels/beans/model/MapElemType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.model; +package com.hotels.transformer.model; /** * Interface that identifies the contained object elem types. diff --git a/bull-common/src/main/java/com/hotels/beans/model/MapType.java b/bull-common/src/main/java/com/hotels/transformer/model/MapType.java similarity index 96% rename from bull-common/src/main/java/com/hotels/beans/model/MapType.java rename to bull-common/src/main/java/com/hotels/transformer/model/MapType.java index 18e241e98..a1097f579 100644 --- a/bull-common/src/main/java/com/hotels/beans/model/MapType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/MapType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.model; +package com.hotels.transformer.model; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bean-utils-library/src/main/java/com/hotels/beans/model/package-info.java b/bull-common/src/main/java/com/hotels/transformer/model/package-info.java similarity index 94% rename from bean-utils-library/src/main/java/com/hotels/beans/model/package-info.java rename to bull-common/src/main/java/com/hotels/transformer/model/package-info.java index 610dabb69..56e7fb301 100644 --- a/bean-utils-library/src/main/java/com/hotels/beans/model/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/package-info.java @@ -17,4 +17,4 @@ * Pojo package. */ -package com.hotels.beans.model; +package com.hotels.transformer.model; diff --git a/bull-common/src/main/java/com/hotels/transformer/package-info.java b/bull-common/src/main/java/com/hotels/transformer/package-info.java new file mode 100644 index 000000000..f0f415ea9 --- /dev/null +++ b/bull-common/src/main/java/com/hotels/transformer/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Transformer package. + */ + +package com.hotels.transformer; diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java similarity index 96% rename from bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java rename to bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 9a6f2033c..fd498ad5b 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.utils; +package com.hotels.transformer.utils; import static java.lang.invoke.LambdaMetafactory.metafactory; import static java.lang.invoke.MethodHandles.lookup; @@ -33,15 +33,15 @@ import static java.util.Set.of; import static java.util.stream.Collectors.toList; -import static com.hotels.beans.validator.Validator.notNull; -import static com.hotels.beans.base.Defaults.defaultValue; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.constant.ClassType.IMMUTABLE; -import static com.hotels.beans.constant.ClassType.MIXED; -import static com.hotels.beans.constant.ClassType.MUTABLE; -import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_FIELD; -import static com.hotels.beans.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; -import static com.hotels.beans.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; +import static com.hotels.transformer.validator.Validator.notNull; +import static com.hotels.transformer.base.Defaults.defaultValue; +import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.transformer.constant.ClassType.IMMUTABLE; +import static com.hotels.transformer.constant.ClassType.MIXED; +import static com.hotels.transformer.constant.ClassType.MUTABLE; +import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_FIELD; +import static com.hotels.transformer.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; +import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; @@ -63,10 +63,10 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.constant.ClassType; -import com.hotels.beans.error.InstanceCreationException; -import com.hotels.beans.error.InvalidBeanException; +import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.constant.ClassType; +import com.hotels.transformer.error.InstanceCreationException; +import com.hotels.transformer.error.InvalidBeanException; /** * Reflection utils for Class objects. diff --git a/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java similarity index 97% rename from bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java rename to bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index b5a25d958..744e8ac03 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.utils; +package com.hotels.transformer.utils; import static java.lang.invoke.LambdaMetafactory.metafactory; import static java.lang.invoke.MethodHandles.lookup; @@ -24,10 +24,10 @@ import static org.apache.commons.lang3.StringUtils.capitalize; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.constant.MethodPrefix.GET; -import static com.hotels.beans.constant.MethodPrefix.IS; -import static com.hotels.beans.constant.MethodPrefix.SET; +import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.transformer.constant.MethodPrefix.GET; +import static com.hotels.transformer.constant.MethodPrefix.IS; +import static com.hotels.transformer.constant.MethodPrefix.SET; import java.lang.annotation.Annotation; import java.lang.invoke.CallSite; @@ -44,14 +44,14 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.error.InvalidBeanException; -import com.hotels.beans.error.MissingFieldException; -import com.hotels.beans.error.MissingMethodException; -import com.hotels.beans.model.EmptyValue; -import com.hotels.beans.model.ItemType; -import com.hotels.beans.model.MapElemType; -import com.hotels.beans.model.MapType; +import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.error.InvalidBeanException; +import com.hotels.transformer.error.MissingFieldException; +import com.hotels.transformer.error.MissingMethodException; +import com.hotels.transformer.model.EmptyValue; +import com.hotels.transformer.model.ItemType; +import com.hotels.transformer.model.MapElemType; +import com.hotels.transformer.model.MapType; /** * Reflection class utils. diff --git a/bull-common/src/main/java/com/hotels/beans/utils/package-info.java b/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java similarity index 94% rename from bull-common/src/main/java/com/hotels/beans/utils/package-info.java rename to bull-common/src/main/java/com/hotels/transformer/utils/package-info.java index dc86d83d5..ea80c6684 100644 --- a/bull-common/src/main/java/com/hotels/beans/utils/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java @@ -17,4 +17,4 @@ * utilities package. */ -package com.hotels.beans.utils; +package com.hotels.transformer.utils; diff --git a/bull-common/src/main/java/com/hotels/beans/validator/Validator.java b/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java similarity index 93% rename from bull-common/src/main/java/com/hotels/beans/validator/Validator.java rename to bull-common/src/main/java/com/hotels/transformer/validator/Validator.java index af7442ec0..d2c24d56a 100644 --- a/bull-common/src/main/java/com/hotels/beans/validator/Validator.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.validator; +package com.hotels.transformer.validator; import static java.util.Objects.isNull; @@ -48,7 +48,7 @@ public interface Validator { * Checks if an object is valid. * @param the object class * @param k the object to check - * @throws com.hotels.beans.error.InvalidBeanException {@link com.hotels.beans.error.InvalidBeanException} if the validation fails + * @throws com.hotels.transformer.error.InvalidBeanException {@link com.hotels.transformer.error.InvalidBeanException} if the validation fails */ void validate(K k); diff --git a/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java similarity index 90% rename from bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java rename to bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java index 1d3668e3f..a569454e7 100644 --- a/bull-common/src/main/java/com/hotels/beans/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.validator; +package com.hotels.transformer.validator; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; @@ -23,9 +23,9 @@ import static org.apache.commons.lang3.StringUtils.SPACE; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.beans.constant.Punctuation.DOT; -import static com.hotels.beans.constant.Punctuation.SEMICOLON; +import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.transformer.constant.Punctuation.DOT; +import static com.hotels.transformer.constant.Punctuation.SEMICOLON; import java.util.List; import java.util.Set; @@ -33,8 +33,8 @@ import javax.validation.ConstraintViolation; -import com.hotels.beans.cache.CacheManager; -import com.hotels.beans.error.InvalidBeanException; +import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.error.InvalidBeanException; /** * Java Bean validation class. diff --git a/bull-common/src/main/java/com/hotels/beans/validator/package-info.java b/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java similarity index 93% rename from bull-common/src/main/java/com/hotels/beans/validator/package-info.java rename to bull-common/src/main/java/com/hotels/transformer/validator/package-info.java index e912c186c..c49d70653 100644 --- a/bull-common/src/main/java/com/hotels/beans/validator/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java @@ -17,4 +17,4 @@ * validator package. */ -package com.hotels.beans.validator; +package com.hotels.transformer.validator; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java index 1c197b967..57406c581 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java @@ -18,7 +18,7 @@ import java.util.Optional; -import com.hotels.beans.constant.ClassType; +import com.hotels.transformer.constant.ClassType; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java index 919e3fea7..a63cd8458 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java @@ -19,7 +19,7 @@ import java.util.Locale; import java.util.Optional; -import com.hotels.beans.constant.ClassType; +import com.hotels.transformer.constant.ClassType; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java index a37c75802..d020bbee5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -21,7 +21,7 @@ import javax.validation.constraints.NotNull; -import com.hotels.beans.annotation.ConstructorArg; +import com.hotels.transformer.annotation.ConstructorArg; import lombok.ToString; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java index 75d4d7d7a..b5bfc8fcd 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -18,7 +18,7 @@ import javax.validation.constraints.NotNull; -import com.hotels.beans.annotation.ConstructorArg; +import com.hotels.transformer.annotation.ConstructorArg; import lombok.Getter; import lombok.ToString; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java index b4f281c76..d2e679904 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -21,7 +21,7 @@ import javax.validation.constraints.NotNull; -import com.hotels.beans.annotation.ConstructorArg; +import com.hotels.transformer.annotation.ConstructorArg; import lombok.Getter; import lombok.ToString; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java index 49f6d4479..66b656786 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java @@ -19,8 +19,8 @@ import java.math.BigInteger; import java.util.List; -import com.hotels.beans.annotation.ConstructorArg; import com.hotels.beans.sample.immutable.ImmutableToSubFoo; +import com.hotels.transformer.annotation.ConstructorArg; import lombok.Getter; import lombok.Setter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java index 4ca500dcb..141f49b54 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java @@ -19,7 +19,7 @@ import java.util.Locale; import java.util.Optional; -import com.hotels.beans.constant.ClassType; +import com.hotels.transformer.constant.ClassType; import lombok.Getter; import lombok.Setter; diff --git a/bull-common/src/test/java/com/hotels/beans/base/DefaultsTest.java b/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java similarity index 98% rename from bull-common/src/test/java/com/hotels/beans/base/DefaultsTest.java rename to bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java index e4baddf4a..83781222a 100644 --- a/bull-common/src/test/java/com/hotels/beans/base/DefaultsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.base; +package com.hotels.transformer.base; import static java.lang.Boolean.FALSE; diff --git a/bull-common/src/test/java/com/hotels/beans/base/package-info.java b/bull-common/src/test/java/com/hotels/transformer/base/package-info.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/base/package-info.java rename to bull-common/src/test/java/com/hotels/transformer/base/package-info.java index 2e040f47c..d2f313a50 100644 --- a/bull-common/src/test/java/com/hotels/beans/base/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/base/package-info.java @@ -17,4 +17,4 @@ * Base item package. */ -package com.hotels.beans.base; +package com.hotels.transformer.base; diff --git a/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java similarity index 98% rename from bull-common/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java rename to bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java index 0528d9441..0b5ab5aee 100644 --- a/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerFactoryTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.cache; +package com.hotels.transformer.cache; import static org.junit.Assert.assertNotNull; import static org.mockito.MockitoAnnotations.initMocks; diff --git a/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java similarity index 98% rename from bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java rename to bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java index e3c0b147d..e6cafba3f 100644 --- a/bull-common/src/test/java/com/hotels/beans/cache/CacheManagerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.cache; +package com.hotels.transformer.cache; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/bull-common/src/main/java/com/hotels/beans/cache/package-info.java b/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java similarity index 94% rename from bull-common/src/main/java/com/hotels/beans/cache/package-info.java rename to bull-common/src/test/java/com/hotels/transformer/cache/package-info.java index d9e881424..0b7cc17dc 100644 --- a/bull-common/src/main/java/com/hotels/beans/cache/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java @@ -17,4 +17,4 @@ * cache package. */ -package com.hotels.beans.cache; +package com.hotels.transformer.cache; diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java similarity index 99% rename from bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java rename to bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index a89b915d8..7f4c65ec7 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.utils; +package com.hotels.transformer.utils; import static java.lang.reflect.Modifier.isFinal; import static java.util.Objects.nonNull; @@ -48,10 +48,6 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.annotation.ConstructorArg; -import com.hotels.beans.constant.ClassType; -import com.hotels.beans.error.InstanceCreationException; -import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.sample.AbstractClass; import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.immutable.ImmutableToFoo; @@ -64,6 +60,10 @@ import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooSubClass; import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; +import com.hotels.transformer.annotation.ConstructorArg; +import com.hotels.transformer.constant.ClassType; +import com.hotels.transformer.error.InstanceCreationException; +import com.hotels.transformer.error.InvalidBeanException; /** * Unit test for {@link ClassUtils}. diff --git a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java similarity index 98% rename from bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java rename to bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index bb8d60dc8..f2bfea00d 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.utils; +package com.hotels.transformer.utils; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; @@ -27,8 +27,8 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import static com.hotels.beans.constant.MethodPrefix.GET; -import static com.hotels.beans.constant.MethodPrefix.IS; +import static com.hotels.transformer.constant.MethodPrefix.GET; +import static com.hotels.transformer.constant.MethodPrefix.IS; import java.lang.annotation.Annotation; import java.lang.reflect.Field; @@ -48,11 +48,6 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.error.MissingFieldException; -import com.hotels.beans.error.MissingMethodException; -import com.hotels.beans.model.ItemType; -import com.hotels.beans.model.MapElemType; -import com.hotels.beans.model.MapType; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSimpleNoGetters; import com.hotels.beans.sample.FromFooSubClass; @@ -62,6 +57,11 @@ import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooAdvFields; import com.hotels.beans.sample.mutable.MutableToFooSimple; +import com.hotels.transformer.error.MissingFieldException; +import com.hotels.transformer.error.MissingMethodException; +import com.hotels.transformer.model.ItemType; +import com.hotels.transformer.model.MapElemType; +import com.hotels.transformer.model.MapType; /** * Unit tests fro class: {@link ReflectionUtils}. diff --git a/bull-common/src/test/java/com/hotels/beans/utils/package-info.java b/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/utils/package-info.java rename to bull-common/src/test/java/com/hotels/transformer/utils/package-info.java index dc86d83d5..ea80c6684 100644 --- a/bull-common/src/test/java/com/hotels/beans/utils/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java @@ -17,4 +17,4 @@ * utilities package. */ -package com.hotels.beans.utils; +package com.hotels.transformer.utils; diff --git a/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java similarity index 98% rename from bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java rename to bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java index 1ab148447..9c78c4242 100644 --- a/bull-common/src/test/java/com/hotels/beans/validator/ValidatorTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.validator; +package com.hotels.transformer.validator; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; @@ -32,8 +32,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.error.InvalidBeanException; import com.hotels.beans.sample.mixed.MixedToFoo; +import com.hotels.transformer.error.InvalidBeanException; /** * Unit test for {@link Validator}. diff --git a/bull-common/src/test/java/com/hotels/beans/validator/package-info.java b/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java similarity index 93% rename from bull-common/src/test/java/com/hotels/beans/validator/package-info.java rename to bull-common/src/test/java/com/hotels/transformer/validator/package-info.java index 38cf80d91..40e8828bf 100644 --- a/bull-common/src/test/java/com/hotels/beans/validator/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java @@ -17,4 +17,4 @@ * validator test package. */ -package com.hotels.beans.validator; +package com.hotels.transformer.validator; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java index b22ef0c3e..021daa6a9 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java @@ -18,7 +18,7 @@ import static java.util.Objects.isNull; -import static com.hotels.beans.validator.Validator.notNull; +import static com.hotels.transformer.validator.Validator.notNull; import java.util.Optional; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 5bbfa3ed1..0cef29424 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -19,27 +19,27 @@ import static java.util.Optional.empty; import static java.util.Optional.of; -import static com.hotels.beans.cache.CacheManagerFactory.getCacheManager; import static com.hotels.beans.conversion.processor.ConversionProcessorFactory.getConversionProcessor; -import static com.hotels.beans.utils.ClassUtils.isBoolean; -import static com.hotels.beans.utils.ClassUtils.isByte; -import static com.hotels.beans.utils.ClassUtils.isChar; -import static com.hotels.beans.utils.ClassUtils.isDouble; -import static com.hotels.beans.utils.ClassUtils.isFloat; -import static com.hotels.beans.utils.ClassUtils.isInt; -import static com.hotels.beans.utils.ClassUtils.isLong; -import static com.hotels.beans.utils.ClassUtils.isShort; -import static com.hotels.beans.utils.ClassUtils.isString; -import static com.hotels.beans.utils.ClassUtils.isBigDecimal; -import static com.hotels.beans.utils.ClassUtils.isBigInteger; -import static com.hotels.beans.utils.ClassUtils.isByteArray; +import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.transformer.utils.ClassUtils.isBoolean; +import static com.hotels.transformer.utils.ClassUtils.isByte; +import static com.hotels.transformer.utils.ClassUtils.isChar; +import static com.hotels.transformer.utils.ClassUtils.isDouble; +import static com.hotels.transformer.utils.ClassUtils.isFloat; +import static com.hotels.transformer.utils.ClassUtils.isInt; +import static com.hotels.transformer.utils.ClassUtils.isLong; +import static com.hotels.transformer.utils.ClassUtils.isShort; +import static com.hotels.transformer.utils.ClassUtils.isString; +import static com.hotels.transformer.utils.ClassUtils.isBigDecimal; +import static com.hotels.transformer.utils.ClassUtils.isBigInteger; +import static com.hotels.transformer.utils.ClassUtils.isByteArray; import java.util.Optional; import java.util.function.Function; -import com.hotels.beans.cache.CacheManager; import com.hotels.beans.conversion.processor.ConversionProcessor; -import com.hotels.beans.utils.ClassUtils; +import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.utils.ClassUtils; /** * This class provides method for converting a primitive input into another. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index d8497cf41..2de292b64 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -19,18 +19,18 @@ import static java.util.Optional.empty; import static java.util.Optional.of; -import static com.hotels.beans.utils.ClassUtils.isBigDecimal; -import static com.hotels.beans.utils.ClassUtils.isBigInteger; -import static com.hotels.beans.utils.ClassUtils.isByteArray; -import static com.hotels.beans.utils.ClassUtils.isBoolean; -import static com.hotels.beans.utils.ClassUtils.isByte; -import static com.hotels.beans.utils.ClassUtils.isChar; -import static com.hotels.beans.utils.ClassUtils.isDouble; -import static com.hotels.beans.utils.ClassUtils.isFloat; -import static com.hotels.beans.utils.ClassUtils.isInt; -import static com.hotels.beans.utils.ClassUtils.isLong; -import static com.hotels.beans.utils.ClassUtils.isShort; -import static com.hotels.beans.utils.ClassUtils.isString; +import static com.hotels.transformer.utils.ClassUtils.isBigDecimal; +import static com.hotels.transformer.utils.ClassUtils.isBigInteger; +import static com.hotels.transformer.utils.ClassUtils.isByteArray; +import static com.hotels.transformer.utils.ClassUtils.isBoolean; +import static com.hotels.transformer.utils.ClassUtils.isByte; +import static com.hotels.transformer.utils.ClassUtils.isChar; +import static com.hotels.transformer.utils.ClassUtils.isDouble; +import static com.hotels.transformer.utils.ClassUtils.isFloat; +import static com.hotels.transformer.utils.ClassUtils.isInt; +import static com.hotels.transformer.utils.ClassUtils.isLong; +import static com.hotels.transformer.utils.ClassUtils.isShort; +import static com.hotels.transformer.utils.ClassUtils.isString; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml new file mode 100644 index 000000000..1c2752e58 --- /dev/null +++ b/bull-map-transformer/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + BULL - Map Transformer + bull-map-transformer + jar + Provides a Map Transformer + + + bean-utils-library-parent + com.hotels.beans + 1.5.1-SNAPSHOT + + \ No newline at end of file diff --git a/docs/site/markdown/transformer/testing.md b/docs/site/markdown/transformer/testing.md index e0358b63f..a07ebf44d 100644 --- a/docs/site/markdown/transformer/testing.md +++ b/docs/site/markdown/transformer/testing.md @@ -80,8 +80,8 @@ import org.junit.Test; import org.mockito.InjectMocks; import com.hotels.beans.transformer.BeanUtils; -import com.hotels.beans.transformer.Transformer; -import com.hotels.beans.error.InvalidBeanException; +import com.hotels.transformer.Transformer; +import com.hotels.transformer.error.InvalidBeanException; /** * Unit test for {@link SampleClass}. @@ -197,8 +197,8 @@ import org.junit.Test; import org.mockito.InjectMocks; import com.hotels.beans.transformer.BeanUtils; -import com.hotels.beans.transformer.Transformer; -import com.hotels.beans.error.InvalidBeanException; +import com.hotels.transformer.Transformer; +import com.hotels.transformer.error.InvalidBeanException; /** * Unit test for {@link SampleClass}. diff --git a/pom.xml b/pom.xml index 8619db669..8cdd0dddf 100644 --- a/pom.xml +++ b/pom.xml @@ -21,9 +21,7 @@ - bean-utils-library bull-common - bull-converter @@ -180,6 +178,23 @@ + + + default + + true + + + bean-utils-library + bull-converter + + + + map-transformer + + bull-map-transformer + + relaxed From 2d3420b1fd09794e8e1af867c6ab287cbf390af9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 1 Sep 2019 15:48:19 +0200 Subject: [PATCH 0796/1786] Started bean-utils-library module relocation --- bean-utils-library/pom.xml | 30 +++-------- bull-bean-transformer/pom.xml | 39 ++++++++++++++ .../main/java/com/hotels/beans/BeanUtils.java | 0 .../java/com/hotels/beans/package-info.java | 0 .../beans/populator/ArrayPopulator.java | 0 .../beans/populator/CollectionPopulator.java | 0 .../beans/populator/ICollectionPopulator.java | 0 .../hotels/beans/populator/MapPopulator.java | 0 .../beans/populator/OptionalPopulator.java | 0 .../com/hotels/beans/populator/Populator.java | 0 .../beans/populator/PopulatorFactory.java | 0 .../hotels/beans/populator/package-info.java | 0 .../transformer/AbstractTransformer.java | 0 .../beans/transformer/BeanTransformer.java | 0 .../hotels/beans/transformer/Transformer.java | 25 +++++++++ .../beans/transformer/TransformerImpl.java | 0 .../transformer/TransformerSettings.java | 0 .../beans/transformer/model/FieldMapping.java | 37 +++++++++++++ .../transformer/model/FieldTransformer.java | 53 +++++++++++++++++++ .../beans/transformer/model/package-info.java | 21 ++++++++ .../beans/transformer/package-info.java | 0 .../src/main/resources/banner.txt | 0 .../main/resources/config/application-dev.yml | 0 .../src/main/resources/config/application.yml | 0 .../config/logging/logback-appenders.xml | 0 .../config/logging/logback-properties.xml | 0 .../src/main/resources/logback-test.xml | 0 .../src/main/resources/logback.xml | 0 .../java/com/hotels/beans/BeanUtilsTest.java | 0 .../java/com/hotels/beans/package-info.java | 0 .../beans/performance/PerformanceTest.java | 0 .../beans/performance/package-info.java | 0 .../beans/populator/ArrayPopulatorTest.java | 0 .../beans/populator/PopulatorFactoryTest.java | 0 .../hotels/beans/populator/package-info.java | 0 .../AbstractBeanTransformerTest.java | 0 .../transformer/BeanTransformerTest.java | 0 .../BuilderObjectTransformationTest.java | 0 .../ImmutableObjectTransformationTest.java | 0 .../MixedObjectTransformationTest.java | 0 .../MutableObjectTransformationTest.java | 0 .../beans/transformer/package-info.java | 0 .../org.mockito.plugins.MockMaker | 0 pom.xml | 1 + 44 files changed, 182 insertions(+), 24 deletions(-) create mode 100644 bull-bean-transformer/pom.xml rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/BeanUtils.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/package-info.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/populator/ArrayPopulator.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/populator/CollectionPopulator.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/populator/MapPopulator.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/populator/OptionalPopulator.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/populator/Populator.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/populator/PopulatorFactory.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/populator/package-info.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/transformer/BeanTransformer.java (100%) create mode 100644 bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/transformer/TransformerImpl.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/transformer/TransformerSettings.java (100%) create mode 100644 bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldMapping.java create mode 100644 bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldTransformer.java create mode 100644 bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java rename {bean-utils-library => bull-bean-transformer}/src/main/java/com/hotels/beans/transformer/package-info.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/resources/banner.txt (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/resources/config/application-dev.yml (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/resources/config/application.yml (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/resources/config/logging/logback-appenders.xml (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/resources/config/logging/logback-properties.xml (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/resources/logback-test.xml (100%) rename {bean-utils-library => bull-bean-transformer}/src/main/resources/logback.xml (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/BeanUtilsTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/package-info.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/performance/PerformanceTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/performance/package-info.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/populator/package-info.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/java/com/hotels/beans/transformer/package-info.java (100%) rename {bean-utils-library => bull-bean-transformer}/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker (100%) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index c44e9dae2..cb1fa6af8 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -11,29 +11,11 @@ 1.5.1-SNAPSHOT - - + + com.hotels.beans - bull-common - ${project.version} - - - com.hotels.beans - bull-converter - ${project.version} - - - - com.hotels.beans - bull-common - ${project.version} - test-jar - test - - - com.shazam - shazamcrest - test - - + bull-bean-transformer + Warning: This module has been relocated and will be no longer available since version: 1.6.0, please use bull-bean-transformer instead + + \ No newline at end of file diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml new file mode 100644 index 000000000..0cea57189 --- /dev/null +++ b/bull-bean-transformer/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + BULL - Bean Transformer + bull-bean-transformer + jar + + + com.hotels.beans + bean-utils-library-parent + 1.5.1-SNAPSHOT + + + + + com.hotels.beans + bull-common + ${project.version} + + + com.hotels.beans + bull-converter + ${project.version} + + + + com.hotels.beans + bull-common + ${project.version} + test-jar + test + + + com.shazam + shazamcrest + test + + + \ No newline at end of file diff --git a/bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/BeanUtils.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/package-info.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/populator/ArrayPopulator.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/populator/CollectionPopulator.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/populator/MapPopulator.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/populator/OptionalPopulator.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/populator/Populator.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/populator/PopulatorFactory.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/populator/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/populator/package-info.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/transformer/BeanTransformer.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java new file mode 100644 index 000000000..dab19c02a --- /dev/null +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -0,0 +1,25 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +/** + * Utility methods for all objects transformation. + * @deprecated This class will be removed since version 1.6.0 please use {@link com.hotels.transformer.Transformer} instead. + */ +@Deprecated(since = "1.6.0", forRemoval = true) +public interface Transformer extends com.hotels.transformer.Transformer { +} diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerImpl.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerSettings.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/transformer/TransformerSettings.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerSettings.java diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldMapping.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldMapping.java new file mode 100644 index 000000000..3278bbcf2 --- /dev/null +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldMapping.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer.model; + +import lombok.Getter; +import lombok.ToString; + +/** + * Specifies the field's name mapping between the source object and destination one. + * @deprecated This class will be removed since version 1.6.0 please use {@link com.hotels.transformer.model.FieldMapping} instead. + */ +@Deprecated(since = "1.6.0", forRemoval = true) +@Getter +@ToString +public class FieldMapping extends com.hotels.transformer.model.FieldMapping { + /** + * @param sourceFieldName The field name in the source object. + * @param destFieldName The field name in the destination object. + */ + public FieldMapping(final String sourceFieldName, final String destFieldName) { + super(sourceFieldName, destFieldName); + } +} diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldTransformer.java new file mode 100644 index 000000000..c4683b79d --- /dev/null +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldTransformer.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer.model; + +import java.util.function.Function; +import java.util.function.Supplier; + +import lombok.Getter; +import lombok.ToString; + +/** + * Specifies the field mapping between the source object and destination one. + * + * @param input field type. + * @param field value on with apply the function. + * @deprecated This class will be removed since version 1.6.0 please use {@link com.hotels.transformer.model.FieldTransformer} instead. + */ +@Deprecated(since = "1.6.0", forRemoval = true) +@Getter +@ToString +public class FieldTransformer extends com.hotels.transformer.model.FieldTransformer { + /** + * Creates a field transformer with a lambda function to be applied on the field. + * @param destinationFieldName the field name in the destination object. + * @param fieldTransformerFunction the transformer function to apply on field + */ + public FieldTransformer(final String destinationFieldName, final Function fieldTransformerFunction) { + super(destinationFieldName, fieldTransformerFunction); + } + + /** + * Creates a field transformer with a field supplier function to be applied on the field. + * @param destinationFieldName the field name in the destination object. + * @param fieldTransformerSupplier the transformer supplier to apply on field + */ + public FieldTransformer(final String destinationFieldName, final Supplier fieldTransformerSupplier) { + super(destinationFieldName, fieldTransformerSupplier); + } +} diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java new file mode 100644 index 000000000..67a51a242 --- /dev/null +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java @@ -0,0 +1,21 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Transformer model package. + * @deprecated This package will be removed since version 1.6.0 please use {@link com.hotels.transformer.model} instead. + */ +@Deprecated(since = "1.6.0", forRemoval = true) +package com.hotels.beans.transformer.model; diff --git a/bean-utils-library/src/main/java/com/hotels/beans/transformer/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java similarity index 100% rename from bean-utils-library/src/main/java/com/hotels/beans/transformer/package-info.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java diff --git a/bean-utils-library/src/main/resources/banner.txt b/bull-bean-transformer/src/main/resources/banner.txt similarity index 100% rename from bean-utils-library/src/main/resources/banner.txt rename to bull-bean-transformer/src/main/resources/banner.txt diff --git a/bean-utils-library/src/main/resources/config/application-dev.yml b/bull-bean-transformer/src/main/resources/config/application-dev.yml similarity index 100% rename from bean-utils-library/src/main/resources/config/application-dev.yml rename to bull-bean-transformer/src/main/resources/config/application-dev.yml diff --git a/bean-utils-library/src/main/resources/config/application.yml b/bull-bean-transformer/src/main/resources/config/application.yml similarity index 100% rename from bean-utils-library/src/main/resources/config/application.yml rename to bull-bean-transformer/src/main/resources/config/application.yml diff --git a/bean-utils-library/src/main/resources/config/logging/logback-appenders.xml b/bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml similarity index 100% rename from bean-utils-library/src/main/resources/config/logging/logback-appenders.xml rename to bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml diff --git a/bean-utils-library/src/main/resources/config/logging/logback-properties.xml b/bull-bean-transformer/src/main/resources/config/logging/logback-properties.xml similarity index 100% rename from bean-utils-library/src/main/resources/config/logging/logback-properties.xml rename to bull-bean-transformer/src/main/resources/config/logging/logback-properties.xml diff --git a/bean-utils-library/src/main/resources/logback-test.xml b/bull-bean-transformer/src/main/resources/logback-test.xml similarity index 100% rename from bean-utils-library/src/main/resources/logback-test.xml rename to bull-bean-transformer/src/main/resources/logback-test.xml diff --git a/bean-utils-library/src/main/resources/logback.xml b/bull-bean-transformer/src/main/resources/logback.xml similarity index 100% rename from bean-utils-library/src/main/resources/logback.xml rename to bull-bean-transformer/src/main/resources/logback.xml diff --git a/bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/BeanUtilsTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/package-info.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/performance/PerformanceTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/performance/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/performance/package-info.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/populator/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/populator/package-info.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java diff --git a/bean-utils-library/src/test/java/com/hotels/beans/transformer/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java similarity index 100% rename from bean-utils-library/src/test/java/com/hotels/beans/transformer/package-info.java rename to bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java diff --git a/bean-utils-library/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-bean-transformer/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker similarity index 100% rename from bean-utils-library/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker rename to bull-bean-transformer/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/pom.xml b/pom.xml index 8cdd0dddf..2b1d774ef 100644 --- a/pom.xml +++ b/pom.xml @@ -186,6 +186,7 @@ bean-utils-library + bull-bean-transformer bull-converter From dbc9bfe298d8a2ce828765730442855c3c069d75 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 1 Sep 2019 19:05:30 +0200 Subject: [PATCH 0797/1786] Modifying class inheritance in order to keep compatibility --- .../main/java/com/hotels/beans/BeanUtils.java | 9 ++++ .../hotels/beans/transformer/Transformer.java | 43 ++++++++++++++++++- .../beans/transformer/model/package-info.java | 1 - 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java index 3aac1360c..389f2b10f 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java @@ -23,6 +23,7 @@ import com.hotels.beans.conversion.Converter; import com.hotels.beans.conversion.ConverterImpl; import com.hotels.beans.transformer.BeanTransformer; +import com.hotels.beans.transformer.Transformer; import com.hotels.beans.transformer.TransformerImpl; import com.hotels.transformer.validator.Validator; import com.hotels.transformer.validator.ValidatorImpl; @@ -66,6 +67,14 @@ public final BeanTransformer getTransformer() { return new TransformerImpl(); } + /** + * Returns a Bean Transformer. + * @return a {@link BeanTransformer} instance. + */ + public final Transformer getTransformer() { + return null; + } + /** * Returns a Bean Validator. * @return a Bean Validator instance. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java index dab19c02a..fcf38c211 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -16,10 +16,51 @@ package com.hotels.beans.transformer; +import static java.util.Arrays.stream; +import static java.util.Objects.isNull; + +import com.hotels.beans.transformer.model.FieldMapping; +import com.hotels.beans.transformer.model.FieldTransformer; + /** * Utility methods for all objects transformation. * @deprecated This class will be removed since version 1.6.0 please use {@link com.hotels.transformer.Transformer} instead. */ @Deprecated(since = "1.6.0", forRemoval = true) -public interface Transformer extends com.hotels.transformer.Transformer { +public interface Transformer extends BeanTransformer { + /** + * Initializes the mapping between fields in the source object and the destination one. + * @param fieldMapping the field mapping + * @return the {@link Transformer} instance + * @deprecated use {@code withFieldMapping(com.hotels.transformer.model.FieldMapping)} instead. + */ + @Deprecated(since = "1.6.0", forRemoval = true) + default Transformer withFieldMapping(FieldMapping... fieldMapping) { + com.hotels.transformer.model.FieldMapping[] fieldMappings = stream(fieldMapping) + .map(fm -> new com.hotels.transformer.model.FieldMapping(fm.getSourceFieldName(), fm.getDestFieldName())) + .toArray(com.hotels.transformer.model.FieldMapping[]::new); + return (Transformer) withFieldMapping(fieldMappings); + } + + /** + * Initializes the field transformer functions. The transformer function returns directly the field value. + * @param fieldTransformer the fields transformer function + * @return the {@link Transformer} instance + * @deprecated use {@code withFieldMapping(com.hotels.transformer.model.FieldTransformer)} instead. + */ + @Deprecated(since = "1.6.0", forRemoval = true) + @SuppressWarnings("unchecked") + default Transformer withFieldTransformer(FieldTransformer... fieldTransformer) { + com.hotels.transformer.model.FieldTransformer[] fieldTransformers = stream(fieldTransformer) + .map(tmpFt -> { + com.hotels.transformer.model.FieldTransformer ft; + if (isNull(tmpFt.getTransformerFunction())) { + ft = new com.hotels.transformer.model.FieldTransformer<>(tmpFt.getDestFieldName(), tmpFt.getTransformerSupplier()); + } else { + ft = new com.hotels.transformer.model.FieldTransformer<>(tmpFt.getDestFieldName(), tmpFt.getTransformerFunction()); + } + return ft; + }).toArray(com.hotels.transformer.model.FieldTransformer[]::new); + return (Transformer) withFieldTransformer(fieldTransformers); + } } diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java index 67a51a242..a0a7561c1 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java @@ -17,5 +17,4 @@ * Transformer model package. * @deprecated This package will be removed since version 1.6.0 please use {@link com.hotels.transformer.model} instead. */ -@Deprecated(since = "1.6.0", forRemoval = true) package com.hotels.beans.transformer.model; From 5c99ad9dcfa2afb1cb166f0289b8b98dfe46d015 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 1 Sep 2019 19:20:16 +0200 Subject: [PATCH 0798/1786] Made priject retrocompatible --- .../main/java/com/hotels/beans/BeanUtils.java | 9 ------ .../{transformer => }/model/FieldMapping.java | 2 +- .../model/FieldTransformer.java | 2 +- .../{transformer => }/model/package-info.java | 2 +- .../transformer/AbstractTransformer.java | 32 +++++++++++++++++++ .../beans/transformer/BeanTransformer.java | 1 - .../hotels/beans/transformer/Transformer.java | 31 +++--------------- pom.xml | 1 - 8 files changed, 40 insertions(+), 40 deletions(-) rename bull-bean-transformer/src/main/java/com/hotels/beans/{transformer => }/model/FieldMapping.java (96%) rename bull-bean-transformer/src/main/java/com/hotels/beans/{transformer => }/model/FieldTransformer.java (97%) rename bull-bean-transformer/src/main/java/com/hotels/beans/{transformer => }/model/package-info.java (94%) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java index 389f2b10f..3aac1360c 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java @@ -23,7 +23,6 @@ import com.hotels.beans.conversion.Converter; import com.hotels.beans.conversion.ConverterImpl; import com.hotels.beans.transformer.BeanTransformer; -import com.hotels.beans.transformer.Transformer; import com.hotels.beans.transformer.TransformerImpl; import com.hotels.transformer.validator.Validator; import com.hotels.transformer.validator.ValidatorImpl; @@ -67,14 +66,6 @@ public final BeanTransformer getTransformer() { return new TransformerImpl(); } - /** - * Returns a Bean Transformer. - * @return a {@link BeanTransformer} instance. - */ - public final Transformer getTransformer() { - return null; - } - /** * Returns a Bean Validator. * @return a Bean Validator instance. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldMapping.java b/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldMapping.java similarity index 96% rename from bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldMapping.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldMapping.java index 3278bbcf2..bbc0a00ed 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldMapping.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldMapping.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.transformer.model; +package com.hotels.beans.model; import lombok.Getter; import lombok.ToString; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldTransformer.java similarity index 97% rename from bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldTransformer.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldTransformer.java index c4683b79d..e255f9fb2 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/FieldTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldTransformer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hotels.beans.transformer.model; +package com.hotels.beans.model; import java.util.function.Function; import java.util.function.Supplier; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/model/package-info.java similarity index 94% rename from bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/model/package-info.java index a0a7561c1..84d8fce7a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/model/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/model/package-info.java @@ -17,4 +17,4 @@ * Transformer model package. * @deprecated This package will be removed since version 1.6.0 please use {@link com.hotels.transformer.model} instead. */ -package com.hotels.beans.transformer.model; +package com.hotels.beans.model; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index b8a2412b3..cd752b030 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -17,6 +17,8 @@ package com.hotels.beans.transformer; import static java.util.Arrays.asList; +import static java.util.Arrays.stream; +import static java.util.Objects.isNull; import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; import static com.hotels.transformer.validator.Validator.notNull; @@ -99,6 +101,17 @@ public final BeanTransformer withFieldMapping(final FieldMapping... fieldMapping return this; } + /** + * {@inheritDoc} + */ + @Deprecated(since = "1.6.0", forRemoval = true) + public final Transformer withFieldMapping(final com.hotels.beans.model.FieldMapping... fieldMapping) { + com.hotels.transformer.model.FieldMapping[] fieldMappings = stream(fieldMapping) + .map(fm -> new com.hotels.transformer.model.FieldMapping(fm.getSourceFieldName(), fm.getDestFieldName())) + .toArray(com.hotels.transformer.model.FieldMapping[]::new); + return (Transformer) withFieldMapping(fieldMappings); + } + /** * {@inheritDoc} */ @@ -128,6 +141,25 @@ public final BeanTransformer withFieldTransformer(final FieldTransformer... fiel return this; } + /** + * {@inheritDoc} + */ + @Deprecated(since = "1.6.0", forRemoval = true) + @SuppressWarnings("unchecked") + public final Transformer withFieldTransformer(final com.hotels.beans.model.FieldTransformer... fieldTransformer) { + com.hotels.transformer.model.FieldTransformer[] fieldTransformers = stream(fieldTransformer) + .map(tmpFt -> { + com.hotels.transformer.model.FieldTransformer ft; + if (isNull(tmpFt.getTransformerFunction())) { + ft = new com.hotels.transformer.model.FieldTransformer<>(tmpFt.getDestFieldName(), tmpFt.getTransformerSupplier()); + } else { + ft = new com.hotels.transformer.model.FieldTransformer<>(tmpFt.getDestFieldName(), tmpFt.getTransformerFunction()); + } + return ft; + }).toArray(com.hotels.transformer.model.FieldTransformer[]::new); + return (Transformer) withFieldTransformer(fieldTransformers); + } + /** * {@inheritDoc} */ diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index a208c2309..c342d5f10 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -16,7 +16,6 @@ package com.hotels.beans.transformer; -import com.hotels.transformer.Transformer; import com.hotels.transformer.model.FieldMapping; import com.hotels.transformer.model.FieldTransformer; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java index fcf38c211..5a0e814e6 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java @@ -16,18 +16,15 @@ package com.hotels.beans.transformer; -import static java.util.Arrays.stream; -import static java.util.Objects.isNull; - -import com.hotels.beans.transformer.model.FieldMapping; -import com.hotels.beans.transformer.model.FieldTransformer; +import com.hotels.beans.model.FieldMapping; +import com.hotels.beans.model.FieldTransformer; /** * Utility methods for all objects transformation. * @deprecated This class will be removed since version 1.6.0 please use {@link com.hotels.transformer.Transformer} instead. */ @Deprecated(since = "1.6.0", forRemoval = true) -public interface Transformer extends BeanTransformer { +public interface Transformer extends com.hotels.transformer.Transformer { /** * Initializes the mapping between fields in the source object and the destination one. * @param fieldMapping the field mapping @@ -35,12 +32,7 @@ public interface Transformer extends BeanTransformer { * @deprecated use {@code withFieldMapping(com.hotels.transformer.model.FieldMapping)} instead. */ @Deprecated(since = "1.6.0", forRemoval = true) - default Transformer withFieldMapping(FieldMapping... fieldMapping) { - com.hotels.transformer.model.FieldMapping[] fieldMappings = stream(fieldMapping) - .map(fm -> new com.hotels.transformer.model.FieldMapping(fm.getSourceFieldName(), fm.getDestFieldName())) - .toArray(com.hotels.transformer.model.FieldMapping[]::new); - return (Transformer) withFieldMapping(fieldMappings); - } + Transformer withFieldMapping(FieldMapping... fieldMapping); /** * Initializes the field transformer functions. The transformer function returns directly the field value. @@ -49,18 +41,5 @@ default Transformer withFieldMapping(FieldMapping... fieldMapping) { * @deprecated use {@code withFieldMapping(com.hotels.transformer.model.FieldTransformer)} instead. */ @Deprecated(since = "1.6.0", forRemoval = true) - @SuppressWarnings("unchecked") - default Transformer withFieldTransformer(FieldTransformer... fieldTransformer) { - com.hotels.transformer.model.FieldTransformer[] fieldTransformers = stream(fieldTransformer) - .map(tmpFt -> { - com.hotels.transformer.model.FieldTransformer ft; - if (isNull(tmpFt.getTransformerFunction())) { - ft = new com.hotels.transformer.model.FieldTransformer<>(tmpFt.getDestFieldName(), tmpFt.getTransformerSupplier()); - } else { - ft = new com.hotels.transformer.model.FieldTransformer<>(tmpFt.getDestFieldName(), tmpFt.getTransformerFunction()); - } - return ft; - }).toArray(com.hotels.transformer.model.FieldTransformer[]::new); - return (Transformer) withFieldTransformer(fieldTransformers); - } + Transformer withFieldTransformer(FieldTransformer... fieldTransformer); } diff --git a/pom.xml b/pom.xml index 2b1d774ef..8cdd0dddf 100644 --- a/pom.xml +++ b/pom.xml @@ -186,7 +186,6 @@ bean-utils-library - bull-bean-transformer bull-converter From 1d6c529211d814fc7254f772cdd5cd1597daa933 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 05:13:07 +0200 Subject: [PATCH 0799/1786] Modified readme --- .travis.yml | 2 +- CHANGELOG-JDK8.md | 19 +++++++++++++++++++ CHANGELOG.md | 19 +++++++++++++++++++ README.md | 6 +++--- bean-utils-library/pom.xml | 4 ++-- pom.xml | 9 +++++++++ 6 files changed, 53 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 19da80924..40480bab5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P site-release + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release deploy: provider: pages local-dir: target/site diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 2e5fca8eb..9904a2065 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,25 @@ All notable changes to this project will be documented in this file. +### [1.1.24] TBD +#### Changed +* **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.1.25`, use `bull-bean-transformer` instead.** + ~~~ + + com.hotels.beans + bull-bean-transformer + x.y.z + + ~~~ +* Module `bean-utils-library` has been relocated into `bull-bean-transformer`. +* The following classes has been deprecated, please find below the complete list and the new one to be used: + + | Deprecated | **New one** | + | :----------- | :----------- | + | `com.hotels.beans.model.FieldMapping` | `com.hotels.transformer.model.FieldMapping` | + | `com.hotels.beans.model.FieldTransformer` | `com.hotels.transformer.model.FieldTransformer` | + | `com.hotels.beans.Transformer` | `com.hotels.transformer.Transformer` | + ### [1.1.23] 2019.08.06 #### Added * Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). diff --git a/CHANGELOG.md b/CHANGELOG.md index 134444600..caec4066c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,25 @@ All notable changes to this project will be documented in this file. +### [1.5.1] TBD +#### Changed +* **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** + ~~~ + + com.hotels.beans + bull-bean-transformer + x.y.z + + ~~~ +* Module `bean-utils-library` has been relocated into `bull-bean-transformer`. +* The following classes has been deprecated, please find below the complete list and the new one to be used: + + | Deprecated | **New one** | + | :----------- | :----------- | + | `com.hotels.beans.model.FieldMapping` | `com.hotels.transformer.model.FieldMapping` | + | `com.hotels.beans.model.FieldTransformer` | `com.hotels.transformer.model.FieldTransformer` | + | `com.hotels.beans.Transformer` | `com.hotels.transformer.Transformer` | + ### [1.5.0] 2019.08.06 #### Added * Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). diff --git a/README.md b/README.md index a0e86def5..fa1d23e16 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou ## Start using -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bean-utils-library) -[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bean-utils-library.svg)](http://www.javadoc.io/doc/com.hotels.beans/bean-utils-library) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) +[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE) @@ -24,7 +24,7 @@ You can obtain BULL from Maven Central: ~~~ com.hotels.beans - bean-utils-library + bull-bean-transformer x.y.z ~~~ diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index cb1fa6af8..221dfb005 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - BULL - Bean Transformer + BULL - Bean Transformer (Deprecated) bean-utils-library jar @@ -15,7 +15,7 @@ com.hotels.beans bull-bean-transformer - Warning: This module has been relocated and will be no longer available since version: 1.6.0, please use bull-bean-transformer instead + Warning: This module has been relocated and will be no longer available since version: 1.6.0, please use bull-bean-transformer instead. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8cdd0dddf..8fcf49ed1 100644 --- a/pom.xml +++ b/pom.xml @@ -184,6 +184,15 @@ true + + bean-utils-library + bull-bean-transformer + bull-converter + bull-map-transformer + + + + bean-transformer bean-utils-library bull-converter From 96d0886c64993412836b72b8ad44e441e6fd16f4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 05:49:14 +0200 Subject: [PATCH 0800/1786] Added tests to check the retro compatibility with the older classes --- .../transformer/AbstractTransformer.java | 19 ++++-------- .../MixedObjectTransformationTest.java | 29 +++++++++++++++---- config/travis/deploy.sh | 4 +-- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index cd752b030..e78f24269 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -18,13 +18,14 @@ import static java.util.Arrays.asList; import static java.util.Arrays.stream; -import static java.util.Objects.isNull; import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; import static com.hotels.transformer.validator.Validator.notNull; import java.util.Map; +import java.util.function.Function; +import com.hotels.beans.BeanUtils; import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; import com.hotels.transformer.cache.CacheManager; import com.hotels.transformer.model.FieldMapping; @@ -109,7 +110,7 @@ public final Transformer withFieldMapping(final com.hotels.beans.model.FieldMapp com.hotels.transformer.model.FieldMapping[] fieldMappings = stream(fieldMapping) .map(fm -> new com.hotels.transformer.model.FieldMapping(fm.getSourceFieldName(), fm.getDestFieldName())) .toArray(com.hotels.transformer.model.FieldMapping[]::new); - return (Transformer) withFieldMapping(fieldMappings); + return withFieldMapping(fieldMappings); } /** @@ -145,19 +146,11 @@ public final BeanTransformer withFieldTransformer(final FieldTransformer... fiel * {@inheritDoc} */ @Deprecated(since = "1.6.0", forRemoval = true) - @SuppressWarnings("unchecked") public final Transformer withFieldTransformer(final com.hotels.beans.model.FieldTransformer... fieldTransformer) { + Function transformerFunction = BeanUtils.getTransformer(FieldTransformer.class); com.hotels.transformer.model.FieldTransformer[] fieldTransformers = stream(fieldTransformer) - .map(tmpFt -> { - com.hotels.transformer.model.FieldTransformer ft; - if (isNull(tmpFt.getTransformerFunction())) { - ft = new com.hotels.transformer.model.FieldTransformer<>(tmpFt.getDestFieldName(), tmpFt.getTransformerSupplier()); - } else { - ft = new com.hotels.transformer.model.FieldTransformer<>(tmpFt.getDestFieldName(), tmpFt.getTransformerFunction()); - } - return ft; - }).toArray(com.hotels.transformer.model.FieldTransformer[]::new); - return (Transformer) withFieldTransformer(fieldTransformers); + .map(transformerFunction).toArray(com.hotels.transformer.model.FieldTransformer[]::new); + return withFieldTransformer(fieldTransformers); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index a68687a8f..ee57b3e57 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -27,6 +27,7 @@ import java.math.BigInteger; import java.util.stream.IntStream; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.hotels.beans.sample.FromFooSimple; @@ -95,18 +96,21 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { /** * Test that bean containing both final fields (with different names) and not are correctly copied through field transformer. + * @param testCaseDescription the test case description + * @param fieldMapping the field mapping definition + * @param fieldTransformer the transformer function to apply */ - @Test - public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTransformer() { + @Test(dataProvider = "dataTransformationTesting") + public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTransformer(final String testCaseDescription, + final FieldMapping fieldMapping, final FieldTransformer fieldTransformer) { //GIVEN - /* Extended declaration. + /* Extended FieldTransformer function declaration. * Function idTransformer = value -> value.negate(); * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", idTransformer); */ - FieldTransformer fieldTransformer = new FieldTransformer<>(IDENTIFIER_FIELD_NAME, BigInteger::negate); //WHEN - underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)).withFieldTransformer(fieldTransformer); + underTest.withFieldMapping(fieldMapping).withFieldTransformer(fieldTransformer); MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); //THEN @@ -118,6 +122,21 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTra assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); } + /** + * Creates the parameters to be used for testing the transformation with field transformer. + * @return parameters to be used for testing the transformation with field transformer. + */ + @DataProvider + private Object[][] dataTransformationTesting() { + return new Object[][] { + {"Test that bean containing both final fields (with different names) and not are correctly copied through field transformer.", + new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME), new FieldTransformer<>(IDENTIFIER_FIELD_NAME, BigInteger::negate)}, + {"Test that bean containing both final fields (with different names) and not are correctly copied through the old field mapping and field transformer classes.", + new com.hotels.beans.model.FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME), + new com.hotels.beans.model.FieldTransformer<>(IDENTIFIER_FIELD_NAME, BigInteger::negate)} + }; + } + /** * Test that the copy method sets the default value when the source object does not contain a required field. */ diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index d73d5bc16..d1344d580 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -Prelease -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true fi fi \ No newline at end of file From de425e9db985a3efa66c0ea29fc64e66c59b7886 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 05:52:05 +0200 Subject: [PATCH 0801/1786] Removed map-transformer module --- bull-map-transformer/pom.xml | 16 ---------------- pom.xml | 7 ------- 2 files changed, 23 deletions(-) delete mode 100644 bull-map-transformer/pom.xml diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml deleted file mode 100644 index 1c2752e58..000000000 --- a/bull-map-transformer/pom.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - 4.0.0 - BULL - Map Transformer - bull-map-transformer - jar - Provides a Map Transformer - - - bean-utils-library-parent - com.hotels.beans - 1.5.1-SNAPSHOT - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8fcf49ed1..9e1540634 100644 --- a/pom.xml +++ b/pom.xml @@ -188,7 +188,6 @@ bean-utils-library bull-bean-transformer bull-converter - bull-map-transformer @@ -198,12 +197,6 @@ bull-converter - - map-transformer - - bull-map-transformer - - relaxed From c16fc454eb4a9f2f72926a45cd76cecc8492ff4a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 06:00:11 +0200 Subject: [PATCH 0802/1786] Added test to reach the expected coverage --- .../transformer/AbstractTransformer.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index e78f24269..aa2ead65f 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -17,15 +17,12 @@ package com.hotels.beans.transformer; import static java.util.Arrays.asList; -import static java.util.Arrays.stream; import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; import static com.hotels.transformer.validator.Validator.notNull; import java.util.Map; -import java.util.function.Function; -import com.hotels.beans.BeanUtils; import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; import com.hotels.transformer.cache.CacheManager; import com.hotels.transformer.model.FieldMapping; @@ -107,10 +104,11 @@ public final BeanTransformer withFieldMapping(final FieldMapping... fieldMapping */ @Deprecated(since = "1.6.0", forRemoval = true) public final Transformer withFieldMapping(final com.hotels.beans.model.FieldMapping... fieldMapping) { - com.hotels.transformer.model.FieldMapping[] fieldMappings = stream(fieldMapping) - .map(fm -> new com.hotels.transformer.model.FieldMapping(fm.getSourceFieldName(), fm.getDestFieldName())) - .toArray(com.hotels.transformer.model.FieldMapping[]::new); - return withFieldMapping(fieldMappings); + final Map fieldsNameMapping = settings.getFieldsNameMapping(); + for (FieldMapping mapping : fieldMapping) { + fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); + } + return this; } /** @@ -147,10 +145,11 @@ public final BeanTransformer withFieldTransformer(final FieldTransformer... fiel */ @Deprecated(since = "1.6.0", forRemoval = true) public final Transformer withFieldTransformer(final com.hotels.beans.model.FieldTransformer... fieldTransformer) { - Function transformerFunction = BeanUtils.getTransformer(FieldTransformer.class); - com.hotels.transformer.model.FieldTransformer[] fieldTransformers = stream(fieldTransformer) - .map(transformerFunction).toArray(com.hotels.transformer.model.FieldTransformer[]::new); - return withFieldTransformer(fieldTransformers); + Map fieldsTransformers = settings.getFieldsTransformers(); + for (FieldTransformer transformer : fieldTransformer) { + fieldsTransformers.put(transformer.getDestFieldName(), transformer); + } + return this; } /** From c2b4c5625606e18685a3e4c86f3d908c3f4bb7b1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 10:45:55 +0200 Subject: [PATCH 0803/1786] updated changelog --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- .../src/main/java/com/hotels/beans/BeanUtils.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 9904a2065..2ef22ca90 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.1.24] TBD +### [1.1.24] 2019.09.02 #### Changed * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.1.25`, use `bull-bean-transformer` instead.** ~~~ diff --git a/CHANGELOG.md b/CHANGELOG.md index caec4066c..0b7e3ba0b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.5.1] TBD +### [1.5.1] 2019.09.02 #### Changed * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** ~~~ diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java index 3aac1360c..bc7eeaf45 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java @@ -47,7 +47,7 @@ public static Function getTransformer(final Class targetClass) { /** * Returns a function that transforms an object T in an object K. * @param beanTransformer the transformer to be used. - * @param targetClass the destination object classClassUtilsTest.java + * @param targetClass the destination object * @param the Source object type * @param the target object type * @return a function that copies of the source object into the destination object From 8bf6388562a22b0b4bea38b2afd7b179697253e3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 11:20:33 +0200 Subject: [PATCH 0804/1786] [travis skip] Modified logback test config --- bull-common/src/test/resources/logback-test.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-common/src/test/resources/logback-test.xml b/bull-common/src/test/resources/logback-test.xml index 4da7aad36..a7f88b2a1 100644 --- a/bull-common/src/test/resources/logback-test.xml +++ b/bull-common/src/test/resources/logback-test.xml @@ -23,7 +23,7 @@ - + From f8213d49ae6aeda7128cc8a3ee3a847e640de74e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 11:25:25 +0200 Subject: [PATCH 0805/1786] [maven-release-plugin] prepare release 1.5.1 --- bean-utils-library/pom.xml | 2 +- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index 221dfb005..eb45a62c0 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1-SNAPSHOT + 1.5.1 diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 0cea57189..a4c597a19 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1-SNAPSHOT + 1.5.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index ca641935d..8bd7b8661 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1-SNAPSHOT + 1.5.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index b9907caad..119dd8c2b 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1-SNAPSHOT + 1.5.1 diff --git a/pom.xml b/pom.xml index 9e1540634..78369bec6 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.5.1-SNAPSHOT + 1.5.1 pom 2019 @@ -69,7 +69,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.5.1 From 326d18994ee04090c55e7fadf6597765d878bfac Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 11:25:33 +0200 Subject: [PATCH 0806/1786] [maven-release-plugin] prepare for next development iteration --- bean-utils-library/pom.xml | 2 +- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml index eb45a62c0..7b66fdbee 100644 --- a/bean-utils-library/pom.xml +++ b/bean-utils-library/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1 + 1.5.2-SNAPSHOT diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index a4c597a19..bf0d54be0 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1 + 1.5.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 8bd7b8661..7e45f1659 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1 + 1.5.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 119dd8c2b..0af9e63d6 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1 + 1.5.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 78369bec6..d9bf99a14 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.5.1 + 1.5.2-SNAPSHOT pom 2019 @@ -69,7 +69,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.5.1 + HEAD From 9735bd934368242ad4ddddcd6ddc1817c384a001 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 12:05:47 +0200 Subject: [PATCH 0807/1786] [travis skip] modified converter condition to prevent null pointer exceptions --- .../processor/impl/BigDecimalConversionProcessor.java | 3 ++- .../processor/impl/BigIntegerConversionProcessor.java | 3 ++- .../processor/impl/ByteArrayConversionProcessor.java | 4 +++- .../conversion/processor/impl/ByteConversionProcessor.java | 4 +++- .../processor/impl/CharacterConversionProcessor.java | 3 ++- .../conversion/processor/impl/DoubleConversionProcessor.java | 3 ++- .../conversion/processor/impl/FloatConversionProcessor.java | 3 ++- .../conversion/processor/impl/IntegerConversionProcessor.java | 3 ++- .../conversion/processor/impl/LongConversionProcessor.java | 3 ++- .../conversion/processor/impl/ShortConversionProcessor.java | 3 ++- 10 files changed, 22 insertions(+), 10 deletions(-) diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java index aaa918d48..d5cd66f58 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.math.BigDecimal.valueOf; import static java.nio.ByteBuffer.wrap; @@ -107,7 +108,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? 1 : 0); + return val -> valueOf(TRUE.equals(val) ? 1 : 0); } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java index e1dfee697..fca9e9849 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.math.BigInteger.valueOf; import static java.nio.ByteBuffer.wrap; @@ -107,7 +108,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? 1 : 0); + return val -> valueOf(TRUE.equals(val) ? 1 : 0); } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java index 555774818..37e870a31 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java @@ -16,6 +16,8 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; + import java.math.BigDecimal; import java.math.BigInteger; import java.util.function.Function; @@ -95,7 +97,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> new byte[] {val ? (byte) 1 : (byte) 0}; + return val -> new byte[] {TRUE.equals(val) ? (byte) 1 : (byte) 0}; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index 5c77b63a5..aba4c5f14 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -16,6 +16,8 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; + import java.math.BigDecimal; import java.math.BigInteger; import java.util.function.Function; @@ -95,7 +97,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (byte) 1 : (byte) 0; + return val -> TRUE.equals(val) ? (byte) 1 : (byte) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java index f09471a01..f94f3433e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; @@ -105,7 +106,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? 'T' : 'F'; + return val -> TRUE.equals(val) ? 'T' : 'F'; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index b187e3c50..17debfeb5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.nio.ByteBuffer.wrap; @@ -106,7 +107,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (double) 1 : (double) 0; + return val -> TRUE.equals(val) ? (double) 1 : (double) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index 1b194b38f..8698c7432 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.nio.ByteBuffer.wrap; @@ -106,7 +107,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (float) 1 : (float) 0; + return val -> TRUE.equals(val) ? (float) 1 : (float) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index 2e0a5d3fc..ee2bf1d09 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; @@ -105,7 +106,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? 1 : 0; + return val -> TRUE.equals(val) ? 1 : 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index ff39ed684..f27db998c 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.nio.ByteBuffer.wrap; @@ -106,7 +107,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (long) 1 : (long) 0; + return val -> TRUE.equals(val) ? (long) 1 : (long) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index 3983104a6..18ecd419f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.nio.ByteBuffer.wrap; @@ -106,7 +107,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (short) 1 : (short) 0; + return val -> TRUE.equals(val) ? (short) 1 : (short) 0; } /** From 96d487088a94ee09a84e5824bd49c2e34c22d746 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 12:37:30 +0200 Subject: [PATCH 0808/1786] Removed deprecated classes --- CHANGELOG-JDK8.md | 10 +++- CHANGELOG.md | 10 +++- bean-utils-library/pom.xml | 21 -------- bull-bean-transformer/pom.xml | 2 +- .../main/java/com/hotels/beans/BeanUtils.java | 2 +- .../com/hotels/beans/model/FieldMapping.java | 37 ------------- .../hotels/beans/model/FieldTransformer.java | 53 ------------------- .../com/hotels/beans/model/package-info.java | 20 ------- .../transformer/AbstractTransformer.java | 25 --------- .../beans/transformer/BeanTransformer.java | 1 + .../hotels/beans/transformer/Transformer.java | 45 ---------------- .../MixedObjectTransformationTest.java | 27 ++-------- bull-common/pom.xml | 2 +- .../src/test/resources/logback-test.xml | 2 +- bull-converter/pom.xml | 2 +- .../impl/BigDecimalConversionProcessor.java | 3 +- .../impl/BigIntegerConversionProcessor.java | 3 +- .../impl/ByteArrayConversionProcessor.java | 4 +- .../impl/ByteConversionProcessor.java | 4 +- .../impl/CharacterConversionProcessor.java | 3 +- .../impl/DoubleConversionProcessor.java | 3 +- .../impl/FloatConversionProcessor.java | 3 +- .../impl/IntegerConversionProcessor.java | 3 +- .../impl/LongConversionProcessor.java | 3 +- .../impl/ShortConversionProcessor.java | 3 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 5 +- 27 files changed, 53 insertions(+), 245 deletions(-) delete mode 100644 bean-utils-library/pom.xml delete mode 100644 bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldMapping.java delete mode 100644 bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldTransformer.java delete mode 100644 bull-bean-transformer/src/main/java/com/hotels/beans/model/package-info.java delete mode 100644 bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 9904a2065..6a47df97c 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,15 @@ All notable changes to this project will be documented in this file. -### [1.1.24] TBD +### [1.1.25] TBD +### Removed +* Removed deprecated module `bean-utils-library` +* The following deprecated classes has been removed: + * `com.hotels.beans.model.FieldMapping` + * `com.hotels.beans.model.FieldTransformer` + * `com.hotels.beans.Transformer` + +### [1.1.24] 2019.09.02 #### Changed * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.1.25`, use `bull-bean-transformer` instead.** ~~~ diff --git a/CHANGELOG.md b/CHANGELOG.md index caec4066c..891e373d3 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ All notable changes to this project will be documented in this file. -### [1.5.1] TBD +### [1.6.0] TBD +### Removed +* Removed deprecated module `bean-utils-library` +* The following deprecated classes has been removed: + * `com.hotels.beans.model.FieldMapping` + * `com.hotels.beans.model.FieldTransformer` + * `com.hotels.beans.Transformer` + +### [1.5.1] 2019.09.02 #### Changed * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** ~~~ diff --git a/bean-utils-library/pom.xml b/bean-utils-library/pom.xml deleted file mode 100644 index 221dfb005..000000000 --- a/bean-utils-library/pom.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - 4.0.0 - BULL - Bean Transformer (Deprecated) - bean-utils-library - jar - - - com.hotels.beans - bean-utils-library-parent - 1.5.1-SNAPSHOT - - - - - com.hotels.beans - bull-bean-transformer - Warning: This module has been relocated and will be no longer available since version: 1.6.0, please use bull-bean-transformer instead. - - - \ No newline at end of file diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 0cea57189..50d1230c2 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1-SNAPSHOT + 1.6.0-SNAPSHOT diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java index 3aac1360c..bc7eeaf45 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java @@ -47,7 +47,7 @@ public static Function getTransformer(final Class targetClass) { /** * Returns a function that transforms an object T in an object K. * @param beanTransformer the transformer to be used. - * @param targetClass the destination object classClassUtilsTest.java + * @param targetClass the destination object * @param the Source object type * @param the target object type * @return a function that copies of the source object into the destination object diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldMapping.java b/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldMapping.java deleted file mode 100644 index bbc0a00ed..000000000 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldMapping.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.model; - -import lombok.Getter; -import lombok.ToString; - -/** - * Specifies the field's name mapping between the source object and destination one. - * @deprecated This class will be removed since version 1.6.0 please use {@link com.hotels.transformer.model.FieldMapping} instead. - */ -@Deprecated(since = "1.6.0", forRemoval = true) -@Getter -@ToString -public class FieldMapping extends com.hotels.transformer.model.FieldMapping { - /** - * @param sourceFieldName The field name in the source object. - * @param destFieldName The field name in the destination object. - */ - public FieldMapping(final String sourceFieldName, final String destFieldName) { - super(sourceFieldName, destFieldName); - } -} diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldTransformer.java deleted file mode 100644 index e255f9fb2..000000000 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/model/FieldTransformer.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.model; - -import java.util.function.Function; -import java.util.function.Supplier; - -import lombok.Getter; -import lombok.ToString; - -/** - * Specifies the field mapping between the source object and destination one. - * - * @param input field type. - * @param field value on with apply the function. - * @deprecated This class will be removed since version 1.6.0 please use {@link com.hotels.transformer.model.FieldTransformer} instead. - */ -@Deprecated(since = "1.6.0", forRemoval = true) -@Getter -@ToString -public class FieldTransformer extends com.hotels.transformer.model.FieldTransformer { - /** - * Creates a field transformer with a lambda function to be applied on the field. - * @param destinationFieldName the field name in the destination object. - * @param fieldTransformerFunction the transformer function to apply on field - */ - public FieldTransformer(final String destinationFieldName, final Function fieldTransformerFunction) { - super(destinationFieldName, fieldTransformerFunction); - } - - /** - * Creates a field transformer with a field supplier function to be applied on the field. - * @param destinationFieldName the field name in the destination object. - * @param fieldTransformerSupplier the transformer supplier to apply on field - */ - public FieldTransformer(final String destinationFieldName, final Supplier fieldTransformerSupplier) { - super(destinationFieldName, fieldTransformerSupplier); - } -} diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/model/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/model/package-info.java deleted file mode 100644 index 84d8fce7a..000000000 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/model/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Transformer model package. - * @deprecated This package will be removed since version 1.6.0 please use {@link com.hotels.transformer.model} instead. - */ -package com.hotels.beans.model; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java index e78f24269..b8a2412b3 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java @@ -17,15 +17,12 @@ package com.hotels.beans.transformer; import static java.util.Arrays.asList; -import static java.util.Arrays.stream; import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; import static com.hotels.transformer.validator.Validator.notNull; import java.util.Map; -import java.util.function.Function; -import com.hotels.beans.BeanUtils; import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; import com.hotels.transformer.cache.CacheManager; import com.hotels.transformer.model.FieldMapping; @@ -102,17 +99,6 @@ public final BeanTransformer withFieldMapping(final FieldMapping... fieldMapping return this; } - /** - * {@inheritDoc} - */ - @Deprecated(since = "1.6.0", forRemoval = true) - public final Transformer withFieldMapping(final com.hotels.beans.model.FieldMapping... fieldMapping) { - com.hotels.transformer.model.FieldMapping[] fieldMappings = stream(fieldMapping) - .map(fm -> new com.hotels.transformer.model.FieldMapping(fm.getSourceFieldName(), fm.getDestFieldName())) - .toArray(com.hotels.transformer.model.FieldMapping[]::new); - return withFieldMapping(fieldMappings); - } - /** * {@inheritDoc} */ @@ -142,17 +128,6 @@ public final BeanTransformer withFieldTransformer(final FieldTransformer... fiel return this; } - /** - * {@inheritDoc} - */ - @Deprecated(since = "1.6.0", forRemoval = true) - public final Transformer withFieldTransformer(final com.hotels.beans.model.FieldTransformer... fieldTransformer) { - Function transformerFunction = BeanUtils.getTransformer(FieldTransformer.class); - com.hotels.transformer.model.FieldTransformer[] fieldTransformers = stream(fieldTransformer) - .map(transformerFunction).toArray(com.hotels.transformer.model.FieldTransformer[]::new); - return withFieldTransformer(fieldTransformers); - } - /** * {@inheritDoc} */ diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index c342d5f10..a208c2309 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -16,6 +16,7 @@ package com.hotels.beans.transformer; +import com.hotels.transformer.Transformer; import com.hotels.transformer.model.FieldMapping; import com.hotels.transformer.model.FieldTransformer; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java deleted file mode 100644 index 5a0e814e6..000000000 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/Transformer.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.transformer; - -import com.hotels.beans.model.FieldMapping; -import com.hotels.beans.model.FieldTransformer; - -/** - * Utility methods for all objects transformation. - * @deprecated This class will be removed since version 1.6.0 please use {@link com.hotels.transformer.Transformer} instead. - */ -@Deprecated(since = "1.6.0", forRemoval = true) -public interface Transformer extends com.hotels.transformer.Transformer { - /** - * Initializes the mapping between fields in the source object and the destination one. - * @param fieldMapping the field mapping - * @return the {@link Transformer} instance - * @deprecated use {@code withFieldMapping(com.hotels.transformer.model.FieldMapping)} instead. - */ - @Deprecated(since = "1.6.0", forRemoval = true) - Transformer withFieldMapping(FieldMapping... fieldMapping); - - /** - * Initializes the field transformer functions. The transformer function returns directly the field value. - * @param fieldTransformer the fields transformer function - * @return the {@link Transformer} instance - * @deprecated use {@code withFieldMapping(com.hotels.transformer.model.FieldTransformer)} instead. - */ - @Deprecated(since = "1.6.0", forRemoval = true) - Transformer withFieldTransformer(FieldTransformer... fieldTransformer); -} diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index ee57b3e57..fdc4ebfe4 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -27,7 +27,6 @@ import java.math.BigInteger; import java.util.stream.IntStream; -import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.hotels.beans.sample.FromFooSimple; @@ -96,21 +95,18 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { /** * Test that bean containing both final fields (with different names) and not are correctly copied through field transformer. - * @param testCaseDescription the test case description - * @param fieldMapping the field mapping definition - * @param fieldTransformer the transformer function to apply */ - @Test(dataProvider = "dataTransformationTesting") - public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTransformer(final String testCaseDescription, - final FieldMapping fieldMapping, final FieldTransformer fieldTransformer) { + @Test + public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTransformer() { //GIVEN /* Extended FieldTransformer function declaration. * Function idTransformer = value -> value.negate(); * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", idTransformer); */ + FieldTransformer fieldTransformer = new FieldTransformer<>(IDENTIFIER_FIELD_NAME, BigInteger::negate); //WHEN - underTest.withFieldMapping(fieldMapping).withFieldTransformer(fieldTransformer); + underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)).withFieldTransformer(fieldTransformer); MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); //THEN @@ -122,21 +118,6 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTra assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); } - /** - * Creates the parameters to be used for testing the transformation with field transformer. - * @return parameters to be used for testing the transformation with field transformer. - */ - @DataProvider - private Object[][] dataTransformationTesting() { - return new Object[][] { - {"Test that bean containing both final fields (with different names) and not are correctly copied through field transformer.", - new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME), new FieldTransformer<>(IDENTIFIER_FIELD_NAME, BigInteger::negate)}, - {"Test that bean containing both final fields (with different names) and not are correctly copied through the old field mapping and field transformer classes.", - new com.hotels.beans.model.FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME), - new com.hotels.beans.model.FieldTransformer<>(IDENTIFIER_FIELD_NAME, BigInteger::negate)} - }; - } - /** * Test that the copy method sets the default value when the source object does not contain a required field. */ diff --git a/bull-common/pom.xml b/bull-common/pom.xml index ca641935d..61bb9ed12 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1-SNAPSHOT + 1.6.0-SNAPSHOT diff --git a/bull-common/src/test/resources/logback-test.xml b/bull-common/src/test/resources/logback-test.xml index 4da7aad36..a7f88b2a1 100644 --- a/bull-common/src/test/resources/logback-test.xml +++ b/bull-common/src/test/resources/logback-test.xml @@ -23,7 +23,7 @@ - + diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index b9907caad..50c74e7db 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.5.1-SNAPSHOT + 1.6.0-SNAPSHOT diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java index aaa918d48..d5cd66f58 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.math.BigDecimal.valueOf; import static java.nio.ByteBuffer.wrap; @@ -107,7 +108,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? 1 : 0); + return val -> valueOf(TRUE.equals(val) ? 1 : 0); } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java index e1dfee697..fca9e9849 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.math.BigInteger.valueOf; import static java.nio.ByteBuffer.wrap; @@ -107,7 +108,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> valueOf(val ? 1 : 0); + return val -> valueOf(TRUE.equals(val) ? 1 : 0); } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java index 555774818..37e870a31 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java @@ -16,6 +16,8 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; + import java.math.BigDecimal; import java.math.BigInteger; import java.util.function.Function; @@ -95,7 +97,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> new byte[] {val ? (byte) 1 : (byte) 0}; + return val -> new byte[] {TRUE.equals(val) ? (byte) 1 : (byte) 0}; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index 5c77b63a5..aba4c5f14 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -16,6 +16,8 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; + import java.math.BigDecimal; import java.math.BigInteger; import java.util.function.Function; @@ -95,7 +97,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (byte) 1 : (byte) 0; + return val -> TRUE.equals(val) ? (byte) 1 : (byte) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java index f09471a01..f94f3433e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; @@ -105,7 +106,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? 'T' : 'F'; + return val -> TRUE.equals(val) ? 'T' : 'F'; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index b187e3c50..17debfeb5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.nio.ByteBuffer.wrap; @@ -106,7 +107,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (double) 1 : (double) 0; + return val -> TRUE.equals(val) ? (double) 1 : (double) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index 1b194b38f..8698c7432 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.nio.ByteBuffer.wrap; @@ -106,7 +107,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (float) 1 : (float) 0; + return val -> TRUE.equals(val) ? (float) 1 : (float) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index 2e0a5d3fc..ee2bf1d09 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.nio.ByteBuffer.wrap; import java.math.BigDecimal; @@ -105,7 +106,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? 1 : 0; + return val -> TRUE.equals(val) ? 1 : 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index ff39ed684..f27db998c 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.nio.ByteBuffer.wrap; @@ -106,7 +107,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (long) 1 : (long) 0; + return val -> TRUE.equals(val) ? (long) 1 : (long) 0; } /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index 3983104a6..18ecd419f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -16,6 +16,7 @@ package com.hotels.beans.conversion.processor.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; import static java.nio.ByteBuffer.wrap; @@ -106,7 +107,7 @@ public Function convertCharacter() { */ @Override public Function convertBoolean() { - return val -> val ? (short) 1 : (short) 0; + return val -> TRUE.equals(val) ? (short) 1 : (short) 0; } /** diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 1c2752e58..d92c033b4 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -11,6 +11,6 @@ bean-utils-library-parent com.hotels.beans - 1.5.1-SNAPSHOT + 1.6.0-SNAPSHOT \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8fcf49ed1..d73c2cc77 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.5.1-SNAPSHOT + 1.6.0-SNAPSHOT pom 2019 @@ -185,7 +185,6 @@ true - bean-utils-library bull-bean-transformer bull-converter bull-map-transformer @@ -194,7 +193,7 @@ bean-transformer - bean-utils-library + bull-bean-transformer bull-converter From 8208d6e129cc592d153301bbb50a1dff79ac78bc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 16:12:41 +0200 Subject: [PATCH 0809/1786] [travis skip] updated readme badge --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index fa1d23e16..d0451d7e6 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,7 @@ BULL is a Java Bean to Java Bean transformer that recursively copies data from o It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. ## Start using - -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE) From 140e16257ad09bf329abc9a6588bea38a24a2898 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 17:51:18 +0200 Subject: [PATCH 0810/1786] - Added MapTransformer interface - Modified logback configuration to produce specific logs for each module --- .../config/logging/logback-appenders.xml | 4 +-- .../{main => test}/resources/logback-test.xml | 0 .../config/logging/logback-appenders.xml | 4 +-- bull-map-transformer/pom.xml | 21 +++++++++++ .../map/transformer/MapTransformer.java | 25 +++++++++++++ .../hotels/map/transformer/package-info.java | 20 +++++++++++ .../config/logging/logback-appenders.xml | 30 ++++++++++++++++ .../config/logging/logback-properties.xml | 5 +++ .../src/main/resources/logback.xml | 36 +++++++++++++++++++ .../test/resources/config/logback-test.xml | 36 +++++++++++++++++++ .../config/logging/logback-appenders.xml | 30 ++++++++++++++++ .../config/logging/logback-properties.xml | 5 +++ .../org.mockito.plugins.MockMaker | 1 + 13 files changed, 213 insertions(+), 4 deletions(-) rename bull-bean-transformer/src/{main => test}/resources/logback-test.xml (100%) create mode 100644 bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java create mode 100644 bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java create mode 100644 bull-map-transformer/src/main/resources/config/logging/logback-appenders.xml create mode 100644 bull-map-transformer/src/main/resources/config/logging/logback-properties.xml create mode 100644 bull-map-transformer/src/main/resources/logback.xml create mode 100644 bull-map-transformer/src/test/resources/config/logback-test.xml create mode 100644 bull-map-transformer/src/test/resources/config/logging/logback-appenders.xml create mode 100644 bull-map-transformer/src/test/resources/config/logging/logback-properties.xml create mode 100644 bull-map-transformer/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml b/bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml index 3bfd17005..570ecb4f0 100644 --- a/bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml +++ b/bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml @@ -12,14 +12,14 @@ - ${ROOT_LOG_DIR}/bean-utils-library.log + ${ROOT_LOG_DIR}/bull-bean-transformer.log true UTF-8 ${LOG_PATTERN} - ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip + ${ROOT_LOG_DIR}/bull-bean-transformer-%d{yyyy-MM-dd}-%i.log.zip 30 diff --git a/bull-bean-transformer/src/main/resources/logback-test.xml b/bull-bean-transformer/src/test/resources/logback-test.xml similarity index 100% rename from bull-bean-transformer/src/main/resources/logback-test.xml rename to bull-bean-transformer/src/test/resources/logback-test.xml diff --git a/bull-common/src/test/resources/config/logging/logback-appenders.xml b/bull-common/src/test/resources/config/logging/logback-appenders.xml index 3bfd17005..d677974af 100644 --- a/bull-common/src/test/resources/config/logging/logback-appenders.xml +++ b/bull-common/src/test/resources/config/logging/logback-appenders.xml @@ -12,14 +12,14 @@ - ${ROOT_LOG_DIR}/bean-utils-library.log + ${ROOT_LOG_DIR}/bull-common.log true UTF-8 ${LOG_PATTERN} - ${ROOT_LOG_DIR}/bean-utils-library-%d{yyyy-MM-dd}-%i.log.zip + ${ROOT_LOG_DIR}/bull-common-%d{yyyy-MM-dd}-%i.log.zip 30 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index d92c033b4..d21e5136c 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -13,4 +13,25 @@ com.hotels.beans 1.6.0-SNAPSHOT + + + + com.hotels.beans + bull-common + ${project.version} + + + + com.hotels.beans + bull-common + ${project.version} + test-jar + test + + + com.shazam + shazamcrest + test + + \ No newline at end of file diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java new file mode 100644 index 000000000..e966dc7f0 --- /dev/null +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -0,0 +1,25 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.map.transformer; + +import com.hotels.transformer.Transformer; + +/** + * Utility methods for populating {@link java.util.Map} elements via reflection. + */ +public interface MapTransformer extends Transformer { +} diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java new file mode 100644 index 000000000..c9df4dbae --- /dev/null +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Map transformer package. + */ + +package com.hotels.map.transformer; diff --git a/bull-map-transformer/src/main/resources/config/logging/logback-appenders.xml b/bull-map-transformer/src/main/resources/config/logging/logback-appenders.xml new file mode 100644 index 000000000..b8fab1514 --- /dev/null +++ b/bull-map-transformer/src/main/resources/config/logging/logback-appenders.xml @@ -0,0 +1,30 @@ + + + + + + + + + ${LOG_PATTERN} + + + + + + ${ROOT_LOG_DIR}/bull-map-transformer.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/bull-map-transformer-%d{yyyy-MM-dd}-%i.log.zip + + 30 + + 5MB + + + + \ No newline at end of file diff --git a/bull-map-transformer/src/main/resources/config/logging/logback-properties.xml b/bull-map-transformer/src/main/resources/config/logging/logback-properties.xml new file mode 100644 index 000000000..934b4e88b --- /dev/null +++ b/bull-map-transformer/src/main/resources/config/logging/logback-properties.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/bull-map-transformer/src/main/resources/logback.xml b/bull-map-transformer/src/main/resources/logback.xml new file mode 100644 index 000000000..7e554a30c --- /dev/null +++ b/bull-map-transformer/src/main/resources/logback.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bull-map-transformer/src/test/resources/config/logback-test.xml b/bull-map-transformer/src/test/resources/config/logback-test.xml new file mode 100644 index 000000000..37cdb1081 --- /dev/null +++ b/bull-map-transformer/src/test/resources/config/logback-test.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bull-map-transformer/src/test/resources/config/logging/logback-appenders.xml b/bull-map-transformer/src/test/resources/config/logging/logback-appenders.xml new file mode 100644 index 000000000..b8fab1514 --- /dev/null +++ b/bull-map-transformer/src/test/resources/config/logging/logback-appenders.xml @@ -0,0 +1,30 @@ + + + + + + + + + ${LOG_PATTERN} + + + + + + ${ROOT_LOG_DIR}/bull-map-transformer.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/bull-map-transformer-%d{yyyy-MM-dd}-%i.log.zip + + 30 + + 5MB + + + + \ No newline at end of file diff --git a/bull-map-transformer/src/test/resources/config/logging/logback-properties.xml b/bull-map-transformer/src/test/resources/config/logging/logback-properties.xml new file mode 100644 index 000000000..934b4e88b --- /dev/null +++ b/bull-map-transformer/src/test/resources/config/logging/logback-properties.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/bull-map-transformer/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/bull-map-transformer/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 000000000..ca6ee9cea --- /dev/null +++ b/bull-map-transformer/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file From 80befeaed2d83c4da52e83088f3cbc170f1ece45 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 18:02:25 +0200 Subject: [PATCH 0811/1786] added MapTransformer methods --- .../map/transformer/MapTransformer.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index e966dc7f0..265bec36b 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -16,10 +16,36 @@ package com.hotels.map.transformer; +import java.util.Map; + import com.hotels.transformer.Transformer; /** * Utility methods for populating {@link java.util.Map} elements via reflection. */ public interface MapTransformer extends Transformer { + /** + * Copies all properties from a map to a new one. + * @param sourceMap the source map + * @param targetMapClass the target map class + * @param the key object type in the source map + * @param the elem object type in the source map + * @param the key object type in the target map + * @param the elem object type in the target map + * @return a copy of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + Map transform(Map sourceMap, Class> targetMapClass); + + /** + * Copies all properties from a map to a new one. + * @param sourceMap the source object + * @param targetMap the destination object + * @param the key object type in the source map + * @param the elem object type in the source map + * @param the key object type in the target map + * @param the elem object type in the target map + * @throws IllegalArgumentException if any parameter is invalid + */ + void transform(Map sourceMap, Map targetMap); } From 854461dc481e26e6a16028a9e04826f2301e7ead Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Sep 2019 21:56:30 +0200 Subject: [PATCH 0812/1786] [travis skip] modified readme badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d0451d7e6..fa1d23e16 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ BULL is a Java Bean to Java Bean transformer that recursively copies data from o It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. ## Start using -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) + +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE) From 2a30d5edd06fdf91e9c029e3c91d9ba02c5d7b0a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2019 02:47:25 +0000 Subject: [PATCH 0813/1786] Bump hotels-oss-parent from 4.1.0 to 4.2.0 Bumps [hotels-oss-parent](https://github.com/HotelsDotCom/hotels-oss-parent) from 4.1.0 to 4.2.0. - [Release notes](https://github.com/HotelsDotCom/hotels-oss-parent/releases) - [Changelog](https://github.com/HotelsDotCom/hotels-oss-parent/blob/master/CHANGELOG.md) - [Commits](https://github.com/HotelsDotCom/hotels-oss-parent/compare/hotels-oss-parent-4.1.0...hotels-oss-parent-4.2.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d9bf99a14..3c0adb797 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.hotels hotels-oss-parent - 4.1.0 + 4.2.0 From bd7cf626a7100dc1a16e180f8d0153f2aecb1a94 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 3 Sep 2019 09:25:57 +0200 Subject: [PATCH 0814/1786] Bumped mockito version --- pom.xml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3c0adb797..3a8ab780c 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ 0.11 2.8.5 7.0.0 - 1.3.0 + 3.0.0 2.0.1.Final 6.0.17.Final @@ -44,7 +44,6 @@ 3.0.0 2.2.6 - 0.8.3 1.0 0.90 1.0 @@ -112,6 +111,18 @@ spring-boot-starter-test ${spring-boot.version} test + + + org.mockito + mockito-core + + + + + org.mockito + mockito-core + ${mockito.version} + test org.slf4j @@ -169,6 +180,11 @@ spring-boot-starter-test test + + org.mockito + mockito-core + test + org.testng testng From 687bb7412305403668226423fe83826616ddb844 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 3 Sep 2019 18:00:16 +0200 Subject: [PATCH 0815/1786] Started map transformer implementation --- .../java/com/hotels/beans/package-info.java | 2 +- .../beans/transformer/BeanTransformer.java | 2 +- .../main/java/com/hotels/map/MapUtils.java | 33 +++++++++++ .../java/com/hotels/map/package-info.java | 20 +++++++ .../map/transformer/MapTransformer.java | 1 + .../map/transformer/MapTransformerImpl.java | 56 +++++++++++++++++++ 6 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java create mode 100644 bull-map-transformer/src/main/java/com/hotels/map/package-info.java create mode 100644 bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java index 99cdebc36..7b3b33b6a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Main package. + * Bean transformer main package. */ package com.hotels.beans; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index a208c2309..1c63837a9 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -22,7 +22,7 @@ /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. - * The implementations are provided by BeanUtils. + * The implementations are provided by {@link TransformerImpl}. */ public interface BeanTransformer extends Transformer { /** diff --git a/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java b/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java new file mode 100644 index 000000000..63868752d --- /dev/null +++ b/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.map; + +import com.hotels.map.transformer.MapTransformer; +import com.hotels.map.transformer.MapTransformerImpl; + +/** + * Set of Map utilities. + */ +public class MapUtils { + /** + * Returns a Map Transformer. + * @return a {@link MapTransformer} instance. + */ + public final MapTransformer getTransformer() { + return new MapTransformerImpl(); + } +} diff --git a/bull-map-transformer/src/main/java/com/hotels/map/package-info.java b/bull-map-transformer/src/main/java/com/hotels/map/package-info.java new file mode 100644 index 000000000..fcabff560 --- /dev/null +++ b/bull-map-transformer/src/main/java/com/hotels/map/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Map transformer main package. + */ + +package com.hotels.map; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index 265bec36b..1fb924273 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -22,6 +22,7 @@ /** * Utility methods for populating {@link java.util.Map} elements via reflection. + * The implementations are provided by {@link MapTransformerImpl}. */ public interface MapTransformer extends Transformer { /** diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java new file mode 100644 index 000000000..98e3321c7 --- /dev/null +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.map.transformer; + +import java.util.Map; + +/** + * Utility methods for populating {@link java.util.Map} elements via reflection. + */ +public class MapTransformerImpl implements MapTransformer { + /** + * {@inheritDoc} + */ + @Override + public Map transform(final Map sourceMap, final Class> targetMapClass) { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public void transform(final Map sourceMap, final Map targetMap) { + + } + + /** + * {@inheritDoc} + */ + @Override + public K transform(final T sourceObj, final Class targetClass) { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public void transform(final T sourceObj, final K targetObject) { + + } +} From 80bf352f979349f5c902e0ed047890d6a376f281 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 5 Sep 2019 09:50:18 +0200 Subject: [PATCH 0816/1786] Common code refactoring --- ...rmer.java => AbstractBeanTransformer.java} | 90 ++------------- .../beans/transformer/BeanTransformer.java | 38 ------ .../beans/transformer/TransformerImpl.java | 2 +- .../transformer/BeanTransformerTest.java | 3 +- .../ImmutableObjectTransformationTest.java | 5 +- .../MixedObjectTransformationTest.java | 3 +- .../transformer/AbstractTransformer.java | 109 ++++++++++++++++++ .../com/hotels/transformer/Transformer.java | 39 +++++++ .../model}/TransformerSettings.java | 6 +- .../transformer/AbstractMapTransformer.java | 79 +++++++++++++ .../map/transformer/MapTransformer.java | 8 ++ .../map/transformer/MapTransformerImpl.java | 2 +- .../model/MapTransformerSettings.java | 43 +++++++ .../map/transformer/model/package-info.java | 20 ++++ 14 files changed, 321 insertions(+), 126 deletions(-) rename bull-bean-transformer/src/main/java/com/hotels/beans/transformer/{AbstractTransformer.java => AbstractBeanTransformer.java} (70%) create mode 100644 bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java rename {bull-bean-transformer/src/main/java/com/hotels/beans/transformer => bull-common/src/main/java/com/hotels/transformer/model}/TransformerSettings.java (96%) create mode 100644 bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java create mode 100644 bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java create mode 100644 bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java similarity index 70% rename from bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java rename to bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java index b8a2412b3..bc1184cab 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java @@ -18,17 +18,15 @@ import static java.util.Arrays.asList; -import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; import static com.hotels.transformer.validator.Validator.notNull; import java.util.Map; import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; -import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.AbstractTransformer; import com.hotels.transformer.model.FieldMapping; import com.hotels.transformer.model.FieldTransformer; -import com.hotels.transformer.utils.ClassUtils; -import com.hotels.transformer.utils.ReflectionUtils; +import com.hotels.transformer.model.TransformerSettings; import com.hotels.transformer.validator.Validator; import com.hotels.transformer.validator.ValidatorImpl; @@ -36,36 +34,11 @@ * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * Contains all method implementation that will be common to any {@link BeanTransformer} implementation. */ -abstract class AbstractTransformer implements BeanTransformer { +abstract class AbstractBeanTransformer extends AbstractTransformer implements BeanTransformer { /** * The cache key prefix for the Transformer Functions. */ - static final String TRANSFORMER_FUNCTION_CACHE_PREFIX = "TransformerFunction"; - - /** - * A regex that returns all the transformer function cached items. - */ - private static final String TRANSFORMER_FUNCTION_REGEX = "^" + TRANSFORMER_FUNCTION_CACHE_PREFIX + ".*"; - - /** - * Reflection utils instance {@link ReflectionUtils}. - */ - final ReflectionUtils reflectionUtils; - - /** - * Class utils instance {@link ClassUtils}. - */ - final ClassUtils classUtils; - - /** - * CacheManager instance {@link CacheManager}. - */ - final CacheManager cacheManager; - - /** - * Contains both the field name mapping and the lambda function to be applied on fields. - */ - final TransformerSettings settings; + static final String TRANSFORMER_FUNCTION_CACHE_PREFIX = "BeanTransformerFunction"; /** * Bean Validator. It offers the possibility to validate a given Java Bean against a set of defined constraints. @@ -80,16 +53,13 @@ abstract class AbstractTransformer implements BeanTransformer { /** * Default constructor. */ - AbstractTransformer() { - this.reflectionUtils = new ReflectionUtils(); - this.classUtils = new ClassUtils(); - this.settings = new TransformerSettings(); - this.cacheManager = getCacheManager("transformer"); + AbstractBeanTransformer() { + super(TRANSFORMER_FUNCTION_CACHE_PREFIX, "beanTransformer", new TransformerSettings()); } /** - * {@inheritDoc} - */ + * {@inheritDoc} + */ @Override public final BeanTransformer withFieldMapping(final FieldMapping... fieldMapping) { final Map fieldsNameMapping = settings.getFieldsNameMapping(); @@ -103,17 +73,9 @@ public final BeanTransformer withFieldMapping(final FieldMapping... fieldMapping * {@inheritDoc} */ @Override - public final void removeFieldMapping(final String destFieldName) { - notNull(destFieldName, "The field name for which the mapping has to be removed cannot be null!"); - settings.getFieldsNameMapping().remove(destFieldName); - } - - /** - * {@inheritDoc} - */ - @Override - public final void resetFieldsMapping() { - settings.getFieldsNameMapping().clear(); + public final BeanTransformer setDefaultValueForMissingField(final boolean useDefaultValue) { + settings.setSetDefaultValueForMissingField(useDefaultValue); + return this; } /** @@ -128,34 +90,6 @@ public final BeanTransformer withFieldTransformer(final FieldTransformer... fiel return this; } - /** - * {@inheritDoc} - */ - @Override - public final void removeFieldTransformer(final String destFieldName) { - notNull(destFieldName, "The field name for which the transformer function has to be removed cannot be null!"); - settings.getFieldsTransformers().remove(destFieldName); - cacheManager.removeMatchingKeys(TRANSFORMER_FUNCTION_REGEX + destFieldName); - } - - /** - * {@inheritDoc} - */ - @Override - public final void resetFieldsTransformer() { - settings.getFieldsTransformers().clear(); - cacheManager.removeMatchingKeys(TRANSFORMER_FUNCTION_REGEX); - } - - /** - * {@inheritDoc} - */ - @Override - public final BeanTransformer setDefaultValueForMissingField(final boolean useDefaultValue) { - settings.setSetDefaultValueForMissingField(useDefaultValue); - return this; - } - /** * {@inheritDoc} */ @@ -195,7 +129,7 @@ public BeanTransformer setPrimitiveTypeConversionEnabled(final boolean primitive if (primitiveTypeConversionEnabled) { conversionAnalyzer = new ConversionAnalyzer(); } else { - cacheManager.removeMatchingKeys(TRANSFORMER_FUNCTION_REGEX); + cacheManager.removeMatchingKeys(transformerFunctionRegex); } return this; } diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index 1c63837a9..60eee1040 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -17,50 +17,12 @@ package com.hotels.beans.transformer; import com.hotels.transformer.Transformer; -import com.hotels.transformer.model.FieldMapping; -import com.hotels.transformer.model.FieldTransformer; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * The implementations are provided by {@link TransformerImpl}. */ public interface BeanTransformer extends Transformer { - /** - * Initializes the mapping between fields in the source object and the destination one. - * @param fieldMapping the field mapping - * @return the {@link BeanTransformer} instance - */ - BeanTransformer withFieldMapping(FieldMapping... fieldMapping); - - /** - * Removes the field mapping for the given field. - * @param destFieldName the field name in the destination object - */ - void removeFieldMapping(String destFieldName); - - /** - * Removes all the configured fields mapping. - */ - void resetFieldsMapping(); - - /** - * Initializes the field transformer functions. The transformer function returns directly the field value. - * @param fieldTransformer the fields transformer function - * @return the {@link BeanTransformer} instance - */ - BeanTransformer withFieldTransformer(FieldTransformer... fieldTransformer); - - /** - * Removes the field transformer for the given field. - * @param destFieldName the field name in the destination object - */ - void removeFieldTransformer(String destFieldName); - - /** - * Removes all the configured fields transformer. - */ - void resetFieldsTransformer(); - /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index f9eb00645..439e00fbe 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -52,7 +52,7 @@ * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * The implementations are provided by BeanUtils. */ -public class TransformerImpl extends AbstractTransformer { +public class TransformerImpl extends AbstractBeanTransformer { /** * {@inheritDoc} */ diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 5ea9ab86f..83e808ae4 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -49,6 +49,7 @@ import com.hotels.transformer.error.MissingFieldException; import com.hotels.transformer.model.FieldMapping; import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.model.TransformerSettings; import com.hotels.transformer.utils.ClassUtils; import com.hotels.transformer.utils.ReflectionUtils; @@ -219,7 +220,7 @@ public void testThatPrimitiveTypeConversionIsCorrectlyEnabled() { underTest.setPrimitiveTypeConversionEnabled(true); //WHEN - boolean actual = underTest.settings.isPrimitiveTypeConversionEnabled(); + boolean actual = underTest.getSettings().isPrimitiveTypeConversionEnabled(); //THEN assertTrue(actual); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 7c23abb45..da1dfd699 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -60,6 +60,7 @@ import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; +import com.hotels.transformer.Transformer; import com.hotels.transformer.annotation.ConstructorArg; import com.hotels.transformer.cache.CacheManager; import com.hotels.transformer.error.InvalidBeanException; @@ -260,7 +261,7 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); + final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); //THEN @@ -285,7 +286,7 @@ public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String te //GIVEN //WHEN - final BeanTransformer beanTransformer = underTest + final Transformer beanTransformer = underTest .withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)) .withFieldMapping(new FieldMapping(PRICE_FIELD_NAME, NET_PRICE_FIELD_NAME)) .withFieldMapping(new FieldMapping(PRICE_FIELD_NAME, GROSS_PRICE_FIELD_NAME)) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index fdc4ebfe4..46afdf628 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -35,6 +35,7 @@ import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; import com.hotels.beans.sample.mixed.MixedToFooMissingField; import com.hotels.beans.sample.mixed.MixedToFooNotExistingFields; +import com.hotels.transformer.Transformer; import com.hotels.transformer.error.MissingFieldException; import com.hotels.transformer.model.FieldMapping; import com.hotels.transformer.model.FieldTransformer; @@ -81,7 +82,7 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); + final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); //THEN diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java new file mode 100644 index 000000000..de5813c62 --- /dev/null +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -0,0 +1,109 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.transformer; + +import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.transformer.validator.Validator.notNull; + +import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.model.TransformerSettings; +import com.hotels.transformer.utils.ClassUtils; +import com.hotels.transformer.utils.ReflectionUtils; + +import lombok.Getter; + +/** + * Abstract class containing all method implementation that will be common to any {@link Transformer}. + * @param the {@link TransformerSettings} implementation. + */ +public abstract class AbstractTransformer implements Transformer { + /** + * Reflection utils instance {@link ReflectionUtils}. + */ + protected final ReflectionUtils reflectionUtils; + + /** + * Class utils instance {@link ClassUtils}. + */ + protected final ClassUtils classUtils; + + /** + * CacheManager instance {@link CacheManager}. + */ + protected final CacheManager cacheManager; + + /** + * A regex that returns all the transformer function cached items. + */ + protected final String transformerFunctionRegex; + + /** + * Contains both the field name mapping and the lambda function to be applied on fields. + */ + @Getter + protected final S settings; + + /** + * Default constructor. + * @param transformerFunctionCachePrefix the cache key prefix for the Transformer Functions. + * @param cacheName the cache key prefix for the transformer. + * @param transformerSettings contains the transformer configuration. + */ + protected AbstractTransformer(final String transformerFunctionCachePrefix, final String cacheName, final S transformerSettings) { + this.reflectionUtils = new ReflectionUtils(); + this.classUtils = new ClassUtils(); + this.settings = transformerSettings; + this.transformerFunctionRegex = "^" + transformerFunctionCachePrefix + ".*"; + this.cacheManager = getCacheManager(cacheName); + } + + /** + * {@inheritDoc} + */ + @Override + public final void removeFieldMapping(final String destFieldName) { + notNull(destFieldName, "The field name for which the mapping has to be removed cannot be null!"); + settings.getFieldsNameMapping().remove(destFieldName); + } + + /** + * {@inheritDoc} + */ + @Override + public final void resetFieldsMapping() { + settings.getFieldsNameMapping().clear(); + } + + /** + * {@inheritDoc} + */ + @Override + public final void removeFieldTransformer(final String destFieldName) { + notNull(destFieldName, "The field name for which the transformer function has to be removed cannot be null!"); + settings.getFieldsTransformers().remove(destFieldName); + cacheManager.removeMatchingKeys(transformerFunctionRegex + destFieldName); + } + + /** + * {@inheritDoc} + */ + @Override + public final void resetFieldsTransformer() { + settings.getFieldsTransformers().clear(); + cacheManager.removeMatchingKeys(transformerFunctionRegex); + } +} diff --git a/bull-common/src/main/java/com/hotels/transformer/Transformer.java b/bull-common/src/main/java/com/hotels/transformer/Transformer.java index c95420bda..dd0086d96 100644 --- a/bull-common/src/main/java/com/hotels/transformer/Transformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/Transformer.java @@ -16,6 +16,9 @@ package com.hotels.transformer; +import com.hotels.transformer.model.FieldMapping; +import com.hotels.transformer.model.FieldTransformer; + /** * Utility methods for all objects transformation. */ @@ -40,4 +43,40 @@ public interface Transformer { * @throws IllegalArgumentException if any parameter is invalid */ void transform(T sourceObj, K targetObject); + + /** + * Initializes the mapping between fields in the source object and the destination one. + * @param fieldMapping the field mapping + * @return the {@link Transformer} instance + */ + Transformer withFieldMapping(FieldMapping... fieldMapping); + + /** + * Removes the field mapping for the given field. + * @param destFieldName the field name in the destination object + */ + void removeFieldMapping(String destFieldName); + + /** + * Removes all the configured fields mapping. + */ + void resetFieldsMapping(); + + /** + * Initializes the field transformer functions. The transformer function returns directly the field value. + * @param fieldTransformer the fields transformer function + * @return the {@link Transformer} instance + */ + Transformer withFieldTransformer(FieldTransformer... fieldTransformer); + + /** + * Removes the field transformer for the given field. + * @param destFieldName the field name in the destination object + */ + void removeFieldTransformer(String destFieldName); + + /** + * Removes all the configured fields transformer. + */ + void resetFieldsTransformer(); } diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerSettings.java b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java similarity index 96% rename from bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerSettings.java rename to bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java index 7eddbb6bd..78cc5f30d 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerSettings.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java @@ -14,15 +14,13 @@ * limitations under the License. */ -package com.hotels.beans.transformer; +package com.hotels.transformer.model; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import com.hotels.transformer.model.FieldTransformer; - import lombok.Getter; import lombok.Setter; @@ -34,7 +32,7 @@ * 3) Other configurations. */ @Getter -final class TransformerSettings { +public class TransformerSettings { /** * Contains the mapping between fields's name in the source object and the destination one. */ diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java new file mode 100644 index 000000000..ea19f6013 --- /dev/null +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.map.transformer; + +import java.util.Map; + +import com.hotels.map.transformer.model.MapTransformerSettings; +import com.hotels.transformer.AbstractTransformer; +import com.hotels.transformer.model.FieldMapping; +import com.hotels.transformer.model.FieldTransformer; + +/** + * Utility methods for populating {@link java.util.Map} elements via reflection.. + * Contains all method implementation that will be common to any {@link MapTransformer} implementation. + */ +abstract class AbstractMapTransformer extends AbstractTransformer implements MapTransformer { + /** + * The cache key prefix for the Transformer Functions. + */ + private static final String TRANSFORMER_FUNCTION_CACHE_PREFIX = "MapTransformerFunction"; + + /** + * Default constructor. + */ + AbstractMapTransformer() { + super(TRANSFORMER_FUNCTION_CACHE_PREFIX, "mapTransformer", new MapTransformerSettings()); + } + + /** + * {@inheritDoc} + */ + @Override + public final MapTransformer withFieldMapping(final FieldMapping... fieldMapping) { + final Map fieldsNameMapping = settings.getFieldsNameMapping(); + for (FieldMapping mapping : fieldMapping) { + fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); + } + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public final MapTransformer withFieldTransformer(final FieldTransformer... fieldTransformer) { + Map fieldsTransformers = settings.getFieldsTransformers(); + for (FieldTransformer transformer : fieldTransformer) { + fieldsTransformers.put(transformer.getDestFieldName(), transformer); + } + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public MapTransformer withKeyTransformer(final FieldTransformer... keyFieldTransformer) { + final Map keyFieldsTransformers = settings.getKeyFieldsTransformers(); + for (FieldTransformer transformer : keyFieldTransformer) { + keyFieldsTransformers.put(transformer.getDestFieldName(), transformer); + } + return this; + } + +} diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index 1fb924273..1493656b6 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -19,6 +19,7 @@ import java.util.Map; import com.hotels.transformer.Transformer; +import com.hotels.transformer.model.FieldTransformer; /** * Utility methods for populating {@link java.util.Map} elements via reflection. @@ -49,4 +50,11 @@ public interface MapTransformer extends Transformer { * @throws IllegalArgumentException if any parameter is invalid */ void transform(Map sourceMap, Map targetMap); + + /** + * Initializes the transformer functions to apply on a Map key. The transformer function returns directly the field value. + * @param keyFieldTransformer the fields transformer function + * @return the {@link Transformer} instance + */ + MapTransformer withKeyTransformer(FieldTransformer... keyFieldTransformer); } diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index 98e3321c7..ac8afb884 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -21,7 +21,7 @@ /** * Utility methods for populating {@link java.util.Map} elements via reflection. */ -public class MapTransformerImpl implements MapTransformer { +public class MapTransformerImpl extends AbstractMapTransformer { /** * {@inheritDoc} */ diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java new file mode 100644 index 000000000..d70e1849e --- /dev/null +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.map.transformer.model; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.model.TransformerSettings; + +import lombok.Getter; + +/** + * Transformer object configuration. + * It contains: + * 1) The lambda function to apply on a Map key. + */ +@Getter +public class MapTransformerSettings extends TransformerSettings { + /** + * Contains the lambda functions to be applied on a given map key. + * This features allows to apply transformation on the destination object value. + * e.g. The following instructions allows to negate the destination value of the identifier field. + * {@code + * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); + * } + */ + private final Map keyFieldsTransformers = new ConcurrentHashMap<>(); +} diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java new file mode 100644 index 000000000..7e970a4e3 --- /dev/null +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Pojo package. + */ + +package com.hotels.map.transformer.model; From df51015bb0ff76de0760194e96c32fd853d5d06f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 5 Sep 2019 18:00:21 +0200 Subject: [PATCH 0817/1786] - Moved all Transformer implementation common method in a common class. - Refactorized class to use generics --- .../transformer/AbstractBeanTransformer.java | 30 +---------------- .../transformer/AbstractTransformer.java | 33 ++++++++++++++++++- .../transformer/AbstractMapTransformer.java | 27 +-------------- 3 files changed, 34 insertions(+), 56 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java index bc1184cab..d1dd72568 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java @@ -20,12 +20,8 @@ import static com.hotels.transformer.validator.Validator.notNull; -import java.util.Map; - import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; import com.hotels.transformer.AbstractTransformer; -import com.hotels.transformer.model.FieldMapping; -import com.hotels.transformer.model.FieldTransformer; import com.hotels.transformer.model.TransformerSettings; import com.hotels.transformer.validator.Validator; import com.hotels.transformer.validator.ValidatorImpl; @@ -34,7 +30,7 @@ * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * Contains all method implementation that will be common to any {@link BeanTransformer} implementation. */ -abstract class AbstractBeanTransformer extends AbstractTransformer implements BeanTransformer { +abstract class AbstractBeanTransformer extends AbstractTransformer implements BeanTransformer { /** * The cache key prefix for the Transformer Functions. */ @@ -57,18 +53,6 @@ abstract class AbstractBeanTransformer extends AbstractTransformer fieldsNameMapping = settings.getFieldsNameMapping(); - for (FieldMapping mapping : fieldMapping) { - fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); - } - return this; - } - /** * {@inheritDoc} */ @@ -78,18 +62,6 @@ public final BeanTransformer setDefaultValueForMissingField(final boolean useDef return this; } - /** - * {@inheritDoc} - */ - @Override - public final BeanTransformer withFieldTransformer(final FieldTransformer... fieldTransformer) { - Map fieldsTransformers = settings.getFieldsTransformers(); - for (FieldTransformer transformer : fieldTransformer) { - fieldsTransformers.put(transformer.getDestFieldName(), transformer); - } - return this; - } - /** * {@inheritDoc} */ diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java index de5813c62..067c5246d 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -19,7 +19,11 @@ import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; import static com.hotels.transformer.validator.Validator.notNull; +import java.util.Map; + import com.hotels.transformer.cache.CacheManager; +import com.hotels.transformer.model.FieldMapping; +import com.hotels.transformer.model.FieldTransformer; import com.hotels.transformer.model.TransformerSettings; import com.hotels.transformer.utils.ClassUtils; import com.hotels.transformer.utils.ReflectionUtils; @@ -28,9 +32,10 @@ /** * Abstract class containing all method implementation that will be common to any {@link Transformer}. + * @param the {@link Transformer} implementation. * @param the {@link TransformerSettings} implementation. */ -public abstract class AbstractTransformer implements Transformer { +public abstract class AbstractTransformer implements Transformer { /** * Reflection utils instance {@link ReflectionUtils}. */ @@ -71,6 +76,32 @@ protected AbstractTransformer(final String transformerFunctionCachePrefix, final this.cacheManager = getCacheManager(cacheName); } + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public final T withFieldMapping(final FieldMapping... fieldMapping) { + final Map fieldsNameMapping = settings.getFieldsNameMapping(); + for (FieldMapping mapping : fieldMapping) { + fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); + } + return (T) this; + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public final T withFieldTransformer(final FieldTransformer... fieldTransformer) { + Map fieldsTransformers = settings.getFieldsTransformers(); + for (FieldTransformer transformer : fieldTransformer) { + fieldsTransformers.put(transformer.getDestFieldName(), transformer); + } + return (T) this; + } + /** * {@inheritDoc} */ diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index ea19f6013..6eae0cfa5 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -20,14 +20,13 @@ import com.hotels.map.transformer.model.MapTransformerSettings; import com.hotels.transformer.AbstractTransformer; -import com.hotels.transformer.model.FieldMapping; import com.hotels.transformer.model.FieldTransformer; /** * Utility methods for populating {@link java.util.Map} elements via reflection.. * Contains all method implementation that will be common to any {@link MapTransformer} implementation. */ -abstract class AbstractMapTransformer extends AbstractTransformer implements MapTransformer { +abstract class AbstractMapTransformer extends AbstractTransformer implements MapTransformer { /** * The cache key prefix for the Transformer Functions. */ @@ -40,30 +39,6 @@ abstract class AbstractMapTransformer extends AbstractTransformer fieldsNameMapping = settings.getFieldsNameMapping(); - for (FieldMapping mapping : fieldMapping) { - fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); - } - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public final MapTransformer withFieldTransformer(final FieldTransformer... fieldTransformer) { - Map fieldsTransformers = settings.getFieldsTransformers(); - for (FieldTransformer transformer : fieldTransformer) { - fieldsTransformers.put(transformer.getDestFieldName(), transformer); - } - return this; - } - /** * {@inheritDoc} */ From 8e6c186bbc92d8054c28ba6ffeb078ff90a89725 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2019 02:52:23 +0000 Subject: [PATCH 0818/1786] Bump spring-boot-starter-test from 2.1.7.RELEASE to 2.1.8.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.1.7.RELEASE to 2.1.8.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.1.7.RELEASE...v2.1.8.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3a8ab780c..f3ca5d1e5 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ 11 ${jdk.version} ${jdk.version} - 2.1.7.RELEASE + 2.1.8.RELEASE 1.18.8 3.9 0.11 From 4318b74cc0585b226ca510cbc6a6ece9f38d248c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 6 Sep 2019 16:48:26 +0200 Subject: [PATCH 0819/1786] Code style improvement --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- .../beans/transformer/BeanTransformer.java | 2 +- .../beans/populator/PopulatorFactoryTest.java | 2 +- .../ImmutableObjectTransformationTest.java | 3 ++- .../MixedObjectTransformationTest.java | 3 +-- .../MutableObjectTransformationTest.java | 2 ++ .../transformer/AbstractTransformer.java | 2 +- .../com/hotels/transformer/Transformer.java | 7 +++--- .../transformer/validator/ValidatorImpl.java | 2 +- .../ImmutableToFooNoConstructors.java | 2 +- .../transformer/utils/ClassUtilsTest.java | 7 +++--- .../utils/ReflectionUtilsTest.java | 3 +++ .../conversion/AbstractConversionTest.java | 23 +++++++++---------- .../map/transformer/MapTransformer.java | 2 +- 15 files changed, 34 insertions(+), 30 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 6a47df97c..4709287f9 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -90,7 +90,7 @@ All notable changes to this project will be documented in this file. ### [1.1.10] 2019.03.31 #### Added * Improved field value retrieval function. -* Added ling to Gitter channel for BULL. +* Added link to Gitter channel for BULL. * Integrated Gitter notification in order to keep up to date BULL community ### [1.1.9] 2019.03.23 diff --git a/CHANGELOG.md b/CHANGELOG.md index 891e373d3..1d52236f0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -107,7 +107,7 @@ All notable changes to this project will be documented in this file. ### [1.2.5] 2019.03.31 #### Added * Improved field value retrieval function. -* Added ling to Gitter channel for BULL. +* Added link to Gitter channel for BULL. * Integrated Gitter notification in order to keep up to date BULL community ### [1.2.4] 2019.03.23 diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index 60eee1040..383cddde3 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -22,7 +22,7 @@ * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * The implementations are provided by {@link TransformerImpl}. */ -public interface BeanTransformer extends Transformer { +public interface BeanTransformer extends Transformer { /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index 9e190d399..2b8e1c538 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -79,7 +79,7 @@ public Object[][] dataProvider() { * @param expectedResult the expected populator */ @Test(dataProvider = "dataProvider") - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "OptionalGetWithoutIsPresent"}) public void testGetPopulatorReturnsTheExpectedResult(final Class type, final Class expectedResult) { // GIVEN diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index da1dfd699..06f276051 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -261,7 +261,7 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); + final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); //THEN @@ -297,6 +297,7 @@ public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String te assertNotNull(actual.getName()); assertEquals(isNameFieldEmpty, actual.getName().isPresent()); sourceObject.getName().ifPresent(name -> assertEquals(name, actual.getName().get())); + assertTrue(sourceObject.getAge().isPresent()); assertEquals(sourceObject.getAge().get(), actual.getAge()); assertEquals(sourceObject.getClassType(), actual.getClassType()); assertEquals(sourceObject.getLocale(), actual.getLocale().getLanguage()); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 46afdf628..fdc4ebfe4 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -35,7 +35,6 @@ import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; import com.hotels.beans.sample.mixed.MixedToFooMissingField; import com.hotels.beans.sample.mixed.MixedToFooNotExistingFields; -import com.hotels.transformer.Transformer; import com.hotels.transformer.error.MissingFieldException; import com.hotels.transformer.model.FieldMapping; import com.hotels.transformer.model.FieldTransformer; @@ -82,7 +81,7 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final Transformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); + final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); //THEN diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index fd45bf6b7..77dab6ddf 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -21,6 +21,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; @@ -235,6 +236,7 @@ public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeCo } //THEN + assertNotNull(raisedException); assertEquals(MissingFieldException.class, raisedException.getCause().getClass()); underTest.setPrimitiveTypeConversionEnabled(false); } diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java index 067c5246d..bed4cab4b 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -35,7 +35,7 @@ * @param the {@link Transformer} implementation. * @param the {@link TransformerSettings} implementation. */ -public abstract class AbstractTransformer implements Transformer { +public abstract class AbstractTransformer implements Transformer { /** * Reflection utils instance {@link ReflectionUtils}. */ diff --git a/bull-common/src/main/java/com/hotels/transformer/Transformer.java b/bull-common/src/main/java/com/hotels/transformer/Transformer.java index dd0086d96..d93456364 100644 --- a/bull-common/src/main/java/com/hotels/transformer/Transformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/Transformer.java @@ -21,8 +21,9 @@ /** * Utility methods for all objects transformation. + * @param the {@link Transformer} implementation. */ -public interface Transformer { +public interface Transformer { /** * Copies all properties from an object to a new one. * @param sourceObj the source object @@ -49,7 +50,7 @@ public interface Transformer { * @param fieldMapping the field mapping * @return the {@link Transformer} instance */ - Transformer withFieldMapping(FieldMapping... fieldMapping); + N withFieldMapping(FieldMapping... fieldMapping); /** * Removes the field mapping for the given field. @@ -67,7 +68,7 @@ public interface Transformer { * @param fieldTransformer the fields transformer function * @return the {@link Transformer} instance */ - Transformer withFieldTransformer(FieldTransformer... fieldTransformer); + N withFieldTransformer(FieldTransformer... fieldTransformer); /** * Removes the field transformer for the given field. diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java index a569454e7..d7406700d 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java @@ -87,7 +87,7 @@ public final void validate(final K k) { /** * Creates a function that, given a constraint error, builds a violation message. - * @return the constaint violation message + * @return the constant violation message */ private Function, String> getConstraintViolationMessage() { return cv -> cv.getRootBeanClass().getName() diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java index 4515faab2..d0fb164c7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java @@ -23,5 +23,5 @@ * Immutable object without constructor. */ @NoArgsConstructor(access = AccessLevel.PRIVATE) -public class ImmutableToFooNoConstructors { +public final class ImmutableToFooNoConstructors { } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 7f4c65ec7..10a1e1f03 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -493,20 +493,19 @@ public void testAreParameterNamesAvailableWorksAsExpected(final String testCaseD @DataProvider private Object[][] dataAreParameterNamesAvailableTesting() { return new Object[][] { - {"Tests that the method returns false if the constructor parameter names are not available", createMockedConstructor(false), false}, + {"Tests that the method returns false if the constructor parameter names are not available", createMockedConstructor(), false}, {"Tests that the method returns false if the constructor parameter names are available", underTest.getAllArgsConstructor(MixedToFoo.class), true} }; } /** * Creates a mocked constructor for testing method {@code areParameterNamesAvailable}. - * @param isNamePresent the value it should return when invoking the {@code isNamePresent} method * @return a mocked {@link Constructor} instance */ - private Constructor createMockedConstructor(final boolean isNamePresent) { + private Constructor createMockedConstructor() { Parameter parameter = mock(Parameter.class); ReflectionTestUtils.setField(parameter, "name", "paramName"); - when(parameter.isNamePresent()).thenReturn(isNamePresent); + when(parameter.isNamePresent()).thenReturn(false); Constructor constructor = mock(Constructor.class); when(constructor.getDeclaringClass()).thenReturn(ImmutableToFoo.class); when(constructor.getParameters()).thenReturn(new Parameter[] {parameter}); diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index f2bfea00d..69a820ecd 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -438,6 +438,7 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong } // THEN + assertNotNull(actualException); assertEquals(IllegalArgumentException.class, actualException.getTargetException().getClass()); } @@ -611,6 +612,7 @@ public void testGetGetterMethodThrowsExceptionIfTheMethodDoesNotExists() throws } // THEN + assertNotNull(actualException); assertEquals(MissingFieldException.class, actualException.getTargetException().getClass()); } @@ -675,6 +677,7 @@ public void testInvokeMethodCorrectlyHandlesExceptions(final String testCaseDesc } // THEN + assertNotNull(actualException); assertEquals(expectedException, actualException.getClass()); } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java index bc2a85f5b..e9dfde9ca 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java @@ -20,18 +20,17 @@ * Abstract class containing all methods/fields common to all Conversion test classes. */ public abstract class AbstractConversionTest { - public static final Byte BYTE_VALUE = 10; - public static final Short SHORT_VALUE = 10; - public static final Integer INTEGER_VALUE = 10; - public static final Long LONG_VALUE = 10L; - public static final Float FLOAT_VALUE = 10f; - public static final Double DOUBLE_VALUE = 10d; - public static final char CHAR_VALUE = '1'; - public static final Boolean BOOLEAN_VALUE = Boolean.TRUE; - public static final String STRING_VALUE = "10"; - public static final byte[] ONE_BYTE_BYTE_ARRAY = new byte[] {1}; - public static final byte[] EIGHT_BYTE_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6, 7, 8}; - + protected static final Byte BYTE_VALUE = 10; + protected static final Short SHORT_VALUE = 10; + protected static final Integer INTEGER_VALUE = 10; + protected static final Long LONG_VALUE = 10L; + protected static final Float FLOAT_VALUE = 10f; + protected static final Double DOUBLE_VALUE = 10d; + protected static final char CHAR_VALUE = '1'; + protected static final Boolean BOOLEAN_VALUE = Boolean.TRUE; + protected static final String STRING_VALUE = "10"; + protected static final byte[] ONE_BYTE_BYTE_ARRAY = new byte[] {1}; + protected static final byte[] EIGHT_BYTE_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6, 7, 8}; protected static final Byte BYTE_VALUE_ZERO = 0; protected static final Short SHORT_VALUE_ZERO = 0; protected static final Integer INTEGER_VALUE_ZERO = 0; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index 1493656b6..09b3c10ba 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -25,7 +25,7 @@ * Utility methods for populating {@link java.util.Map} elements via reflection. * The implementations are provided by {@link MapTransformerImpl}. */ -public interface MapTransformer extends Transformer { +public interface MapTransformer extends Transformer { /** * Copies all properties from a map to a new one. * @param sourceMap the source map From 246a3fac774e3f8c5d6303a05111396bf21808d5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 6 Sep 2019 18:48:26 +0200 Subject: [PATCH 0820/1786] Moved transform method into the specific interfaces --- .../beans/transformer/BeanTransformer.java | 21 +++++++++++++++++++ .../ImmutableObjectTransformationTest.java | 3 +-- .../com/hotels/transformer/Transformer.java | 21 ------------------- .../transformer/AbstractMapTransformer.java | 1 - .../map/transformer/MapTransformerImpl.java | 16 -------------- 5 files changed, 22 insertions(+), 40 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index 383cddde3..218ecabb4 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -23,6 +23,27 @@ * The implementations are provided by {@link TransformerImpl}. */ public interface BeanTransformer extends Transformer { + /** + * Copies all properties from an object to a new one. + * @param sourceObj the source object + * @param targetClass the destination object class + * @param the Source object type + * @param the target object type + * @return a copy of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + K transform(T sourceObj, Class targetClass); + + /** + * Copies all properties from an object to a new one. + * @param sourceObj the source object + * @param targetObject the destination object + * @param the Source object type + * @param the target object type + * @throws IllegalArgumentException if any parameter is invalid + */ + void transform(T sourceObj, K targetObject); + /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 06f276051..a3f8f23fd 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -60,7 +60,6 @@ import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.transformer.Transformer; import com.hotels.transformer.annotation.ConstructorArg; import com.hotels.transformer.cache.CacheManager; import com.hotels.transformer.error.InvalidBeanException; @@ -286,7 +285,7 @@ public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String te //GIVEN //WHEN - final Transformer beanTransformer = underTest + final BeanTransformer beanTransformer = underTest .withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)) .withFieldMapping(new FieldMapping(PRICE_FIELD_NAME, NET_PRICE_FIELD_NAME)) .withFieldMapping(new FieldMapping(PRICE_FIELD_NAME, GROSS_PRICE_FIELD_NAME)) diff --git a/bull-common/src/main/java/com/hotels/transformer/Transformer.java b/bull-common/src/main/java/com/hotels/transformer/Transformer.java index d93456364..6f618245a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/Transformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/Transformer.java @@ -24,27 +24,6 @@ * @param the {@link Transformer} implementation. */ public interface Transformer { - /** - * Copies all properties from an object to a new one. - * @param sourceObj the source object - * @param targetClass the destination object class - * @param the Source object type - * @param the target object type - * @return a copy of the source object into the destination object - * @throws IllegalArgumentException if any parameter is invalid - */ - K transform(T sourceObj, Class targetClass); - - /** - * Copies all properties from an object to a new one. - * @param sourceObj the source object - * @param targetObject the destination object - * @param the Source object type - * @param the target object type - * @throws IllegalArgumentException if any parameter is invalid - */ - void transform(T sourceObj, K targetObject); - /** * Initializes the mapping between fields in the source object and the destination one. * @param fieldMapping the field mapping diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index 6eae0cfa5..8870960d2 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -50,5 +50,4 @@ public MapTransformer withKeyTransformer(final FieldTransformer... keyFieldTrans } return this; } - } diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index ac8afb884..096ce4b83 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -37,20 +37,4 @@ public Map transform(final Map sourceMap, final Class void transform(final Map sourceMap, final Map targetMap) { } - - /** - * {@inheritDoc} - */ - @Override - public K transform(final T sourceObj, final Class targetClass) { - return null; - } - - /** - * {@inheritDoc} - */ - @Override - public void transform(final T sourceObj, final K targetObject) { - - } } From 86d26d871616a35b76c20874fe0e1939f812ab75 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 6 Sep 2019 18:58:21 +0200 Subject: [PATCH 0821/1786] Updated maven wrapper to 3.6.2 --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 866cd7760..4b38d3904 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,4 +1,4 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.1/apache-maven-3.6.1-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip wrapper.url=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar # Path where the maven-wrapper.jar will be saved to. From 822c1c5dd0a2ceedc05b9df518a00ed31a0b0034 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 9 Sep 2019 06:58:47 +0200 Subject: [PATCH 0822/1786] [travis skip] Adding bean transformer to the map transformation module --- bull-map-transformer/pom.xml | 5 ++++ .../transformer/AbstractMapTransformer.java | 16 +++++++++++ .../map/transformer/MapTransformer.java | 28 +++++++++++++++++++ .../map/transformer/MapTransformerImpl.java | 4 +-- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index d21e5136c..581b6241e 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -20,6 +20,11 @@ bull-common ${project.version} + + com.hotels.beans + bull-bean-transformer + ${project.version} + com.hotels.beans diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index 8870960d2..dd69ab7bf 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -39,6 +39,22 @@ abstract class AbstractMapTransformer extends AbstractTransformer Map transform(final Map sourceMap, final Class> targetMapClass) { + return transform(sourceMap, targetMapClass, new BeanUtils()); + } + + /** + * {@inheritDoc} + */ + @Override + public void transform(final Map sourceMap, final Map targetMap) { + + } + /** * {@inheritDoc} */ diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index 09b3c10ba..dfa62fdfe 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -18,6 +18,7 @@ import java.util.Map; +import com.hotels.beans.transformer.BeanTransformer; import com.hotels.transformer.Transformer; import com.hotels.transformer.model.FieldTransformer; @@ -39,6 +40,20 @@ public interface MapTransformer extends Transformer { */ Map transform(Map sourceMap, Class> targetMapClass); + /** + * Copies all properties from a map to a new one. + * @param sourceMap the source map + * @param targetMapClass the target map class + * @param beanTransformer the bean transformer to use for the map elements transformation + * @param the key object type in the source map + * @param the elem object type in the source map + * @param the key object type in the target map + * @param the elem object type in the target map + * @return a copy of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + Map transform(Map sourceMap, Class> targetMapClass, BeanTransformer beanTransformer); + /** * Copies all properties from a map to a new one. * @param sourceMap the source object @@ -51,6 +66,19 @@ public interface MapTransformer extends Transformer { */ void transform(Map sourceMap, Map targetMap); + /** + * Copies all properties from a map to a new one. + * @param sourceMap the source object + * @param targetMap the destination object + * @param beanTransformer the bean transformer to use for the map elements transformation + * @param the key object type in the source map + * @param the elem object type in the source map + * @param the key object type in the target map + * @param the elem object type in the target map + * @throws IllegalArgumentException if any parameter is invalid + */ + void transform(Map sourceMap, Map targetMap, BeanTransformer beanTransformer); + /** * Initializes the transformer functions to apply on a Map key. The transformer function returns directly the field value. * @param keyFieldTransformer the fields transformer function diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index 096ce4b83..d38341400 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -26,7 +26,7 @@ public class MapTransformerImpl extends AbstractMapTransformer { * {@inheritDoc} */ @Override - public Map transform(final Map sourceMap, final Class> targetMapClass) { + public Map transform(final Map sourceMap, final Class> targetMapClass, final BeanTransformer beanTransformer) { return null; } @@ -34,7 +34,7 @@ public Map transform(final Map sourceMap, final Class void transform(final Map sourceMap, final Map targetMap) { + public void transform(final Map sourceMap, final Map targetMap, final BeanTransformer beanTransformer) { } } From f14118583a7a557a10b69cb5d99eb5eb92889ed9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 9 Sep 2019 18:02:38 +0200 Subject: [PATCH 0823/1786] [travis skip] draft map implementation --- .../beans/populator/ArrayPopulator.java | 11 +- .../beans/populator/CollectionPopulator.java | 10 ++ .../hotels/beans/populator/MapPopulator.java | 6 + .../beans/populator/OptionalPopulator.java | 8 + .../com/hotels/beans/populator/Populator.java | 8 + .../transformer/utils/ReflectionUtils.java | 152 +++++++++++++----- .../transformer/AbstractMapTransformer.java | 8 +- .../map/transformer/MapTransformer.java | 18 ++- .../map/transformer/MapTransformerImpl.java | 82 +++++++++- .../java/com/hotels/map/MapUtilsTest.java | 59 +++++++ .../java/com/hotels/map/package-info.java | 20 +++ .../map/transformer/MapTransformerTest.java | 114 +++++++++++++ .../hotels/map/transformer/package-info.java | 20 +++ 13 files changed, 460 insertions(+), 56 deletions(-) create mode 100644 bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java create mode 100644 bull-map-transformer/src/test/java/com/hotels/map/package-info.java create mode 100644 bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java create mode 100644 bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index afa9c0bd3..0134b5741 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -24,6 +24,7 @@ /** * Populator for primitive types array. + * TODO: parametrized guide: https://www.javacodegeeks.com/2013/12/advanced-java-generics-retreiving-generic-type-arguments.html */ class ArrayPopulator extends Populator implements ICollectionPopulator { @@ -40,7 +41,15 @@ class ArrayPopulator extends Populator implements ICollectionPopulator fieldClass, final Object fieldValue) { + return getPopulatedObject(fieldClass, fieldClass.getComponentType(), fieldValue, null); } /** diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index 896b68c50..a01759637 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -50,6 +50,16 @@ public Collection getPopulatedObject(final Field field, final Collection fiel return getPopulatedObject(field.getType(), reflectionUtils.getGenericFieldType(field), fieldValue, genericClass); } + /** + * {@inheritDoc} + */ + @Override + public Collection getPopulatedObject(final Class fieldClass, final Collection fieldValue) { + final Class genericClass = reflectionUtils.getArgumentTypeClass(fieldValue, true); +// return getPopulatedObject(fieldClass, reflectionUtils.getGenericFieldType(fieldClass.getGenericSuperclass()), fieldValue, genericClass); + return getPopulatedObject(fieldClass, fieldClass, fieldValue, genericClass); + } + /** * {@inheritDoc} */ diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java index 10fb1d250..7c0d6df7f 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -48,6 +48,12 @@ class MapPopulator extends Populator> { return getPopulatedObject(fieldValue, mapGenericType); } + @Override + public Map getPopulatedObject(final Class fieldClass, final Map fieldValue) { + MapType mapGenericType = reflectionUtils.getMapGenericType(fieldValue.getClass().getGenericSuperclass(), fieldClass); + return getPopulatedObject(fieldValue, mapGenericType); + } + /** * Populates the Map objects. * @param fieldValue the source Map. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index b33ac4717..e6618517d 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -53,4 +53,12 @@ public Object getPopulatedObject(final Field field, final Object fieldValue) { return res; } + /** + * {@inheritDoc} + */ + @Override + public Object getPopulatedObject(final Class fieldClass, final Object fieldValue) { + return null; // no implementation needed. + } + } diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java index 9791a8054..e63ca0ab3 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java @@ -63,6 +63,14 @@ public abstract class Populator { */ protected abstract O getPopulatedObject(Field field, O fieldValue); + /** + * Populates the target object with the values into the source object. + * @param fieldClass the field class + * @param fieldValue the source object from which extract the values + * @return a populated list of elements + */ + public abstract O getPopulatedObject(Class fieldClass, O fieldValue); + /** * Populates the target object with the values into the source object. * @param the target object type diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index 744e8ac03..2332537d3 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -421,18 +421,28 @@ public Method getSetterMethodForField(final Class fieldClass, final String fi public Class getGenericFieldType(final Field field) { final String cacheKey = "GenericFieldType-" + field.getDeclaringClass().getName() + '-' + field.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Class.class).orElseGet(() -> { - Class res = null; - if (ParameterizedType.class.isAssignableFrom(field.getGenericType().getClass())) { - final Type[] fieldArgTypes = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); - if (fieldArgTypes.length != 0) { - res = (Class) fieldArgTypes[0]; - } - } + Class res = getGenericFieldType(field.getGenericType()); CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); } + /** + * Gets the generic infer type of an object. + * @param objectType the element object type containing the generic + * @return the generic type class + */ + public Class getGenericFieldType(final Type objectType) { + Class res = null; + if (ParameterizedType.class.isAssignableFrom(objectType.getClass())) { + final Type[] fieldArgTypes = ((ParameterizedType) objectType).getActualTypeArguments(); + if (fieldArgTypes.length != 0) { + res = (Class) fieldArgTypes[0]; + } + } + return res; + } + /** * Gets the generic infer type of a map object. * @param fieldType the field containing the generic @@ -444,54 +454,99 @@ public MapType getMapGenericType(final Type fieldType, final String declaringCla final Class fieldClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); final String cacheKey = "MapGenericFieldType-" + fieldClass.getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, MapType.class).orElseGet(() -> { - if (!Map.class.isAssignableFrom(fieldClass)) { + MapType mapType; + try { + mapType = getMapGenericType(fieldType, fieldClass); + CACHE_MANAGER.cacheObject(cacheKey, mapType); + } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Type for object: " + fieldName + " is invalid. " - + "It cannot be assigned from: " + Map.class.getName() + "."); + + "It cannot be assigned from: " + Map.class.getName() + "."); } - final ParameterizedType genericType = (ParameterizedType) fieldType; - final MapElemType keyType = getMapElemType(genericType.getActualTypeArguments()[0], declaringClass, fieldName); - final MapElemType elemType = getMapElemType(genericType.getActualTypeArguments()[1], declaringClass, fieldName); - final MapType mapType = new MapType(keyType, elemType); - CACHE_MANAGER.cacheObject(cacheKey, mapType); return mapType; }); } + /** + * Gets the generic infer type of a map object. + * @param fieldType the field containing the generic + * @param fieldClass the field class + * @return the generic type class + */ + public MapType getMapGenericType(final Type fieldType, final Class fieldClass) { + if (!Map.class.isAssignableFrom(fieldClass)) { + throw new IllegalArgumentException("Type: " + fieldClass.getName() + " cannot be assigned from: " + Map.class.getName() + "."); + } + final ParameterizedType genericType = (ParameterizedType) fieldType; + final MapElemType keyType = getMapElemType(genericType.getActualTypeArguments()[0]); + final MapElemType elemType = getMapElemType(genericType.getActualTypeArguments()[1]); + return new MapType(keyType, elemType); + } + +// /** +// * Retrieves the generic class of the objects contained in the map. +// * It could be {@link ItemType} in case the object is primitive or is a collection +// * It could be {@link MapType} in case the object is a {@link Map} +// * @param fieldType the field containing the generic +// * @param declaringClass the class containing the field +// * @param fieldName the field name +// * @return the generic class of the objects contained in the map. +// */ +// private MapElemType getMapElemType(final Type fieldType, final String declaringClass, final String fieldName) { +// final String cacheKey = "MapElemType-" + declaringClass + "-" + fieldType.getTypeName() + '-' + fieldName; +// return CACHE_MANAGER.getFromCache(cacheKey, MapElemType.class).orElseGet(() -> { +// final Class argumentTypeClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); +// final MapElemType res; +// if (Map.class.isAssignableFrom(argumentTypeClass)) { +// res = getMapGenericType(fieldType, declaringClass, fieldName); +// } else { +// res = buildItemType(fieldType, declaringClass, fieldName); +// } +// CACHE_MANAGER.cacheObject(cacheKey, res); +// return res; +// }); +// } + /** * Retrieves the generic class of the objects contained in the map. * It could be {@link ItemType} in case the object is primitive or is a collection * It could be {@link MapType} in case the object is a {@link Map} * @param fieldType the field containing the generic - * @param declaringClass the class containing the field - * @param fieldName the field name * @return the generic class of the objects contained in the map. */ - private MapElemType getMapElemType(final Type fieldType, final String declaringClass, final String fieldName) { - final String cacheKey = "MapElemType-" + declaringClass + "-" + fieldType.getTypeName() + '-' + fieldName; - return CACHE_MANAGER.getFromCache(cacheKey, MapElemType.class).orElseGet(() -> { - final Class argumentTypeClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); - final MapElemType res; - if (Map.class.isAssignableFrom(argumentTypeClass)) { - res = getMapGenericType(fieldType, declaringClass, fieldName); - } else { - res = buildItemType(fieldType, declaringClass, fieldName); - } - CACHE_MANAGER.cacheObject(cacheKey, res); - return res; - }); + private MapElemType getMapElemType(final Type fieldType) { + final Class argumentTypeClass = getArgumentTypeClass(fieldType, false); + final MapElemType res; + if (Map.class.isAssignableFrom(argumentTypeClass)) { + res = getMapGenericType(fieldType, argumentTypeClass); + } else { + res = buildItemType(fieldType); + } + return res; } +// /** +// * Builds the {@link ItemType} object from a given object. +// * @param argument the object from which the class has to be retrieved +// * @param declaringClass the class containing the field of which the argument belongs to +// * @param fieldName the field name of which the argument belongs to +// * @return the {@link ItemType} object +// */ +// private ItemType buildItemType(final Object argument, final String declaringClass, final String fieldName) { +// return ItemType.builder() +// .objectClass(getArgumentTypeClass(argument, declaringClass, fieldName, false)) +// .genericClass(getArgumentTypeClass(argument, declaringClass, fieldName, true)) +// .build(); +// } + /** * Builds the {@link ItemType} object from a given object. * @param argument the object from which the class has to be retrieved - * @param declaringClass the class containing the field of which the argument belongs to - * @param fieldName the field name of which the argument belongs to * @return the {@link ItemType} object */ - private ItemType buildItemType(final Object argument, final String declaringClass, final String fieldName) { + private ItemType buildItemType(final Object argument) { return ItemType.builder() - .objectClass(getArgumentTypeClass(argument, declaringClass, fieldName, false)) - .genericClass(getArgumentTypeClass(argument, declaringClass, fieldName, true)) + .objectClass(getArgumentTypeClass(argument, false)) + .genericClass(getArgumentTypeClass(argument, true)) .build(); } @@ -511,19 +566,32 @@ public Class getArgumentTypeClass(final Object argument, final String declari return CACHE_MANAGER.getFromCache(cacheKey, Class.class) .map(atc -> atc == EmptyValue.class ? null : atc) .orElseGet(() -> { - Class res = null; - if (argumentIsTypeClass) { - res = getNestedGenericClass ? null : (Class) argument; - } else if (ParameterizedType.class.isAssignableFrom(argument.getClass())) { - res = getNestedGenericClass - ? getArgumentTypeClass(((ParameterizedType) argument).getActualTypeArguments()[0], declaringClass, fieldName, false) - : (Class) ((ParameterizedType) argument).getRawType(); - } + Class res = getArgumentTypeClass(argument, getNestedGenericClass); CACHE_MANAGER.cacheObject(cacheKey, res, EmptyValue.class); return res; }); } + /** + * Gets the class of a given object. + * @param argument the object from which the class has to be retrieved + * @param getNestedGenericClass if true it retrieves the class of the object generic (if any). i.e. {@code argument = List;} + * returns {@code String}, if false returns {@code List} + * @return the given argument class type + */ + public Class getArgumentTypeClass(final Object argument, final boolean getNestedGenericClass) { + final boolean argumentIsTypeClass = argument instanceof Class; + Class res = null; + if (argumentIsTypeClass) { + res = getNestedGenericClass ? null : (Class) argument; + } else if (ParameterizedType.class.isAssignableFrom(argument.getClass())) { + res = getNestedGenericClass + ? getArgumentTypeClass(((ParameterizedType) argument).getActualTypeArguments()[0], false) + : (Class) ((ParameterizedType) argument).getRawType(); + } + return res; + } + /** * Gets the type of an array. * @param arrayField the array diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index dd69ab7bf..8aa5758e9 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -18,6 +18,7 @@ import java.util.Map; +import com.hotels.beans.BeanUtils; import com.hotels.map.transformer.model.MapTransformerSettings; import com.hotels.transformer.AbstractTransformer; import com.hotels.transformer.model.FieldTransformer; @@ -43,8 +44,9 @@ abstract class AbstractMapTransformer extends AbstractTransformer Map transform(final Map sourceMap, final Class> targetMapClass) { - return transform(sourceMap, targetMapClass, new BeanUtils()); +// public Map transform(final Map sourceMap, final Class> targetMapClass) { + public Map transform(final Map sourceMap) { + return transform(sourceMap, new BeanUtils().getTransformer()); } /** @@ -52,7 +54,7 @@ public Map transform(final Map sourceMap, final Class void transform(final Map sourceMap, final Map targetMap) { - + transform(sourceMap, targetMap, new BeanUtils().getTransformer()); } /** diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index dfa62fdfe..fa83092c1 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -30,29 +30,31 @@ public interface MapTransformer extends Transformer { /** * Copies all properties from a map to a new one. * @param sourceMap the source map - * @param targetMapClass the target map class +// * @param targetMapClass the target map class * @param the key object type in the source map * @param the elem object type in the source map - * @param the key object type in the target map - * @param the elem object type in the target map +// * @param the key object type in the target map +// * @param the elem object type in the target map * @return a copy of the source object into the destination object * @throws IllegalArgumentException if any parameter is invalid */ - Map transform(Map sourceMap, Class> targetMapClass); +// Map transform(Map sourceMap, Class> targetMapClass); + Map transform(Map sourceMap); /** * Copies all properties from a map to a new one. * @param sourceMap the source map - * @param targetMapClass the target map class +// * @param targetMapClass the target map class * @param beanTransformer the bean transformer to use for the map elements transformation * @param the key object type in the source map * @param the elem object type in the source map - * @param the key object type in the target map - * @param the elem object type in the target map +// * @param the key object type in the target map +// * @param the elem object type in the target map * @return a copy of the source object into the destination object * @throws IllegalArgumentException if any parameter is invalid */ - Map transform(Map sourceMap, Class> targetMapClass, BeanTransformer beanTransformer); +// Map transform(Map sourceMap, Class> targetMapClass, BeanTransformer beanTransformer); + Map transform(Map sourceMap, BeanTransformer beanTransformer); /** * Copies all properties from a map to a new one. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index d38341400..477e70dc7 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -16,18 +16,56 @@ package com.hotels.map.transformer; +import static java.util.Objects.nonNull; +import static java.util.stream.Collectors.toMap; + +import static com.hotels.beans.populator.PopulatorFactory.getPopulator; + +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import com.hotels.beans.populator.Populator; +import com.hotels.beans.populator.PopulatorFactory; +import com.hotels.beans.transformer.BeanTransformer; +import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.utils.ReflectionUtils; /** * Utility methods for populating {@link java.util.Map} elements via reflection. */ public class MapTransformerImpl extends AbstractMapTransformer { + /** + * {@inheritDoc} + */ +// @Override +// public Map transform(final Map sourceMap, final BeanTransformer beanTransformer) { +// Set> entries = sourceMap.entrySet(); +// Map collect = sourceMap.entrySet() +// .stream() +// .collect( +// toMap( +// e -> { +// T key = e.getKey(); +// return getFieldValue(key, beanTransformer, settings.getKeyFieldsTransformers().get(key)); +// }, +// e -> getFieldValue()e.getValue())); +// return null; +// } + /** * {@inheritDoc} */ @Override - public Map transform(final Map sourceMap, final Class> targetMapClass, final BeanTransformer beanTransformer) { - return null; + public Map transform(final Map sourceMap, final BeanTransformer beanTransformer) { + return (Map) sourceMap.entrySet().stream() + .collect( + toMap( + e -> getFieldValue(e.getKey(), beanTransformer, settings.getKeyFieldsTransformers().get(e.getKey())), + e -> getFieldValue(e.getValue(), beanTransformer, settings.getFieldsTransformers().get(e.getValue())) + )); } /** @@ -37,4 +75,44 @@ public Map transform(final Map sourceMap, final Class void transform(final Map sourceMap, final Map targetMap, final BeanTransformer beanTransformer) { } + + private Object getFieldValue(final Object value, final BeanTransformer beanTransformer, final FieldTransformer fieldTransformer) { + Object newValue; + Class fieldType = value.getClass(); + if (classUtils.isPrimitiveOrSpecialType(fieldType)) { + newValue = value; + } else { +// newValue = null; +// Optional populator1 = getPopulator(fieldType, fieldType, beanTransformer); +// Object populatedObject = populator1.get().getPopulatedObject(fieldType, value); +// System.out.println("populatedObject = " + populatedObject); + newValue = getPopulator(fieldType, fieldType, beanTransformer) + .map(populator -> populator.getPopulatedObject(fieldType, value)) + .orElseGet(() -> + // recursively inject object + beanTransformer.transform(value, fieldType) + ); + } + if (nonNull(fieldTransformer)) { + newValue = fieldTransformer.getTransformedObject(newValue); + } + return newValue; + } + +// private Object getFieldValue(final Object value, final BeanTransformer beanTransformer, final FieldTransformer fieldTransformer) { +// Object newValue; +// Class objectClass = value.getClass(); +// Optional populator = PopulatorFactory.getPopulator(objectClass, objectClass, beanTransformer); +// if (Map.class.isAssignableFrom(objectClass)) { +// newValue = this.transform((Map) value, beanTransformer); +// } else if (classUtils.isPrimitiveOrSpecialType(objectClass)) { +// newValue = value; +// } else { +// newValue = beanTransformer.transform(value, objectClass); +// } +// if (nonNull(fieldTransformer)) { +// newValue = fieldTransformer.getTransformedObject(newValue); +// } +// return newValue; +// } } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java new file mode 100644 index 000000000..009e85927 --- /dev/null +++ b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.map; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.MockitoAnnotations.initMocks; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.hotels.map.transformer.MapTransformer; + +/** + * Unit test for {@link MapUtils}. + */ +public class MapUtilsTest { + /** + * The class to be tested. + */ + @InjectMocks + private MapUtils underTest; + + /** + * Initialized mocks. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + } + + /** + * Test that a Transformer is returned. + */ + @Test + public void testGetTransformerWorksProperly() { + //GIVEN + + //WHEN + final MapTransformer transformer = underTest.getTransformer(); + + //THEN + assertNotNull(transformer); + } +} diff --git a/bull-map-transformer/src/test/java/com/hotels/map/package-info.java b/bull-map-transformer/src/test/java/com/hotels/map/package-info.java new file mode 100644 index 000000000..7533358d7 --- /dev/null +++ b/bull-map-transformer/src/test/java/com/hotels/map/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Test package. + */ + +package com.hotels.map; \ No newline at end of file diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java new file mode 100644 index 000000000..11d755b2a --- /dev/null +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -0,0 +1,114 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.map.transformer; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.math.BigInteger; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.mockito.InjectMocks; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import com.hotels.beans.sample.FromFooSimple; + +/** + * Unit test for {@link MapTransformer}. + */ +public class MapTransformerTest { + private static final Map SAMPLE_MAP = new HashMap<>(); + private static final Map> COMPLEX_MAP = new HashMap<>(); + private static final Map> VERY_COMPLEX_MAP = new HashMap<>(); + private static final Map> EXTREME_COMPLEX_MAP = new HashMap<>(); + private static final String ITEM_1 = "donald"; + private static final String ITEM_2 = "duck"; + private static final BigInteger ID = new BigInteger("1234"); + private static final String NAME = "Goofy"; + + /** + * The class to be tested. + */ + @InjectMocks + private MapTransformerImpl underTest; + + /** + * Initialized mocks. + */ + @BeforeClass + public void beforeClass() { + initMocks(this); + initObjects(); + } + + /** + * Test that the given map is correctly transformed. + * @param testCaseDescription the test case description + * @param sourceMap the map to transform + * @param the key type + * @param the element type + */ + @Test(dataProvider = "dataMapTransformerObject") + public void testTransformWorksProperly(final String testCaseDescription, final Map sourceMap) { + //GIVEN + + //WHEN + Map actual = underTest.transform(sourceMap); + + //THEN + assertNotNull(actual); + } + + /** + * Creates the parameters to be used for testing the map transformations. + * @return parameters to be used for testing the map transformation. + */ + @DataProvider + private Object[][] dataMapTransformerObject() { + return new Object[][] { +// {"Test that a simple Map is correctly transformed", SAMPLE_MAP}, + {"Test that a Map containing a list is correctly transformed", COMPLEX_MAP}, +// {"Test that a Map containing a Map is correctly transformed", VERY_COMPLEX_MAP}, +// {"Test that a Map containing a Map that has an object as key, is correctly transformed", EXTREME_COMPLEX_MAP} + }; + } + + /** + * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. + */ + private void initObjects() { + SAMPLE_MAP.put(ITEM_1, ITEM_2); + COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); + VERY_COMPLEX_MAP.put(ITEM_1, SAMPLE_MAP); + EXTREME_COMPLEX_MAP.put(createFromFooSimple(), SAMPLE_MAP); + } + + /** + * Creates a {@link FromFooSimple} instance. + * @return the {@link FromFooSimple} instance. + */ + private FromFooSimple createFromFooSimple() { + return new FromFooSimple(NAME, ID, Boolean.TRUE); + } +} diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java new file mode 100644 index 000000000..c9df4dbae --- /dev/null +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Map transformer package. + */ + +package com.hotels.map.transformer; From d007bf248516699fa6feaef72a91970243cf649b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 10 Sep 2019 18:31:49 +0200 Subject: [PATCH 0824/1786] [travis skip] added generics for FieldTransformer and FieldMapping --- .../beans/populator/ArrayPopulator.java | 1 - .../transformer/AbstractBeanTransformer.java | 4 +- .../transformer/AbstractTransformer.java | 11 +- .../transformer/model/FieldMapping.java | 6 +- .../model/TransformerSettings.java | 6 +- .../transformer/AbstractMapTransformer.java | 16 ++- .../map/transformer/MapTransformer.java | 45 ++++++-- .../map/transformer/MapTransformerImpl.java | 108 +++++++++--------- .../model/MapTransformerSettings.java | 4 +- .../map/transformer/MapTransformerTest.java | 5 +- pom.xml | 11 +- 11 files changed, 117 insertions(+), 100 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index 0134b5741..de19db398 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -24,7 +24,6 @@ /** * Populator for primitive types array. - * TODO: parametrized guide: https://www.javacodegeeks.com/2013/12/advanced-java-generics-retreiving-generic-type-arguments.html */ class ArrayPopulator extends Populator implements ICollectionPopulator { diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java index d1dd72568..a4e079fbc 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java @@ -30,7 +30,7 @@ * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. * Contains all method implementation that will be common to any {@link BeanTransformer} implementation. */ -abstract class AbstractBeanTransformer extends AbstractTransformer implements BeanTransformer { +abstract class AbstractBeanTransformer extends AbstractTransformer> implements BeanTransformer { /** * The cache key prefix for the Transformer Functions. */ @@ -50,7 +50,7 @@ abstract class AbstractBeanTransformer extends AbstractTransformer()); } /** diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java index bed4cab4b..7e05093bd 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -34,8 +34,9 @@ * Abstract class containing all method implementation that will be common to any {@link Transformer}. * @param the {@link Transformer} implementation. * @param the {@link TransformerSettings} implementation. + * @param

      the {@link FieldMapping} and {@link FieldTransformer} key class type. */ -public abstract class AbstractTransformer implements Transformer { +public abstract class AbstractTransformer> implements Transformer { /** * Reflection utils instance {@link ReflectionUtils}. */ @@ -82,9 +83,9 @@ protected AbstractTransformer(final String transformerFunctionCachePrefix, final @Override @SuppressWarnings("unchecked") public final T withFieldMapping(final FieldMapping... fieldMapping) { - final Map fieldsNameMapping = settings.getFieldsNameMapping(); + final Map fieldsNameMapping = settings.getFieldsNameMapping(); for (FieldMapping mapping : fieldMapping) { - fieldsNameMapping.put(mapping.getDestFieldName(), mapping.getSourceFieldName()); + fieldsNameMapping.put((P) mapping.getDestFieldName(), (P) mapping.getSourceFieldName()); } return (T) this; } @@ -95,9 +96,9 @@ public final T withFieldMapping(final FieldMapping... fieldMapping) { @Override @SuppressWarnings("unchecked") public final T withFieldTransformer(final FieldTransformer... fieldTransformer) { - Map fieldsTransformers = settings.getFieldsTransformers(); + Map fieldsTransformers = settings.getFieldsTransformers(); for (FieldTransformer transformer : fieldTransformer) { - fieldsTransformers.put(transformer.getDestFieldName(), transformer); + fieldsTransformers.put((P) transformer.getDestFieldName(), transformer); } return (T) this; } diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java index a201eb486..db72cd24e 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java @@ -26,14 +26,14 @@ @AllArgsConstructor @Getter @ToString -public class FieldMapping { +public class FieldMapping { /** * The field name in the source object. */ - private final String sourceFieldName; + private final T sourceFieldName; /** * The field name in the destination object. */ - private final String destFieldName; + private final K destFieldName; } diff --git a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java index 78cc5f30d..d45de9b7e 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java @@ -32,11 +32,11 @@ * 3) Other configurations. */ @Getter -public class TransformerSettings { +public class TransformerSettings { /** * Contains the mapping between fields's name in the source object and the destination one. */ - private final Map fieldsNameMapping = new ConcurrentHashMap<>(); + private final Map fieldsNameMapping = new ConcurrentHashMap<>(); /** * Contains the lambda functions to be applied on a given fields. @@ -46,7 +46,7 @@ public class TransformerSettings { * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); * } */ - private final Map fieldsTransformers = new ConcurrentHashMap<>(); + private final Map fieldsTransformers = new ConcurrentHashMap<>(); /** * Contains the list of fields that don't need to be transformed. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index 8aa5758e9..73bd5ee33 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -1,12 +1,9 @@ /** * Copyright (C) 2019 Expedia, Inc. - * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,7 +24,7 @@ * Utility methods for populating {@link java.util.Map} elements via reflection.. * Contains all method implementation that will be common to any {@link MapTransformer} implementation. */ -abstract class AbstractMapTransformer extends AbstractTransformer implements MapTransformer { +abstract class AbstractMapTransformer extends AbstractTransformer implements MapTransformer { /** * The cache key prefix for the Transformer Functions. */ @@ -44,7 +41,6 @@ abstract class AbstractMapTransformer extends AbstractTransformer Map transform(final Map sourceMap, final Class> targetMapClass) { public Map transform(final Map sourceMap) { return transform(sourceMap, new BeanUtils().getTransformer()); } @@ -57,12 +53,20 @@ public void transform(final Map sourceMap, final Map ta transform(sourceMap, targetMap, new BeanUtils().getTransformer()); } + /** + * {@inheritDoc} + */ + @Override + public Map transform(final Map sourceMap, final Class targetKeyClass, final Class targetElemClass) { + return transform(sourceMap, targetKeyClass, targetElemClass, new BeanUtils().getTransformer()); + } + /** * {@inheritDoc} */ @Override public MapTransformer withKeyTransformer(final FieldTransformer... keyFieldTransformer) { - final Map keyFieldsTransformers = settings.getKeyFieldsTransformers(); + final Map keyFieldsTransformers = settings.getKeyFieldsTransformers(); for (FieldTransformer transformer : keyFieldTransformer) { keyFieldsTransformers.put(transformer.getDestFieldName(), transformer); } diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index fa83092c1..3e48ed370 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -28,36 +28,57 @@ */ public interface MapTransformer extends Transformer { /** - * Copies all properties from a map to a new one. + * Copies all properties from a map to a new one applying the transformation function and mappings defined. * @param sourceMap the source map -// * @param targetMapClass the target map class * @param the key object type in the source map * @param the elem object type in the source map -// * @param the key object type in the target map -// * @param the elem object type in the target map * @return a copy of the source object into the destination object * @throws IllegalArgumentException if any parameter is invalid */ -// Map transform(Map sourceMap, Class> targetMapClass); Map transform(Map sourceMap); /** - * Copies all properties from a map to a new one. + * Copies all properties from a map to a new one applying the transformation function and mappings defined. * @param sourceMap the source map -// * @param targetMapClass the target map class * @param beanTransformer the bean transformer to use for the map elements transformation * @param the key object type in the source map * @param the elem object type in the source map -// * @param the key object type in the target map -// * @param the elem object type in the target map * @return a copy of the source object into the destination object * @throws IllegalArgumentException if any parameter is invalid */ -// Map transform(Map sourceMap, Class> targetMapClass, BeanTransformer beanTransformer); Map transform(Map sourceMap, BeanTransformer beanTransformer); /** - * Copies all properties from a map to a new one. + * Transforms the given Map into a new one. All the Map key, element are transformed into the given class types + * @param sourceMap the source map + * @param targetKeyClass the Map key class type in the target Map + * @param targetElemClass the Map element class type in the target Map + * @param the key object type in the source map + * @param the elem object type in the source map + * @param the key object type in the target map + * @param the elem object type in the target map + * @return a copy of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + Map transform(Map sourceMap, Class targetKeyClass, Class targetElemClass); + + /** + * Transforms the given Map into a new one. All the Map key, element are transformed into the given class types + * @param sourceMap the source map + * @param targetKeyClass the Map key class type in the target Map + * @param targetElemClass the Map element class type in the target Map + * @param beanTransformer the bean transformer to use for the map elements transformation + * @param the key object type in the source map + * @param the elem object type in the source map + * @param the key object type in the target map + * @param the elem object type in the target map + * @return a copy of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + Map transform(Map sourceMap, Class targetKeyClass, Class targetElemClass, BeanTransformer beanTransformer); + + /** + * Copies all properties from a map to the given one. * @param sourceMap the source object * @param targetMap the destination object * @param the key object type in the source map @@ -69,7 +90,7 @@ public interface MapTransformer extends Transformer { void transform(Map sourceMap, Map targetMap); /** - * Copies all properties from a map to a new one. + * Copies all properties from a map to the given one. * @param sourceMap the source object * @param targetMap the destination object * @param beanTransformer the bean transformer to use for the map elements transformation diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index 477e70dc7..a846304ec 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -1,12 +1,9 @@ /** * Copyright (C) 2019 Expedia, Inc. - * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,17 +18,10 @@ import static com.hotels.beans.populator.PopulatorFactory.getPopulator; -import java.util.ArrayList; -import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import com.hotels.beans.populator.Populator; -import com.hotels.beans.populator.PopulatorFactory; import com.hotels.beans.transformer.BeanTransformer; import com.hotels.transformer.model.FieldTransformer; -import com.hotels.transformer.utils.ReflectionUtils; /** * Utility methods for populating {@link java.util.Map} elements via reflection. @@ -40,32 +30,57 @@ public class MapTransformerImpl extends AbstractMapTransformer { /** * {@inheritDoc} */ -// @Override -// public Map transform(final Map sourceMap, final BeanTransformer beanTransformer) { -// Set> entries = sourceMap.entrySet(); -// Map collect = sourceMap.entrySet() -// .stream() -// .collect( -// toMap( -// e -> { -// T key = e.getKey(); -// return getFieldValue(key, beanTransformer, settings.getKeyFieldsTransformers().get(key)); -// }, -// e -> getFieldValue()e.getValue())); -// return null; -// } + @Override + @SuppressWarnings("unchecked") + public Map transform(final Map sourceMap, final BeanTransformer beanTransformer) { + Map keyFieldsTransformers = settings.getKeyFieldsTransformers(); + Map res; + if (settings.getFieldsNameMapping().isEmpty() && keyFieldsTransformers.isEmpty()) { + res = Map.copyOf(sourceMap); + } else { + res = (Map) sourceMap.entrySet().stream() + .collect(toMap( + e -> getTransformedObject(keyFieldsTransformers.get(e.getKey()), e.getKey()), +// e -> getFieldValue(e.getKey(), beanTransformer, keyFieldsTransformers.get(e.getKey())) + e -> getTransformedObject(settings.getFieldsTransformers().get(e.getKey()), getMapValue(e, sourceMap)) +// e -> getFieldValue(getMapValue(e, sourceMap), beanTransformer, settings.getFieldsTransformers().get(e.getKey())) + )); + } + return res; + } + + /** + * Checks if a mapping has been defined between one key and the other. + * In case a mapping exists, it returns the Map value for the new key. + * @param entry the Map entry from which extract the key and the value. + * @param sourceMap the Map from which the data has to be retrieved. + * @param the key type + * @param the class type + * @return the value for the new key + */ + @SuppressWarnings("unchecked") + private K getMapValue(final Map.Entry entry, final Map sourceMap) { + T newKey = (T) settings.getFieldsNameMapping().get(entry.getKey()); + return sourceMap.getOrDefault(newKey, entry.getValue()); + } + + /** + * Clones a Map. + * @param map the map to clone + * @param the key type + * @param the class type + * @return a clone of the given Map. + */ + private Map cloneMap(final Map map) { + return map.entrySet().stream().collect(toMap(Map.Entry::getKey, Map.Entry::getValue)); + } /** * {@inheritDoc} */ @Override - public Map transform(final Map sourceMap, final BeanTransformer beanTransformer) { - return (Map) sourceMap.entrySet().stream() - .collect( - toMap( - e -> getFieldValue(e.getKey(), beanTransformer, settings.getKeyFieldsTransformers().get(e.getKey())), - e -> getFieldValue(e.getValue(), beanTransformer, settings.getFieldsTransformers().get(e.getValue())) - )); + public Map transform(final Map sourceMap, final Class targetKeyClass, final Class targetElemClass, final BeanTransformer beanTransformer) { + return null; } /** @@ -76,16 +91,12 @@ public void transform(final Map sourceMap, final Map ta } - private Object getFieldValue(final Object value, final BeanTransformer beanTransformer, final FieldTransformer fieldTransformer) { + private Object getFieldValue(final Object value, final BeanTransformer beanTransformer, final FieldTransformer fieldTransformer) { Object newValue; Class fieldType = value.getClass(); if (classUtils.isPrimitiveOrSpecialType(fieldType)) { newValue = value; } else { -// newValue = null; -// Optional populator1 = getPopulator(fieldType, fieldType, beanTransformer); -// Object populatedObject = populator1.get().getPopulatedObject(fieldType, value); -// System.out.println("populatedObject = " + populatedObject); newValue = getPopulator(fieldType, fieldType, beanTransformer) .map(populator -> populator.getPopulatedObject(fieldType, value)) .orElseGet(() -> @@ -93,26 +104,15 @@ private Object getFieldValue(final Object value, final BeanTransformer beanTrans beanTransformer.transform(value, fieldType) ); } + newValue = getTransformedObject(fieldTransformer, newValue); + return newValue; + } + + private Object getTransformedObject(final FieldTransformer fieldTransformer, final Object value) { + Object newValue = value; if (nonNull(fieldTransformer)) { - newValue = fieldTransformer.getTransformedObject(newValue); + newValue = fieldTransformer.getTransformedObject(value); } return newValue; } - -// private Object getFieldValue(final Object value, final BeanTransformer beanTransformer, final FieldTransformer fieldTransformer) { -// Object newValue; -// Class objectClass = value.getClass(); -// Optional populator = PopulatorFactory.getPopulator(objectClass, objectClass, beanTransformer); -// if (Map.class.isAssignableFrom(objectClass)) { -// newValue = this.transform((Map) value, beanTransformer); -// } else if (classUtils.isPrimitiveOrSpecialType(objectClass)) { -// newValue = value; -// } else { -// newValue = beanTransformer.transform(value, objectClass); -// } -// if (nonNull(fieldTransformer)) { -// newValue = fieldTransformer.getTransformedObject(newValue); -// } -// return newValue; -// } } diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java index d70e1849e..61c769159 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java @@ -30,7 +30,7 @@ * 1) The lambda function to apply on a Map key. */ @Getter -public class MapTransformerSettings extends TransformerSettings { +public class MapTransformerSettings extends TransformerSettings { /** * Contains the lambda functions to be applied on a given map key. * This features allows to apply transformation on the destination object value. @@ -39,5 +39,5 @@ public class MapTransformerSettings extends TransformerSettings { * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); * } */ - private final Map keyFieldsTransformers = new ConcurrentHashMap<>(); + private final Map keyFieldsTransformers = new ConcurrentHashMap<>(); } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 11d755b2a..7b5929c2c 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -16,7 +16,6 @@ package com.hotels.map.transformer; -import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.junit.Assert.assertNotNull; @@ -87,8 +86,8 @@ public void testTransformWorksProperly(final String testCaseDescription, @DataProvider private Object[][] dataMapTransformerObject() { return new Object[][] { -// {"Test that a simple Map is correctly transformed", SAMPLE_MAP}, - {"Test that a Map containing a list is correctly transformed", COMPLEX_MAP}, + {"Test that a simple Map is correctly transformed", SAMPLE_MAP}, +// {"Test that a Map containing a list is correctly transformed", COMPLEX_MAP}, // {"Test that a Map containing a Map is correctly transformed", VERY_COMPLEX_MAP}, // {"Test that a Map containing a Map that has an object as key, is correctly transformed", EXTREME_COMPLEX_MAP} }; diff --git a/pom.xml b/pom.xml index d73c2cc77..46b5b0d68 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,8 @@ bull-common + bull-bean-transformer + bull-converter @@ -185,18 +187,9 @@ true - bull-bean-transformer - bull-converter bull-map-transformer - - bean-transformer - - bull-bean-transformer - bull-converter - - map-transformer From d0440c9ad33cf86f534d079e2e337f7f9e114789 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2019 02:35:09 +0000 Subject: [PATCH 0825/1786] Bump lombok from 1.18.8 to 1.18.10 Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.18.8 to 1.18.10. - [Release notes](https://github.com/rzwitserloot/lombok/releases) - [Changelog](https://github.com/rzwitserloot/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/rzwitserloot/lombok/compare/v1.18.8...v1.18.10) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f3ca5d1e5..789172c2a 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ ${jdk.version} ${jdk.version} 2.1.8.RELEASE - 1.18.8 + 1.18.10 3.9 0.11 2.8.5 From 6fade4e2bbaed58d0f01d56738b85bccbe09e6e4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 11 Sep 2019 08:32:49 +0200 Subject: [PATCH 0826/1786] [travis skip] added tests --- .../java/com/hotels/map/transformer/MapTransformerTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 7b5929c2c..d3d78fae9 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -87,9 +87,9 @@ public void testTransformWorksProperly(final String testCaseDescription, private Object[][] dataMapTransformerObject() { return new Object[][] { {"Test that a simple Map is correctly transformed", SAMPLE_MAP}, -// {"Test that a Map containing a list is correctly transformed", COMPLEX_MAP}, -// {"Test that a Map containing a Map is correctly transformed", VERY_COMPLEX_MAP}, -// {"Test that a Map containing a Map that has an object as key, is correctly transformed", EXTREME_COMPLEX_MAP} + {"Test that a Map containing a list is correctly transformed", COMPLEX_MAP}, + {"Test that a Map containing a Map is correctly transformed", VERY_COMPLEX_MAP}, + {"Test that a Map containing a Map that has an object as key, is correctly transformed", EXTREME_COMPLEX_MAP} }; } From e734c6cc9bffd6851f09622a997d6be7849695a5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 11 Sep 2019 09:05:54 +0200 Subject: [PATCH 0827/1786] Updated changelog with the new version --- CHANGELOG-JDK8.md | 9 +++++++++ CHANGELOG.md | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 2ef22ca90..6cb706a03 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,15 @@ All notable changes to this project will be documented in this file. +### [1.1.25] TBD +#### Changed +* Updated `spring-boot-starter-test` version to `2.1.8.RELEASE` (was `2.1.7.RELEASE`). +* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). +* Updated `testng` version to `7.0.0` (was `6.14.3`). +* Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). +* Updated `jacoco-maven-plugin` version to `0.8.4` (was `0.8.2`). +* Updated `lombok` version to `1.18.10` (was `1.18.8`). + ### [1.1.24] 2019.09.02 #### Changed * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.1.25`, use `bull-bean-transformer` instead.** diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b7e3ba0b..7ef9d6c71 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to this project will be documented in this file. +### [1.5.2] TBD +#### Changed +* Updated `spring-boot-starter-test` version to `2.1.8.RELEASE` (was `2.1.7.RELEASE`). +* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). +* Updated `testng` version to `7.0.0` (was `6.14.3`). +* Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). +* Updated `jacoco-maven-plugin` version to `0.8.4` (was `0.8.2`). +* Updated `lombok` version to `1.18.10` (was `1.18.8`). + ### [1.5.1] 2019.09.02 #### Changed * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** From c81fd2fb9be60711d4414130131e6c6156a4253e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 12 Sep 2019 16:43:57 +0200 Subject: [PATCH 0828/1786] [travis skip] Implemented Bean transformation inside maps --- .../AbstractBeanTransformerTest.java | 135 +------------- .../transformer/BeanTransformerTest.java | 6 +- .../ImmutableObjectTransformationTest.java | 4 +- .../transformer/model/FieldMapping.java | 2 + .../model/TransformerSettings.java | 1 + .../transformer/utils/ReflectionUtils.java | 38 ---- .../transformer/AbstractTransformerTest.java | 154 ++++++++++++++++ .../beans/transformer/package-info.java | 20 +++ .../map/transformer/MapTransformerImpl.java | 48 +++-- .../map/transformer/MapTransformerTest.java | 170 +++++++++++++++--- 10 files changed, 350 insertions(+), 228 deletions(-) create mode 100644 bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java create mode 100644 bull-common/src/test/java/com/hotels/beans/transformer/package-info.java diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index 585afa555..58f2daaa9 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -16,79 +16,16 @@ package com.hotels.beans.transformer; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; - import static org.mockito.MockitoAnnotations.initMocks; -import static com.hotels.transformer.constant.ClassType.IMMUTABLE; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; - import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooAdvFields; -import com.hotels.beans.sample.FromFooMap; -import com.hotels.beans.sample.FromFooOnlyPrimitiveTypes; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSubClass; -import com.hotels.beans.sample.FromFooWithPrimitiveFields; -import com.hotels.beans.sample.FromSubFoo; - /** * Unit test for {@link BeanTransformer}. */ -public abstract class AbstractBeanTransformerTest { - static final BigInteger ID = new BigInteger("1234"); - static final String NAME = "Goofy"; - static FromFoo fromFoo; - static FromFoo fromFooWithNullProperties; - static FromFooSimple fromFooSimple; - static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; - static FromFooSubClass fromFooSubClass; - static FromFooAdvFields fromFooAdvFields; - static FromFooMap fromFooMap; - static FromFooOnlyPrimitiveTypes fromFooPrimitiveTypes; - static final int AGE = 34; - static final String AGE_FIELD_NAME = "age"; - static final String DEST_FIELD_NAME = "destFieldName"; - static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; - static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; - static final String ID_FIELD_NAME = "id"; - static final String IDENTIFIER_FIELD_NAME = "identifier"; - static final String LOCALE_FIELD_NAME = "locale"; - static final String PHONE_NUMBER_DEST_FIELD_NAME = "phoneNumbers"; - static final String PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME = "nestedObject.phoneNumbers"; - static final String NAME_FIELD_NAME = "name"; - static final float PRICE = 10.0f; - - private static final String ITEM_1 = "donald"; - private static final String ITEM_2 = "duck"; - private static final String SURNAME = "surname"; - private static final boolean ACTIVE = true; - private static final int PHONE = 123; - private static final String INDEX_NUMBER = null; - private static final boolean CHECK = true; - private static final BigDecimal AMOUNT = new BigDecimal(10); - private static final String SUB_FOO_NAME = "Smith"; - private static final int[] SUB_FOO_PHONE_NUMBERS = {12345, 6892, 10873}; - private static final Map SAMPLE_MAP = new HashMap<>(); - private static final Map> COMPLEX_MAP = new HashMap<>(); - private static final Map> VERY_COMPLEX_MAP = new HashMap<>(); - private static final Map> EXTREME_COMPLEX_MAP = new HashMap<>(); - private static List fromSubFooList; - private static List sourceFooSimpleList; - private static FromSubFoo fromSubFoo; - +public abstract class AbstractBeanTransformerTest extends AbstractTransformerTest { /** * The class to be tested. */ @@ -110,74 +47,4 @@ public void beforeClass() { public void beforeMethod() { initMocks(this); } - - /** - * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. - */ - private void initObjects() { - SAMPLE_MAP.put(ITEM_1, ITEM_2); - COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); - VERY_COMPLEX_MAP.put(ITEM_1, SAMPLE_MAP); - fromSubFoo = new FromSubFoo(SUB_FOO_NAME, SUB_FOO_PHONE_NUMBERS, SAMPLE_MAP, COMPLEX_MAP, VERY_COMPLEX_MAP); - fromSubFooList = singletonList(fromSubFoo); - sourceFooSimpleList = asList(ITEM_1, ITEM_2); - fromFoo = createFromFoo(fromSubFoo); - fromFooWithNullProperties = createFromFoo(null); - fromFooSimple = createFromFooSimple(); - fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); - fromFooSubClass = createFromFooSubClass(); - fromFooAdvFields = createFromFooAdvFields(); - fromFooPrimitiveTypes = createFromFooPrimitiveTypes(); - EXTREME_COMPLEX_MAP.put(fromFooSimple, SAMPLE_MAP); - fromFooMap = new FromFooMap(SAMPLE_MAP, COMPLEX_MAP, VERY_COMPLEX_MAP, EXTREME_COMPLEX_MAP); - } - - /** - * Creates a {@link FromFoo} instance. - * @param fromSubFoo the {@link FromSubFoo} instance - * @return the {@link FromFoo} instance. - */ - private FromFoo createFromFoo(final FromSubFoo fromSubFoo) { - return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); - } - - /** - * Creates a {@link FromFooSimple} instance. - * @return the {@link FromFooSimple} instance. - */ - private FromFooSimple createFromFooSimple() { - return new FromFooSimple(NAME, ID, ACTIVE); - } - - /** - * Creates a {@link FromFooWithPrimitiveFields} instance. - * @return the {@link FromFooWithPrimitiveFields} instance. - */ - private FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { - return new FromFooWithPrimitiveFields(NAME, ID.intValue(), AGE, fromSubFooList, sourceFooSimpleList, fromSubFoo); - } - - /** - * Creates a {@link FromFooSubClass} instance. - * @return the {@link FromFooSubClass} instance. - */ - private FromFooSubClass createFromFooSubClass() { - return new FromFooSubClass(fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObjectList(), fromFoo.getList(), fromFoo.getNestedObject(), SURNAME, PHONE, CHECK, AMOUNT); - } - - /** - * Creates a {@link FromFooAdvFields} instance. - * @return the {@link FromFooAdvFields} instance. - */ - private FromFooAdvFields createFromFooAdvFields() { - return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage(), PRICE); - } - - /** - * Creates a {@link FromFooOnlyPrimitiveTypes} instance. - * @return the {@link FromFooOnlyPrimitiveTypes} instance. - */ - private FromFooOnlyPrimitiveTypes createFromFooPrimitiveTypes() { - return new FromFooOnlyPrimitiveTypes(ID.toString(), ID.intValue(), PRICE, String.valueOf(ACTIVE)); - } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 83e808ae4..553aa074f 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -75,7 +75,7 @@ public class BeanTransformerTest extends AbstractBeanTransformerTest { @Test public void testRemoveFieldMappingWorksProperly() { //GIVEN - BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); + BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); //WHEN beanTransformer.removeFieldMapping(DEST_FIELD_NAME); @@ -91,7 +91,7 @@ public void testRemoveFieldMappingWorksProperly() { @Test(expectedExceptions = IllegalArgumentException.class) public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { //GIVEN - BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); + BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); //WHEN beanTransformer.removeFieldMapping(null); @@ -104,7 +104,7 @@ public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { public void testResetFieldsMappingWorksProperly() { //GIVEN BeanTransformer beanTransformer = underTest - .withFieldMapping(new FieldMapping(SOURCE_FIELD_NAME, DEST_FIELD_NAME), new FieldMapping(SOURCE_FIELD_NAME_2, DEST_FIELD_NAME)); + .withFieldMapping(new FieldMapping<>(SOURCE_FIELD_NAME, DEST_FIELD_NAME), new FieldMapping<>(SOURCE_FIELD_NAME_2, DEST_FIELD_NAME)); //WHEN beanTransformer.resetFieldsMapping(); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index a3f8f23fd..95a996d65 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -151,7 +151,7 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(final String testCaseDescription, final Object sourceObject, final String expectedName, final BigInteger expectedId, final int[] expectedPhoneNumbers) { //GIVEN - FieldMapping phoneNumbersMapping = new FieldMapping(PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME, PHONE_NUMBER_DEST_FIELD_NAME); + FieldMapping phoneNumbersMapping = new FieldMapping<>(PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME, PHONE_NUMBER_DEST_FIELD_NAME); //WHEN ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(sourceObject, ImmutableFlatToFoo.class); @@ -227,7 +227,7 @@ public void testTransformThrowsExceptionWhenImmutableIsInvalid(final String test */ @DataProvider(parallel = true) private Object[][] dataInvalidBeanExceptionTesting() throws CloneNotSupportedException { - FromFoo fromFooNullId = AbstractBeanTransformerTest.fromFoo.clone(); + FromFoo fromFooNullId = AbstractTransformerTest.fromFoo.clone(); fromFooNullId.setId(null); return new Object[][] { {"Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object.", diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java index db72cd24e..70a280419 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java @@ -22,6 +22,8 @@ /** * Specifies the field's name mapping between the source object and destination one. + * @param source element type + * @param target element type */ @AllArgsConstructor @Getter diff --git a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java index d45de9b7e..2f8a3d3f4 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java @@ -30,6 +30,7 @@ * 1) The field name mapping * 2) The lambda function to apply on a field. * 3) Other configurations. + * @param source element type */ @Getter public class TransformerSettings { diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index 2332537d3..b692d71ce 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -482,30 +482,6 @@ public MapType getMapGenericType(final Type fieldType, final Class fieldClass return new MapType(keyType, elemType); } -// /** -// * Retrieves the generic class of the objects contained in the map. -// * It could be {@link ItemType} in case the object is primitive or is a collection -// * It could be {@link MapType} in case the object is a {@link Map} -// * @param fieldType the field containing the generic -// * @param declaringClass the class containing the field -// * @param fieldName the field name -// * @return the generic class of the objects contained in the map. -// */ -// private MapElemType getMapElemType(final Type fieldType, final String declaringClass, final String fieldName) { -// final String cacheKey = "MapElemType-" + declaringClass + "-" + fieldType.getTypeName() + '-' + fieldName; -// return CACHE_MANAGER.getFromCache(cacheKey, MapElemType.class).orElseGet(() -> { -// final Class argumentTypeClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); -// final MapElemType res; -// if (Map.class.isAssignableFrom(argumentTypeClass)) { -// res = getMapGenericType(fieldType, declaringClass, fieldName); -// } else { -// res = buildItemType(fieldType, declaringClass, fieldName); -// } -// CACHE_MANAGER.cacheObject(cacheKey, res); -// return res; -// }); -// } - /** * Retrieves the generic class of the objects contained in the map. * It could be {@link ItemType} in case the object is primitive or is a collection @@ -524,20 +500,6 @@ private MapElemType getMapElemType(final Type fieldType) { return res; } -// /** -// * Builds the {@link ItemType} object from a given object. -// * @param argument the object from which the class has to be retrieved -// * @param declaringClass the class containing the field of which the argument belongs to -// * @param fieldName the field name of which the argument belongs to -// * @return the {@link ItemType} object -// */ -// private ItemType buildItemType(final Object argument, final String declaringClass, final String fieldName) { -// return ItemType.builder() -// .objectClass(getArgumentTypeClass(argument, declaringClass, fieldName, false)) -// .genericClass(getArgumentTypeClass(argument, declaringClass, fieldName, true)) -// .build(); -// } - /** * Builds the {@link ItemType} object from a given object. * @param argument the object from which the class has to be retrieved diff --git a/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java new file mode 100644 index 000000000..8c86bef5a --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -0,0 +1,154 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.transformer; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; + +import static com.hotels.transformer.constant.ClassType.IMMUTABLE; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +import com.hotels.beans.sample.FromFoo; +import com.hotels.beans.sample.FromFooAdvFields; +import com.hotels.beans.sample.FromFooMap; +import com.hotels.beans.sample.FromFooOnlyPrimitiveTypes; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.FromFooSubClass; +import com.hotels.beans.sample.FromFooWithPrimitiveFields; +import com.hotels.beans.sample.FromSubFoo; + +/** + * Unit test for {@link com.hotels.transformer.Transformer}. + */ +public abstract class AbstractTransformerTest { + public static FromFoo fromFoo; + protected static final BigInteger ID = new BigInteger("1234"); + protected static final String NAME = "Goofy"; + protected static FromFoo fromFooWithNullProperties; + protected static FromFooSimple fromFooSimple; + protected static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; + protected static FromFooSubClass fromFooSubClass; + protected static FromFooAdvFields fromFooAdvFields; + protected static FromFooMap fromFooMap; + protected static FromFooOnlyPrimitiveTypes fromFooPrimitiveTypes; + protected static final int AGE = 34; + protected static final String AGE_FIELD_NAME = "age"; + protected static final String DEST_FIELD_NAME = "destFieldName"; + protected static final String CONSTRUCTOR_PARAMETER_NAME = "constructorParameterName"; + protected static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; + protected static final String ID_FIELD_NAME = "id"; + protected static final String IDENTIFIER_FIELD_NAME = "identifier"; + protected static final String LOCALE_FIELD_NAME = "locale"; + protected static final String PHONE_NUMBER_DEST_FIELD_NAME = "phoneNumbers"; + protected static final String PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME = "nestedObject.phoneNumbers"; + protected static final String NAME_FIELD_NAME = "name"; + protected static final float PRICE = 10.0f; + protected static final Map SAMPLE_MAP = new HashMap<>(); + protected static final Map> COMPLEX_MAP = new HashMap<>(); + protected static final Map> VERY_COMPLEX_MAP = new HashMap<>(); + protected static final Map> EXTREME_COMPLEX_MAP = new HashMap<>(); + private static final String ITEM_1 = "donald"; + private static final String ITEM_2 = "duck"; + private static final String SURNAME = "surname"; + private static final boolean ACTIVE = true; + private static final int PHONE = 123; + private static final String INDEX_NUMBER = null; + private static final boolean CHECK = true; + private static final BigDecimal AMOUNT = new BigDecimal(10); + private static final String SUB_FOO_NAME = "Smith"; + private static final int[] SUB_FOO_PHONE_NUMBERS = {12345, 6892, 10873}; + private static List fromSubFooList; + private static List sourceFooSimpleList; + private static FromSubFoo fromSubFoo; + + /** + * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. + */ + protected void initObjects() { + SAMPLE_MAP.put(ITEM_1, ITEM_2); + COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); + VERY_COMPLEX_MAP.put(ITEM_1, SAMPLE_MAP); + fromSubFoo = new FromSubFoo(SUB_FOO_NAME, SUB_FOO_PHONE_NUMBERS, SAMPLE_MAP, COMPLEX_MAP, VERY_COMPLEX_MAP); + fromSubFooList = singletonList(fromSubFoo); + sourceFooSimpleList = asList(ITEM_1, ITEM_2); + fromFoo = createFromFoo(fromSubFoo); + fromFooWithNullProperties = createFromFoo(null); + fromFooSimple = createFromFooSimple(); + fromFooWithPrimitiveFields = createFromFooWithPrimitiveFields(); + fromFooSubClass = createFromFooSubClass(); + fromFooAdvFields = createFromFooAdvFields(); + fromFooPrimitiveTypes = createFromFooPrimitiveTypes(); + EXTREME_COMPLEX_MAP.put(fromFooSimple, SAMPLE_MAP); + fromFooMap = new FromFooMap(SAMPLE_MAP, COMPLEX_MAP, VERY_COMPLEX_MAP, EXTREME_COMPLEX_MAP); + } + + /** + * Creates a {@link FromFoo} instance. + * @param fromSubFoo the {@link FromSubFoo} instance + * @return the {@link FromFoo} instance. + */ + private FromFoo createFromFoo(final FromSubFoo fromSubFoo) { + return new FromFoo(NAME, ID, fromSubFooList, sourceFooSimpleList, fromSubFoo); + } + + /** + * Creates a {@link FromFooSimple} instance. + * @return the {@link FromFooSimple} instance. + */ + private FromFooSimple createFromFooSimple() { + return new FromFooSimple(NAME, ID, ACTIVE); + } + + /** + * Creates a {@link FromFooWithPrimitiveFields} instance. + * @return the {@link FromFooWithPrimitiveFields} instance. + */ + private FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { + return new FromFooWithPrimitiveFields(NAME, ID.intValue(), AGE, fromSubFooList, sourceFooSimpleList, fromSubFoo); + } + + /** + * Creates a {@link FromFooSubClass} instance. + * @return the {@link FromFooSubClass} instance. + */ + private FromFooSubClass createFromFooSubClass() { + return new FromFooSubClass(fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObjectList(), fromFoo.getList(), fromFoo.getNestedObject(), SURNAME, PHONE, CHECK, AMOUNT); + } + + /** + * Creates a {@link FromFooAdvFields} instance. + * @return the {@link FromFooAdvFields} instance. + */ + private FromFooAdvFields createFromFooAdvFields() { + return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage(), PRICE); + } + + /** + * Creates a {@link FromFooOnlyPrimitiveTypes} instance. + * @return the {@link FromFooOnlyPrimitiveTypes} instance. + */ + private FromFooOnlyPrimitiveTypes createFromFooPrimitiveTypes() { + return new FromFooOnlyPrimitiveTypes(ID.toString(), ID.intValue(), PRICE, String.valueOf(ACTIVE)); + } +} diff --git a/bull-common/src/test/java/com/hotels/beans/transformer/package-info.java b/bull-common/src/test/java/com/hotels/beans/transformer/package-info.java new file mode 100644 index 000000000..0c711726d --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/transformer/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Transformer test package. + */ + +package com.hotels.beans.transformer; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index a846304ec..314e51799 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -17,11 +17,13 @@ import static java.util.stream.Collectors.toMap; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; +import static com.hotels.transformer.validator.Validator.notNull; import java.util.Map; import com.hotels.beans.transformer.BeanTransformer; import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.utils.ReflectionUtils; /** * Utility methods for populating {@link java.util.Map} elements via reflection. @@ -33,6 +35,8 @@ public class MapTransformerImpl extends AbstractMapTransformer { @Override @SuppressWarnings("unchecked") public Map transform(final Map sourceMap, final BeanTransformer beanTransformer) { + notNull(sourceMap, "The map to copy cannot be null!"); + notNull(beanTransformer, "The bean transformer to use cannot be null!"); Map keyFieldsTransformers = settings.getKeyFieldsTransformers(); Map res; if (settings.getFieldsNameMapping().isEmpty() && keyFieldsTransformers.isEmpty()) { @@ -40,11 +44,9 @@ public Map transform(final Map sourceMap, final BeanTransform } else { res = (Map) sourceMap.entrySet().stream() .collect(toMap( - e -> getTransformedObject(keyFieldsTransformers.get(e.getKey()), e.getKey()), -// e -> getFieldValue(e.getKey(), beanTransformer, keyFieldsTransformers.get(e.getKey())) - e -> getTransformedObject(settings.getFieldsTransformers().get(e.getKey()), getMapValue(e, sourceMap)) -// e -> getFieldValue(getMapValue(e, sourceMap), beanTransformer, settings.getFieldsTransformers().get(e.getKey())) - )); + e -> getTransformedObject(keyFieldsTransformers.get(e.getKey()), e.getKey()), + e -> getTransformedObject(settings.getFieldsTransformers().get(e.getKey()), getMapValue(e, sourceMap)) + )); } return res; } @@ -60,27 +62,24 @@ public Map transform(final Map sourceMap, final BeanTransform */ @SuppressWarnings("unchecked") private K getMapValue(final Map.Entry entry, final Map sourceMap) { - T newKey = (T) settings.getFieldsNameMapping().get(entry.getKey()); - return sourceMap.getOrDefault(newKey, entry.getValue()); - } - - /** - * Clones a Map. - * @param map the map to clone - * @param the key type - * @param the class type - * @return a clone of the given Map. - */ - private Map cloneMap(final Map map) { - return map.entrySet().stream().collect(toMap(Map.Entry::getKey, Map.Entry::getValue)); + return sourceMap.getOrDefault((T) settings.getFieldsNameMapping().get(entry.getKey()), entry.getValue()); } /** * {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public Map transform(final Map sourceMap, final Class targetKeyClass, final Class targetElemClass, final BeanTransformer beanTransformer) { - return null; + notNull(sourceMap, "The source map to copy cannot be null!"); + notNull(targetKeyClass, "The target key class cannot be null!"); + notNull(targetElemClass, "The target element class cannot be null!"); + notNull(beanTransformer, "The bean transformer to use cannot be null!"); + return (Map) sourceMap.entrySet().stream() + .collect(toMap( + e -> getFieldValue(e.getKey(), targetKeyClass, settings.getKeyFieldsTransformers().get(e.getKey()), beanTransformer), + e -> getFieldValue(getMapValue(e, sourceMap), targetElemClass, settings.getFieldsTransformers().get(e.getKey()), beanTransformer) + )); } /** @@ -88,10 +87,12 @@ public Map transform(final Map sourceMap, final Class void transform(final Map sourceMap, final Map targetMap, final BeanTransformer beanTransformer) { - + notNull(sourceMap, "The source map to copy cannot be null!"); + notNull(targetMap, "The target map cannot be null!"); + notNull(beanTransformer, "The bean transformer to use cannot be null!"); } - private Object getFieldValue(final Object value, final BeanTransformer beanTransformer, final FieldTransformer fieldTransformer) { + private Object getFieldValue(final Object value, final Class targetClass, final FieldTransformer fieldTransformer, final BeanTransformer beanTransformer) { Object newValue; Class fieldType = value.getClass(); if (classUtils.isPrimitiveOrSpecialType(fieldType)) { @@ -99,10 +100,7 @@ private Object getFieldValue(final Object value, final BeanTransformer beanTrans } else { newValue = getPopulator(fieldType, fieldType, beanTransformer) .map(populator -> populator.getPopulatedObject(fieldType, value)) - .orElseGet(() -> - // recursively inject object - beanTransformer.transform(value, fieldType) - ); + .orElseGet(() -> beanTransformer.transform(value, targetClass)); } newValue = getTransformedObject(fieldTransformer, newValue); return newValue; diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index d3d78fae9..ad23168d5 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -16,14 +16,13 @@ package com.hotels.map.transformer; -import static java.util.Collections.singletonList; - import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; -import java.math.BigInteger; +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; + import java.util.HashMap; -import java.util.List; import java.util.Map; import org.mockito.InjectMocks; @@ -31,20 +30,20 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.BeanUtils; +import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.immutable.ImmutableToFoo; +import com.hotels.beans.sample.mutable.MutableToFooSimple; +import com.hotels.beans.transformer.AbstractTransformerTest; +import com.hotels.beans.transformer.BeanTransformer; /** * Unit test for {@link MapTransformer}. */ -public class MapTransformerTest { - private static final Map SAMPLE_MAP = new HashMap<>(); - private static final Map> COMPLEX_MAP = new HashMap<>(); - private static final Map> VERY_COMPLEX_MAP = new HashMap<>(); - private static final Map> EXTREME_COMPLEX_MAP = new HashMap<>(); - private static final String ITEM_1 = "donald"; - private static final String ITEM_2 = "duck"; - private static final BigInteger ID = new BigInteger("1234"); - private static final String NAME = "Goofy"; +public class MapTransformerTest extends AbstractTransformerTest { + private static final Map COMPLEX_OBJECT_MAP = new HashMap<>(); + private static final BeanTransformer BEAN_TRANSFORMER = new BeanUtils().getTransformer(); /** * The class to be tested. @@ -61,6 +60,123 @@ public void beforeClass() { initObjects(); } + /** + * Test that the method {@code transform} raises an {@link IllegalArgumentException} if any parameter is null. + * @param testCaseDescription the test case description + * @param sourceMap the map to transform + * @param beanTransformer the bean transformer + */ + @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformMethodWithTwoArgument") + public void testTransformRaisesExceptionIfItsCalledWithNullParameter(final String testCaseDescription, final Map sourceMap, final BeanTransformer beanTransformer) { + //GIVEN + + //WHEN + underTest.transform(sourceMap, beanTransformer); + } + + /** + * Created the parameter to test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. + * @return parameters to be used for testing. + */ + @DataProvider + private Object[][] dataTransformMethodWithTwoArgument() { + return new Object[][] { + {"Test that an IllegalArgumentException is thrown if the sourceMap is null", null, BEAN_TRANSFORMER}, + {"Test that an IllegalArgumentException is thrown if the transformer is null", SAMPLE_MAP, null} + }; + } + + /** + * Test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. + * @param testCaseDescription the test case description + * @param sourceMap the map to transform + * @param targetMap the target map + * @param beanTransformer the bean transformer + * @param the key type + * @param the element type + */ + @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformMethodWithThreeArgument") + public void testTransformRaisesExceptionIfItsCalledWithAnyNullParameter(final String testCaseDescription, final Map sourceMap, + final Map targetMap, final BeanTransformer beanTransformer) { + //GIVEN + + //WHEN + underTest.transform(sourceMap, targetMap, beanTransformer); + } + + /** + * Created the parameter to test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. + * @return parameters to be used for testing. + */ + @DataProvider + private Object[][] dataTransformMethodWithThreeArgument() { + return new Object[][] { + {"Test that an IllegalArgumentException is thrown if the sourceMap is null", null, SAMPLE_MAP, BEAN_TRANSFORMER}, + {"Test that an IllegalArgumentException is thrown if the targetMap is null", SAMPLE_MAP, null, BEAN_TRANSFORMER}, + {"Test that an IllegalArgumentException is thrown if the bean transformer is null", SAMPLE_MAP, SAMPLE_MAP, null} + }; + } + + /** + * Test that the method {@code transform} raises an {@link IllegalArgumentException} if any parameter is null. + * @param testCaseDescription the test case description + * @param sourceMap the map to transform + * @param targetKeyClass the Map key class type in the target Map + * @param targetElemClass the Map element class type in the target Map + * @param beanTransformer the bean transformer + */ + @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformMethodWithFourArgument") + public void testTransformRaisesExceptionIfItsCalledWithNullParameter(final String testCaseDescription, final Map sourceMap, + final Class targetKeyClass, final Class targetElemClass, final BeanTransformer beanTransformer) { + //GIVEN + + //WHEN + underTest.transform(sourceMap, targetKeyClass, targetElemClass, beanTransformer); + } + + /** + * Created the parameter to test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. + * @return parameters to be used for testing. + */ + @DataProvider + private Object[][] dataTransformMethodWithFourArgument() { + return new Object[][] { + {"Test that an IllegalArgumentException is thrown if the sourceMap is null", null, String.class, String.class, BEAN_TRANSFORMER}, + {"Test that an IllegalArgumentException is thrown if the targetKeyClass is null", SAMPLE_MAP, null, String.class, BEAN_TRANSFORMER}, + {"Test that an IllegalArgumentException is thrown if the targetElemClass is null", SAMPLE_MAP, String.class, null, BEAN_TRANSFORMER}, + {"Test that an IllegalArgumentException is thrown if the bean transformer is null", SAMPLE_MAP, String.class, String.class, null} + }; + } + + /** + * Test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. + * @param testCaseDescription the test case description + * @param sourceMap the map to transform + * @param sourceMap the map to transform + * @param the key type + * @param the element type + */ + @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformWithTargetClassesAndInvalidParameter") + public void testTransformRaisesExceptionIfItsCalledWithAnyNullParameter(final String testCaseDescription, final Map sourceMap, final Class targetKeyClass, final Class targetElemClass) { + //GIVEN + + //WHEN + underTest.transform(sourceMap, targetKeyClass, targetElemClass); + } + + /** + * Created the parameter to test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. + * @return parameters to be used for testing. + */ + @DataProvider + private Object[][] dataTransformWithTargetClassesAndInvalidParameter() { + return new Object[][] { + {"Test that an IllegalArgumentException is thrown if the sourceMap is null", null, String.class, String.class}, + {"Test that an IllegalArgumentException is thrown if the targetKeyClass is null", SAMPLE_MAP, null, String.class}, + {"Test that an IllegalArgumentException is thrown if the targetElemClass is null", SAMPLE_MAP, String.class, null}, + }; + } + /** * Test that the given map is correctly transformed. * @param testCaseDescription the test case description @@ -94,20 +210,22 @@ private Object[][] dataMapTransformerObject() { } /** - * Create an instance of two objects: one without custom annotation and another one with custom annotations then execute the copy into a specular immutable object. + * Test that the given map is correctly transformed. */ - private void initObjects() { - SAMPLE_MAP.put(ITEM_1, ITEM_2); - COMPLEX_MAP.put(ITEM_1, singletonList(ITEM_2)); - VERY_COMPLEX_MAP.put(ITEM_1, SAMPLE_MAP); - EXTREME_COMPLEX_MAP.put(createFromFooSimple(), SAMPLE_MAP); - } + @Test + public void testTransformWorksProperly() { + //GIVEN + COMPLEX_OBJECT_MAP.put(fromFooSimple, fromFoo); - /** - * Creates a {@link FromFooSimple} instance. - * @return the {@link FromFooSimple} instance. - */ - private FromFooSimple createFromFooSimple() { - return new FromFooSimple(NAME, ID, Boolean.TRUE); + //WHEN + Map actual = underTest.transform(COMPLEX_OBJECT_MAP, MutableToFooSimple.class, ImmutableToFoo.class); + + //THEN + assertNotNull(actual); + for (Map.Entry entry : actual.entrySet()) { + assertThat(entry.getKey(), sameBeanAs(fromFooSimple)); + assertThat(entry.getValue(), sameBeanAs(fromFoo)); + + } } } From 4c75534aa35d9945a3a74379a49a4d66e1be6624 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 22 Sep 2019 05:12:52 +0200 Subject: [PATCH 0829/1786] MapTransformer module: moved the transformation of complex object in a map in a different branch --- .../beans/populator/ArrayPopulator.java | 10 +- .../beans/populator/CollectionPopulator.java | 10 -- .../hotels/beans/populator/MapPopulator.java | 6 - .../beans/populator/OptionalPopulator.java | 9 -- .../com/hotels/beans/populator/Populator.java | 8 -- .../transformer/utils/ReflectionUtils.java | 114 ++++++---------- .../transformer/AbstractMapTransformer.java | 19 +-- .../map/transformer/MapTransformer.java | 54 -------- .../map/transformer/MapTransformerImpl.java | 51 ++----- .../java/com/hotels/map/package-info.java | 4 +- .../map/transformer/MapTransformerTest.java | 129 +++--------------- .../hotels/map/transformer/package-info.java | 1 + 12 files changed, 79 insertions(+), 336 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index de19db398..afa9c0bd3 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -40,15 +40,7 @@ class ArrayPopulator extends Populator implements ICollectionPopulator fieldClass, final Object fieldValue) { - return getPopulatedObject(fieldClass, fieldClass.getComponentType(), fieldValue, null); + return getPopulatedObject(field.getType(), reflectionUtils.getArrayType(field), fieldValue, null); } /** diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index a01759637..896b68c50 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -50,16 +50,6 @@ public Collection getPopulatedObject(final Field field, final Collection fiel return getPopulatedObject(field.getType(), reflectionUtils.getGenericFieldType(field), fieldValue, genericClass); } - /** - * {@inheritDoc} - */ - @Override - public Collection getPopulatedObject(final Class fieldClass, final Collection fieldValue) { - final Class genericClass = reflectionUtils.getArgumentTypeClass(fieldValue, true); -// return getPopulatedObject(fieldClass, reflectionUtils.getGenericFieldType(fieldClass.getGenericSuperclass()), fieldValue, genericClass); - return getPopulatedObject(fieldClass, fieldClass, fieldValue, genericClass); - } - /** * {@inheritDoc} */ diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java index 7c0d6df7f..10fb1d250 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -48,12 +48,6 @@ class MapPopulator extends Populator> { return getPopulatedObject(fieldValue, mapGenericType); } - @Override - public Map getPopulatedObject(final Class fieldClass, final Map fieldValue) { - MapType mapGenericType = reflectionUtils.getMapGenericType(fieldValue.getClass().getGenericSuperclass(), fieldClass); - return getPopulatedObject(fieldValue, mapGenericType); - } - /** * Populates the Map objects. * @param fieldValue the source Map. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index e6618517d..98c3cbbe1 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -52,13 +52,4 @@ public Object getPopulatedObject(final Field field, final Object fieldValue) { } return res; } - - /** - * {@inheritDoc} - */ - @Override - public Object getPopulatedObject(final Class fieldClass, final Object fieldValue) { - return null; // no implementation needed. - } - } diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java index e63ca0ab3..9791a8054 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java @@ -63,14 +63,6 @@ public abstract class Populator { */ protected abstract O getPopulatedObject(Field field, O fieldValue); - /** - * Populates the target object with the values into the source object. - * @param fieldClass the field class - * @param fieldValue the source object from which extract the values - * @return a populated list of elements - */ - public abstract O getPopulatedObject(Class fieldClass, O fieldValue); - /** * Populates the target object with the values into the source object. * @param the target object type diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index b692d71ce..744e8ac03 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -421,28 +421,18 @@ public Method getSetterMethodForField(final Class fieldClass, final String fi public Class getGenericFieldType(final Field field) { final String cacheKey = "GenericFieldType-" + field.getDeclaringClass().getName() + '-' + field.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Class.class).orElseGet(() -> { - Class res = getGenericFieldType(field.getGenericType()); + Class res = null; + if (ParameterizedType.class.isAssignableFrom(field.getGenericType().getClass())) { + final Type[] fieldArgTypes = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); + if (fieldArgTypes.length != 0) { + res = (Class) fieldArgTypes[0]; + } + } CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); } - /** - * Gets the generic infer type of an object. - * @param objectType the element object type containing the generic - * @return the generic type class - */ - public Class getGenericFieldType(final Type objectType) { - Class res = null; - if (ParameterizedType.class.isAssignableFrom(objectType.getClass())) { - final Type[] fieldArgTypes = ((ParameterizedType) objectType).getActualTypeArguments(); - if (fieldArgTypes.length != 0) { - res = (Class) fieldArgTypes[0]; - } - } - return res; - } - /** * Gets the generic infer type of a map object. * @param fieldType the field containing the generic @@ -454,61 +444,54 @@ public MapType getMapGenericType(final Type fieldType, final String declaringCla final Class fieldClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); final String cacheKey = "MapGenericFieldType-" + fieldClass.getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, MapType.class).orElseGet(() -> { - MapType mapType; - try { - mapType = getMapGenericType(fieldType, fieldClass); - CACHE_MANAGER.cacheObject(cacheKey, mapType); - } catch (IllegalArgumentException e) { + if (!Map.class.isAssignableFrom(fieldClass)) { throw new IllegalArgumentException("Type for object: " + fieldName + " is invalid. " - + "It cannot be assigned from: " + Map.class.getName() + "."); + + "It cannot be assigned from: " + Map.class.getName() + "."); } + final ParameterizedType genericType = (ParameterizedType) fieldType; + final MapElemType keyType = getMapElemType(genericType.getActualTypeArguments()[0], declaringClass, fieldName); + final MapElemType elemType = getMapElemType(genericType.getActualTypeArguments()[1], declaringClass, fieldName); + final MapType mapType = new MapType(keyType, elemType); + CACHE_MANAGER.cacheObject(cacheKey, mapType); return mapType; }); } - /** - * Gets the generic infer type of a map object. - * @param fieldType the field containing the generic - * @param fieldClass the field class - * @return the generic type class - */ - public MapType getMapGenericType(final Type fieldType, final Class fieldClass) { - if (!Map.class.isAssignableFrom(fieldClass)) { - throw new IllegalArgumentException("Type: " + fieldClass.getName() + " cannot be assigned from: " + Map.class.getName() + "."); - } - final ParameterizedType genericType = (ParameterizedType) fieldType; - final MapElemType keyType = getMapElemType(genericType.getActualTypeArguments()[0]); - final MapElemType elemType = getMapElemType(genericType.getActualTypeArguments()[1]); - return new MapType(keyType, elemType); - } - /** * Retrieves the generic class of the objects contained in the map. * It could be {@link ItemType} in case the object is primitive or is a collection * It could be {@link MapType} in case the object is a {@link Map} * @param fieldType the field containing the generic + * @param declaringClass the class containing the field + * @param fieldName the field name * @return the generic class of the objects contained in the map. */ - private MapElemType getMapElemType(final Type fieldType) { - final Class argumentTypeClass = getArgumentTypeClass(fieldType, false); - final MapElemType res; - if (Map.class.isAssignableFrom(argumentTypeClass)) { - res = getMapGenericType(fieldType, argumentTypeClass); - } else { - res = buildItemType(fieldType); - } - return res; + private MapElemType getMapElemType(final Type fieldType, final String declaringClass, final String fieldName) { + final String cacheKey = "MapElemType-" + declaringClass + "-" + fieldType.getTypeName() + '-' + fieldName; + return CACHE_MANAGER.getFromCache(cacheKey, MapElemType.class).orElseGet(() -> { + final Class argumentTypeClass = getArgumentTypeClass(fieldType, declaringClass, fieldName, false); + final MapElemType res; + if (Map.class.isAssignableFrom(argumentTypeClass)) { + res = getMapGenericType(fieldType, declaringClass, fieldName); + } else { + res = buildItemType(fieldType, declaringClass, fieldName); + } + CACHE_MANAGER.cacheObject(cacheKey, res); + return res; + }); } /** * Builds the {@link ItemType} object from a given object. * @param argument the object from which the class has to be retrieved + * @param declaringClass the class containing the field of which the argument belongs to + * @param fieldName the field name of which the argument belongs to * @return the {@link ItemType} object */ - private ItemType buildItemType(final Object argument) { + private ItemType buildItemType(final Object argument, final String declaringClass, final String fieldName) { return ItemType.builder() - .objectClass(getArgumentTypeClass(argument, false)) - .genericClass(getArgumentTypeClass(argument, true)) + .objectClass(getArgumentTypeClass(argument, declaringClass, fieldName, false)) + .genericClass(getArgumentTypeClass(argument, declaringClass, fieldName, true)) .build(); } @@ -528,32 +511,19 @@ public Class getArgumentTypeClass(final Object argument, final String declari return CACHE_MANAGER.getFromCache(cacheKey, Class.class) .map(atc -> atc == EmptyValue.class ? null : atc) .orElseGet(() -> { - Class res = getArgumentTypeClass(argument, getNestedGenericClass); + Class res = null; + if (argumentIsTypeClass) { + res = getNestedGenericClass ? null : (Class) argument; + } else if (ParameterizedType.class.isAssignableFrom(argument.getClass())) { + res = getNestedGenericClass + ? getArgumentTypeClass(((ParameterizedType) argument).getActualTypeArguments()[0], declaringClass, fieldName, false) + : (Class) ((ParameterizedType) argument).getRawType(); + } CACHE_MANAGER.cacheObject(cacheKey, res, EmptyValue.class); return res; }); } - /** - * Gets the class of a given object. - * @param argument the object from which the class has to be retrieved - * @param getNestedGenericClass if true it retrieves the class of the object generic (if any). i.e. {@code argument = List;} - * returns {@code String}, if false returns {@code List} - * @return the given argument class type - */ - public Class getArgumentTypeClass(final Object argument, final boolean getNestedGenericClass) { - final boolean argumentIsTypeClass = argument instanceof Class; - Class res = null; - if (argumentIsTypeClass) { - res = getNestedGenericClass ? null : (Class) argument; - } else if (ParameterizedType.class.isAssignableFrom(argument.getClass())) { - res = getNestedGenericClass - ? getArgumentTypeClass(((ParameterizedType) argument).getActualTypeArguments()[0], false) - : (Class) ((ParameterizedType) argument).getRawType(); - } - return res; - } - /** * Gets the type of an array. * @param arrayField the array diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index 73bd5ee33..753751206 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -1,9 +1,12 @@ /** * Copyright (C) 2019 Expedia, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -45,22 +48,6 @@ public Map transform(final Map sourceMap) { return transform(sourceMap, new BeanUtils().getTransformer()); } - /** - * {@inheritDoc} - */ - @Override - public void transform(final Map sourceMap, final Map targetMap) { - transform(sourceMap, targetMap, new BeanUtils().getTransformer()); - } - - /** - * {@inheritDoc} - */ - @Override - public Map transform(final Map sourceMap, final Class targetKeyClass, final Class targetElemClass) { - return transform(sourceMap, targetKeyClass, targetElemClass, new BeanUtils().getTransformer()); - } - /** * {@inheritDoc} */ diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index 3e48ed370..734b40c30 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -48,60 +48,6 @@ public interface MapTransformer extends Transformer { */ Map transform(Map sourceMap, BeanTransformer beanTransformer); - /** - * Transforms the given Map into a new one. All the Map key, element are transformed into the given class types - * @param sourceMap the source map - * @param targetKeyClass the Map key class type in the target Map - * @param targetElemClass the Map element class type in the target Map - * @param the key object type in the source map - * @param the elem object type in the source map - * @param the key object type in the target map - * @param the elem object type in the target map - * @return a copy of the source object into the destination object - * @throws IllegalArgumentException if any parameter is invalid - */ - Map transform(Map sourceMap, Class targetKeyClass, Class targetElemClass); - - /** - * Transforms the given Map into a new one. All the Map key, element are transformed into the given class types - * @param sourceMap the source map - * @param targetKeyClass the Map key class type in the target Map - * @param targetElemClass the Map element class type in the target Map - * @param beanTransformer the bean transformer to use for the map elements transformation - * @param the key object type in the source map - * @param the elem object type in the source map - * @param the key object type in the target map - * @param the elem object type in the target map - * @return a copy of the source object into the destination object - * @throws IllegalArgumentException if any parameter is invalid - */ - Map transform(Map sourceMap, Class targetKeyClass, Class targetElemClass, BeanTransformer beanTransformer); - - /** - * Copies all properties from a map to the given one. - * @param sourceMap the source object - * @param targetMap the destination object - * @param the key object type in the source map - * @param the elem object type in the source map - * @param the key object type in the target map - * @param the elem object type in the target map - * @throws IllegalArgumentException if any parameter is invalid - */ - void transform(Map sourceMap, Map targetMap); - - /** - * Copies all properties from a map to the given one. - * @param sourceMap the source object - * @param targetMap the destination object - * @param beanTransformer the bean transformer to use for the map elements transformation - * @param the key object type in the source map - * @param the elem object type in the source map - * @param the key object type in the target map - * @param the elem object type in the target map - * @throws IllegalArgumentException if any parameter is invalid - */ - void transform(Map sourceMap, Map targetMap, BeanTransformer beanTransformer); - /** * Initializes the transformer functions to apply on a Map key. The transformer function returns directly the field value. * @param keyFieldTransformer the fields transformer function diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index 314e51799..6a77d2489 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -1,9 +1,12 @@ /** * Copyright (C) 2019 Expedia, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,14 +19,13 @@ import static java.util.Objects.nonNull; import static java.util.stream.Collectors.toMap; -import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import static com.hotels.transformer.validator.Validator.notNull; +import java.util.HashMap; import java.util.Map; import com.hotels.beans.transformer.BeanTransformer; import com.hotels.transformer.model.FieldTransformer; -import com.hotels.transformer.utils.ReflectionUtils; /** * Utility methods for populating {@link java.util.Map} elements via reflection. @@ -40,7 +42,7 @@ public Map transform(final Map sourceMap, final BeanTransform Map keyFieldsTransformers = settings.getKeyFieldsTransformers(); Map res; if (settings.getFieldsNameMapping().isEmpty() && keyFieldsTransformers.isEmpty()) { - res = Map.copyOf(sourceMap); + res = new HashMap<>(sourceMap); } else { res = (Map) sourceMap.entrySet().stream() .collect(toMap( @@ -66,46 +68,11 @@ private K getMapValue(final Map.Entry entry, final Map source } /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - @Override - public Map transform(final Map sourceMap, final Class targetKeyClass, final Class targetElemClass, final BeanTransformer beanTransformer) { - notNull(sourceMap, "The source map to copy cannot be null!"); - notNull(targetKeyClass, "The target key class cannot be null!"); - notNull(targetElemClass, "The target element class cannot be null!"); - notNull(beanTransformer, "The bean transformer to use cannot be null!"); - return (Map) sourceMap.entrySet().stream() - .collect(toMap( - e -> getFieldValue(e.getKey(), targetKeyClass, settings.getKeyFieldsTransformers().get(e.getKey()), beanTransformer), - e -> getFieldValue(getMapValue(e, sourceMap), targetElemClass, settings.getFieldsTransformers().get(e.getKey()), beanTransformer) - )); - } - - /** - * {@inheritDoc} + * Applies the {@link FieldTransformer} function (if any) to the given Map element value. + * @param fieldTransformer the {@link FieldTransformer} function to apply + * @param value the object on which the function has to be applied + * @return the transformed value */ - @Override - public void transform(final Map sourceMap, final Map targetMap, final BeanTransformer beanTransformer) { - notNull(sourceMap, "The source map to copy cannot be null!"); - notNull(targetMap, "The target map cannot be null!"); - notNull(beanTransformer, "The bean transformer to use cannot be null!"); - } - - private Object getFieldValue(final Object value, final Class targetClass, final FieldTransformer fieldTransformer, final BeanTransformer beanTransformer) { - Object newValue; - Class fieldType = value.getClass(); - if (classUtils.isPrimitiveOrSpecialType(fieldType)) { - newValue = value; - } else { - newValue = getPopulator(fieldType, fieldType, beanTransformer) - .map(populator -> populator.getPopulatedObject(fieldType, value)) - .orElseGet(() -> beanTransformer.transform(value, targetClass)); - } - newValue = getTransformedObject(fieldTransformer, newValue); - return newValue; - } - private Object getTransformedObject(final FieldTransformer fieldTransformer, final Object value) { Object newValue = value; if (nonNull(fieldTransformer)) { diff --git a/bull-map-transformer/src/test/java/com/hotels/map/package-info.java b/bull-map-transformer/src/test/java/com/hotels/map/package-info.java index 7533358d7..7620a9326 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/package-info.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/package-info.java @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * Test package. + * Map Transformer Test package. */ -package com.hotels.map; \ No newline at end of file +package com.hotels.map; diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index ad23168d5..41a684716 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -16,12 +16,15 @@ package com.hotels.map.transformer; +import static org.hamcrest.Matchers.both; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.everyItem; +import static org.hamcrest.Matchers.isIn; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; - import java.util.HashMap; import java.util.Map; @@ -31,18 +34,14 @@ import org.testng.annotations.Test; import com.hotels.beans.BeanUtils; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.immutable.ImmutableToFoo; -import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.transformer.AbstractTransformerTest; import com.hotels.beans.transformer.BeanTransformer; +import com.hotels.transformer.model.FieldMapping; /** * Unit test for {@link MapTransformer}. */ public class MapTransformerTest extends AbstractTransformerTest { - private static final Map COMPLEX_OBJECT_MAP = new HashMap<>(); private static final BeanTransformer BEAN_TRANSFORMER = new BeanUtils().getTransformer(); /** @@ -67,7 +66,8 @@ public void beforeClass() { * @param beanTransformer the bean transformer */ @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformMethodWithTwoArgument") - public void testTransformRaisesExceptionIfItsCalledWithNullParameter(final String testCaseDescription, final Map sourceMap, final BeanTransformer beanTransformer) { + public void testTransformRaisesExceptionIfItsCalledWithNullParameter(final String testCaseDescription, + final Map sourceMap, final BeanTransformer beanTransformer) { //GIVEN //WHEN @@ -86,97 +86,6 @@ private Object[][] dataTransformMethodWithTwoArgument() { }; } - /** - * Test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. - * @param testCaseDescription the test case description - * @param sourceMap the map to transform - * @param targetMap the target map - * @param beanTransformer the bean transformer - * @param the key type - * @param the element type - */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformMethodWithThreeArgument") - public void testTransformRaisesExceptionIfItsCalledWithAnyNullParameter(final String testCaseDescription, final Map sourceMap, - final Map targetMap, final BeanTransformer beanTransformer) { - //GIVEN - - //WHEN - underTest.transform(sourceMap, targetMap, beanTransformer); - } - - /** - * Created the parameter to test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. - * @return parameters to be used for testing. - */ - @DataProvider - private Object[][] dataTransformMethodWithThreeArgument() { - return new Object[][] { - {"Test that an IllegalArgumentException is thrown if the sourceMap is null", null, SAMPLE_MAP, BEAN_TRANSFORMER}, - {"Test that an IllegalArgumentException is thrown if the targetMap is null", SAMPLE_MAP, null, BEAN_TRANSFORMER}, - {"Test that an IllegalArgumentException is thrown if the bean transformer is null", SAMPLE_MAP, SAMPLE_MAP, null} - }; - } - - /** - * Test that the method {@code transform} raises an {@link IllegalArgumentException} if any parameter is null. - * @param testCaseDescription the test case description - * @param sourceMap the map to transform - * @param targetKeyClass the Map key class type in the target Map - * @param targetElemClass the Map element class type in the target Map - * @param beanTransformer the bean transformer - */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformMethodWithFourArgument") - public void testTransformRaisesExceptionIfItsCalledWithNullParameter(final String testCaseDescription, final Map sourceMap, - final Class targetKeyClass, final Class targetElemClass, final BeanTransformer beanTransformer) { - //GIVEN - - //WHEN - underTest.transform(sourceMap, targetKeyClass, targetElemClass, beanTransformer); - } - - /** - * Created the parameter to test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. - * @return parameters to be used for testing. - */ - @DataProvider - private Object[][] dataTransformMethodWithFourArgument() { - return new Object[][] { - {"Test that an IllegalArgumentException is thrown if the sourceMap is null", null, String.class, String.class, BEAN_TRANSFORMER}, - {"Test that an IllegalArgumentException is thrown if the targetKeyClass is null", SAMPLE_MAP, null, String.class, BEAN_TRANSFORMER}, - {"Test that an IllegalArgumentException is thrown if the targetElemClass is null", SAMPLE_MAP, String.class, null, BEAN_TRANSFORMER}, - {"Test that an IllegalArgumentException is thrown if the bean transformer is null", SAMPLE_MAP, String.class, String.class, null} - }; - } - - /** - * Test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. - * @param testCaseDescription the test case description - * @param sourceMap the map to transform - * @param sourceMap the map to transform - * @param the key type - * @param the element type - */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformWithTargetClassesAndInvalidParameter") - public void testTransformRaisesExceptionIfItsCalledWithAnyNullParameter(final String testCaseDescription, final Map sourceMap, final Class targetKeyClass, final Class targetElemClass) { - //GIVEN - - //WHEN - underTest.transform(sourceMap, targetKeyClass, targetElemClass); - } - - /** - * Created the parameter to test that the method {@code transform} raises an {@link IllegalArgumentException} with an invalid parameter. - * @return parameters to be used for testing. - */ - @DataProvider - private Object[][] dataTransformWithTargetClassesAndInvalidParameter() { - return new Object[][] { - {"Test that an IllegalArgumentException is thrown if the sourceMap is null", null, String.class, String.class}, - {"Test that an IllegalArgumentException is thrown if the targetKeyClass is null", SAMPLE_MAP, null, String.class}, - {"Test that an IllegalArgumentException is thrown if the targetElemClass is null", SAMPLE_MAP, String.class, null}, - }; - } - /** * Test that the given map is correctly transformed. * @param testCaseDescription the test case description @@ -193,6 +102,8 @@ public void testTransformWorksProperly(final String testCaseDescription, //THEN assertNotNull(actual); + assertEquals(actual.size(), sourceMap.size()); + assertThat(actual.entrySet(), both(everyItem(isIn(sourceMap.entrySet()))).and(containsInAnyOrder(sourceMap.entrySet().toArray()))); } /** @@ -210,22 +121,24 @@ private Object[][] dataMapTransformerObject() { } /** - * Test that the given map is correctly transformed. + * Test that the given map is correctly transformed if key mappings are defined. */ @Test - public void testTransformWorksProperly() { + public void testTransformWorksProperlyWithKeyMapping() { //GIVEN - COMPLEX_OBJECT_MAP.put(fromFooSimple, fromFoo); + Map sourceMap = new HashMap<>(); + sourceMap.put("key1", 1); + sourceMap.put("key2", 2); + underTest.withFieldMapping(new FieldMapping<>("key1", "key2")); //WHEN - Map actual = underTest.transform(COMPLEX_OBJECT_MAP, MutableToFooSimple.class, ImmutableToFoo.class); + Map actual = underTest.transform(sourceMap); //THEN assertNotNull(actual); - for (Map.Entry entry : actual.entrySet()) { - assertThat(entry.getKey(), sameBeanAs(fromFooSimple)); - assertThat(entry.getValue(), sameBeanAs(fromFoo)); - - } + assertEquals(actual.size(), sourceMap.size()); + assertEquals(actual.get("key1"), sourceMap.get("key1")); + assertEquals(actual.get("key2"), sourceMap.get("key1")); + underTest.resetFieldsMapping(); } } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java index c9df4dbae..c8c3e0cba 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java @@ -18,3 +18,4 @@ */ package com.hotels.map.transformer; + From 5771c8be4b901d8b938597f294f2c9ca500f8b91 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2019 05:07:18 +0000 Subject: [PATCH 0830/1786] Bump mockito-core from 3.0.0 to 3.1.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.0.0...v3.1.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 789172c2a..141b537d1 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ 0.11 2.8.5 7.0.0 - 3.0.0 + 3.1.0 2.0.1.Final 6.0.17.Final From a2d8f5d83f849d4361f94f37e9cbd58ccdcfc62e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2019 04:52:36 +0000 Subject: [PATCH 0831/1786] Bump spring-boot-starter-test from 2.1.8.RELEASE to 2.1.9.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.1.8.RELEASE to 2.1.9.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.1.8.RELEASE...v2.1.9.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 789172c2a..83a4d6c98 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ 11 ${jdk.version} ${jdk.version} - 2.1.8.RELEASE + 2.1.9.RELEASE 1.18.10 3.9 0.11 From abe6a2b4f48ef675c2cb8a04917b3a35bfe4ea00 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 02:45:36 +0000 Subject: [PATCH 0832/1786] Bump gson from 2.8.5 to 2.8.6 Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.8.6. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.6) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 789172c2a..4d101ae2f 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ 1.18.10 3.9 0.11 - 2.8.5 + 2.8.6 7.0.0 3.0.0 From ba4ed486833711e1c10df376b706d240a638f2a9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 12 Oct 2019 20:27:30 +0200 Subject: [PATCH 0833/1786] [travis skip] made map transformer able to transform key and elem types in a different class type --- .../com/hotels/beans/populator/Populator.java | 2 +- .../transformer/AbstractTransformerTest.java | 2 +- .../transformer/AbstractMapTransformer.java | 8 +++ .../map/transformer/MapTransformer.java | 29 ++++++++ .../map/transformer/MapTransformerImpl.java | 46 +++++++++++-- .../map/transformer/MapTransformerTest.java | 68 ++++++++++++++++--- 6 files changed, 140 insertions(+), 15 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java index 9791a8054..733fc6853 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java @@ -83,7 +83,7 @@ public final O getPopulatedObject(final Class targetClass, final String f * @param the target object type * @return a copy of the source object into the destination object */ - final K transform(final T sourceObj, final Class targetClass) { + public final K transform(final T sourceObj, final Class targetClass) { return transform(sourceObj, targetClass, null); } diff --git a/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index 8c86bef5a..ab26f94bc 100644 --- a/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -68,7 +68,7 @@ public abstract class AbstractTransformerTest { protected static final Map> COMPLEX_MAP = new HashMap<>(); protected static final Map> VERY_COMPLEX_MAP = new HashMap<>(); protected static final Map> EXTREME_COMPLEX_MAP = new HashMap<>(); - private static final String ITEM_1 = "donald"; + protected static final String ITEM_1 = "donald"; private static final String ITEM_2 = "duck"; private static final String SURNAME = "surname"; private static final boolean ACTIVE = true; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index 753751206..369ea5179 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -48,6 +48,14 @@ public Map transform(final Map sourceMap) { return transform(sourceMap, new BeanUtils().getTransformer()); } + /** + * {@inheritDoc} + */ + @Override + public Map transform(final Map sourceMap, final Class targetKeyType, final Class targetElemType) { + return transform(sourceMap, new BeanUtils().getTransformer(), targetKeyType, targetElemType); + } + /** * {@inheritDoc} */ diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index 734b40c30..8cdd99a91 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -48,6 +48,35 @@ public interface MapTransformer extends Transformer { */ Map transform(Map sourceMap, BeanTransformer beanTransformer); + /** + * Copies all properties from a map to a new one applying the transformation function and mappings defined. + * @param sourceMap the source map + * @param targetKeyType the key type in the target map + * @param targetElemType the elem type in the target map + * @param the key object type in the source map + * @param the elem object type in the source map + * @param the key object type in the target map + * @param the elem object type in the target map + * @return a copy of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + Map transform(Map sourceMap, Class targetKeyType, Class targetElemType); + + /** + * Copies all properties from a map to a new one applying the transformation function and mappings defined. + * @param sourceMap the source map + * @param beanTransformer the bean transformer to use for the map elements transformation + * @param targetKeyType the key type in the target map + * @param targetElemType the elem type in the target map + * @param the key object type in the source map + * @param the elem object type in the source map + * @param the key object type in the target map + * @param the elem object type in the target map + * @return a copy of the source object into the destination object + * @throws IllegalArgumentException if any parameter is invalid + */ + Map transform(Map sourceMap, BeanTransformer beanTransformer, Class targetKeyType, Class targetElemType); + /** * Initializes the transformer functions to apply on a Map key. The transformer function returns directly the field value. * @param keyFieldTransformer the fields transformer function diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index 6a77d2489..efe582ff0 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -19,6 +19,7 @@ import static java.util.Objects.nonNull; import static java.util.stream.Collectors.toMap; +import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import static com.hotels.transformer.validator.Validator.notNull; import java.util.HashMap; @@ -53,6 +54,22 @@ public Map transform(final Map sourceMap, final BeanTransform return res; } + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public Map transform(final Map sourceMap, final BeanTransformer beanTransformer, final Class targetKeyType, final Class targetElemType) { + notNull(sourceMap, "The map to copy cannot be null!"); + notNull(beanTransformer, "The bean transformer to use cannot be null!"); + Map keyFieldsTransformers = settings.getKeyFieldsTransformers(); + return (Map) sourceMap.entrySet().stream() + .collect(toMap( + e -> getTransformedObject(keyFieldsTransformers.get(e.getKey()), e.getKey(), beanTransformer, targetKeyType), + e -> getTransformedObject(settings.getFieldsTransformers().get(e.getKey()), getMapValue(e, sourceMap), beanTransformer, targetElemType) + )); + } + /** * Checks if a mapping has been defined between one key and the other. * In case a mapping exists, it returns the Map value for the new key. @@ -71,13 +88,32 @@ private K getMapValue(final Map.Entry entry, final Map source * Applies the {@link FieldTransformer} function (if any) to the given Map element value. * @param fieldTransformer the {@link FieldTransformer} function to apply * @param value the object on which the function has to be applied + * @param beanTransformer the bean transformer to use for the map elements transformation + * @param targetClass the destination object class + * @param the return class type * @return the transformed value */ - private Object getTransformedObject(final FieldTransformer fieldTransformer, final Object value) { - Object newValue = value; - if (nonNull(fieldTransformer)) { - newValue = fieldTransformer.getTransformedObject(value); + @SuppressWarnings("unchecked") + private K getTransformedObject(final FieldTransformer fieldTransformer, final Object value, + final BeanTransformer beanTransformer, final Class targetClass) { + K newValue; + if (Map.class.isAssignableFrom(value.getClass())) { + newValue = (K) transform((Map) value, beanTransformer); + } else { + newValue = (K) getPopulator(targetClass, value.getClass(), beanTransformer) + .map(populator -> populator.transform(value, targetClass)) + .orElseGet(() -> beanTransformer.transform(value, targetClass)); } - return newValue; + return (K) getTransformedObject(fieldTransformer, newValue); + } + + /** + * Applies the {@link FieldTransformer} function (if any) to the given Map element value. + * @param fieldTransformer the {@link FieldTransformer} function to apply + * @param value the object on which the function has to be applied + * @return the transformed value + */ + private Object getTransformedObject(final FieldTransformer fieldTransformer, final Object value) { + return nonNull(fieldTransformer) ? fieldTransformer.getTransformedObject(value) : value; } } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 41a684716..863b6c66d 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -16,6 +16,10 @@ package com.hotels.map.transformer; +import static java.math.BigInteger.ONE; +import static java.math.BigInteger.ZERO; +import static java.util.Collections.singletonList; + import static org.hamcrest.Matchers.both; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.everyItem; @@ -25,7 +29,9 @@ import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; +import java.math.BigInteger; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.mockito.InjectMocks; @@ -34,6 +40,8 @@ import org.testng.annotations.Test; import com.hotels.beans.BeanUtils; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.transformer.AbstractTransformerTest; import com.hotels.beans.transformer.BeanTransformer; import com.hotels.transformer.model.FieldMapping; @@ -43,6 +51,8 @@ */ public class MapTransformerTest extends AbstractTransformerTest { private static final BeanTransformer BEAN_TRANSFORMER = new BeanUtils().getTransformer(); + private static final String MAP_KEY_1 = "key1"; + private static final String MAP_KEY_2 = "key2"; /** * The class to be tested. @@ -103,7 +113,8 @@ public void testTransformWorksProperly(final String testCaseDescription, //THEN assertNotNull(actual); assertEquals(actual.size(), sourceMap.size()); - assertThat(actual.entrySet(), both(everyItem(isIn(sourceMap.entrySet()))).and(containsInAnyOrder(sourceMap.entrySet().toArray()))); + assertThat(actual.entrySet(), + both(everyItem(isIn(sourceMap.entrySet()))).and(containsInAnyOrder(sourceMap.entrySet().toArray()))); } /** @@ -126,19 +137,60 @@ private Object[][] dataMapTransformerObject() { @Test public void testTransformWorksProperlyWithKeyMapping() { //GIVEN - Map sourceMap = new HashMap<>(); - sourceMap.put("key1", 1); - sourceMap.put("key2", 2); - underTest.withFieldMapping(new FieldMapping<>("key1", "key2")); + Map sourceMap = new HashMap<>(); + sourceMap.put(MAP_KEY_1, ZERO); + sourceMap.put(MAP_KEY_2, ONE); + underTest.withFieldMapping(new FieldMapping<>(MAP_KEY_1, MAP_KEY_2)); //WHEN - Map actual = underTest.transform(sourceMap); + Map actual = underTest.transform(sourceMap); //THEN assertNotNull(actual); assertEquals(actual.size(), sourceMap.size()); - assertEquals(actual.get("key1"), sourceMap.get("key1")); - assertEquals(actual.get("key2"), sourceMap.get("key1")); + assertEquals(actual.get(MAP_KEY_1), sourceMap.get(MAP_KEY_1)); + assertEquals(actual.get(MAP_KEY_2), sourceMap.get(MAP_KEY_1)); underTest.resetFieldsMapping(); } + + /** + * Test that the given map is correctly transformed and the elements are correctly transformed. + */ + @Test + public void testTransformWorksProperlyWithTargetKeyAndElemType() { + //GIVEN + + //WHEN + Map actual = underTest.transform(EXTREME_COMPLEX_MAP, MutableToFooSimple.class, Map.class); + + //THEN + assertNotNull(actual); + assertEquals(actual.size(), EXTREME_COMPLEX_MAP.size()); + // check that the element has been converted + for (Map.Entry entry : actual.entrySet()) { + assertEquals(MutableToFooSimple.class, entry.getKey().getClass()); + } + } + + /** + * Test that the given map is correctly transformed and the elements are correctly transformed if the Map contains a List. + */ + @Test + public void testTransformWorksProperlyWithMapContainingList() { + //GIVEN + List sampleList = singletonList(ITEM_1); + Map> sourceMap = new HashMap<>(); + sourceMap.put(fromFooSimple, sampleList); + + //WHEN + Map actual = underTest.transform(sourceMap, MutableToFooSimple.class, List.class); + + //THEN + assertNotNull(actual); + assertEquals(actual.size(), sourceMap.size()); + for (Map.Entry entry : actual.entrySet()) { + assertEquals(MutableToFooSimple.class, entry.getKey().getClass()); + assertEquals(sampleList, entry.getValue()); + } + } } From dd427ae5e1528e7024609387b04df85da08c4588 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Oct 2019 21:08:41 +0200 Subject: [PATCH 0834/1786] Replaced slack link invitation with a not expired one --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa1d23e16..e55a6be25 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) -[![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWQxOWZiYjAwOThlY2FmNjYxZDY1ZDNlZTdlNTZlY2Y2YmE0MjcxMzNjZjNjOTY3OWJkNzdmM2ViNmQ2NjUyNDE) +[![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) From 03e1dba2f6bab411fe05073cbd9ddec31fb364ec Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 21 Oct 2019 14:54:32 +0200 Subject: [PATCH 0835/1786] Removed duplicated code --- .../map/transformer/MapTransformerImpl.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index efe582ff0..77549bfdc 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -38,8 +38,7 @@ public class MapTransformerImpl extends AbstractMapTransformer { @Override @SuppressWarnings("unchecked") public Map transform(final Map sourceMap, final BeanTransformer beanTransformer) { - notNull(sourceMap, "The map to copy cannot be null!"); - notNull(beanTransformer, "The bean transformer to use cannot be null!"); + validateParameters(sourceMap, beanTransformer); Map keyFieldsTransformers = settings.getKeyFieldsTransformers(); Map res; if (settings.getFieldsNameMapping().isEmpty() && keyFieldsTransformers.isEmpty()) { @@ -60,8 +59,7 @@ public Map transform(final Map sourceMap, final BeanTransform @Override @SuppressWarnings("unchecked") public Map transform(final Map sourceMap, final BeanTransformer beanTransformer, final Class targetKeyType, final Class targetElemType) { - notNull(sourceMap, "The map to copy cannot be null!"); - notNull(beanTransformer, "The bean transformer to use cannot be null!"); + validateParameters(sourceMap, beanTransformer); Map keyFieldsTransformers = settings.getKeyFieldsTransformers(); return (Map) sourceMap.entrySet().stream() .collect(toMap( @@ -70,6 +68,18 @@ public Map transform(final Map sourceMap, final BeanTra )); } + /** + * Checks that the input parameter are valid. + * @param sourceMap the Map to transform + * @param beanTransformer the {@link BeanTransformer} instance + * @param the key object type in the source map + * @param the elem object type in the source map + */ + private void validateParameters(final Map sourceMap, final BeanTransformer beanTransformer) { + notNull(sourceMap, "The map to copy cannot be null!"); + notNull(beanTransformer, "The bean transformer to use cannot be null!"); + } + /** * Checks if a mapping has been defined between one key and the other. * In case a mapping exists, it returns the Map value for the new key. From 67d6a90b1f2f9ce1b9affbbd8aca8e996814c5ad Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 22 Oct 2019 19:07:11 +0200 Subject: [PATCH 0836/1786] - Added specific exception in case the transformation function is not valid - Implemented additional UT --- .../transformer/BeanTransformerTest.java | 2 - .../ImmutableObjectTransformationTest.java | 28 +++++++- .../error/InvalidFunctionException.java | 34 ++++++++++ .../transformer/model/FieldTransformer.java | 9 ++- .../transformer/AbstractTransformerTest.java | 3 + .../transformer/AbstractMapTransformer.java | 9 +++ .../map/transformer/MapTransformer.java | 5 ++ .../map/transformer/MapTransformerImpl.java | 8 ++- .../map/transformer/MapTransformerTest.java | 66 +++++++++++++++++++ 9 files changed, 157 insertions(+), 7 deletions(-) create mode 100644 bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 553aa074f..1b0bfc36c 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -59,10 +59,8 @@ public class BeanTransformerTest extends AbstractBeanTransformerTest { private static final String SOURCE_FIELD_NAME = "sourceFieldName"; private static final String SOURCE_FIELD_NAME_2 = "sourceFieldName2"; - private static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; private static final String GET_SOURCE_FIELD_VALUE_METHOD_NAME = "getSourceFieldValue"; private static final String GET_SOURCE_FIELD_TYPE_METHOD_NAME = "getSourceFieldType"; - private static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); private static final String CACHE_MANAGER_FIELD_NAME = "cacheManager"; private static final String REFLECTION_UTILS_FIELD_NAME = "reflectionUtils"; private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 95a996d65..47757b213 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -63,6 +63,7 @@ import com.hotels.transformer.annotation.ConstructorArg; import com.hotels.transformer.cache.CacheManager; import com.hotels.transformer.error.InvalidBeanException; +import com.hotels.transformer.error.InvalidFunctionException; import com.hotels.transformer.model.FieldMapping; import com.hotels.transformer.model.FieldTransformer; import com.hotels.transformer.utils.ReflectionUtils; @@ -79,9 +80,13 @@ public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTe private static final String GROSS_PRICE_FIELD_NAME = "price.grossPrice"; private static final boolean ACTIVE = true; + /** + * After method actions. + */ @AfterMethod public void afterMethod() { underTest.setValidationEnabled(false); + underTest.resetFieldsTransformer(); } /** @@ -286,9 +291,9 @@ public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String te //WHEN final BeanTransformer beanTransformer = underTest - .withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)) - .withFieldMapping(new FieldMapping(PRICE_FIELD_NAME, NET_PRICE_FIELD_NAME)) - .withFieldMapping(new FieldMapping(PRICE_FIELD_NAME, GROSS_PRICE_FIELD_NAME)) + .withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)) + .withFieldMapping(new FieldMapping<>(PRICE_FIELD_NAME, NET_PRICE_FIELD_NAME)) + .withFieldMapping(new FieldMapping<>(PRICE_FIELD_NAME, GROSS_PRICE_FIELD_NAME)) .withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); ImmutableToFooAdvFields actual = (ImmutableToFooAdvFields) beanTransformer.transform(sourceObject, targetObjectClass); @@ -494,6 +499,23 @@ public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { underTest.resetFieldsTransformer(); } + /** + * Test that an {@link InvalidFunctionException} is raised if the transformer function defined is not valid. + */ + @Test(expectedExceptions = InvalidFunctionException.class) + public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { + //GIVEN + FromFooSimpleBooleanField fromFooSimpleNullFields = new FromFooSimpleBooleanField(); + FieldTransformer upperCase = + new FieldTransformer<>("work", String::toUpperCase); + + //WHEN + ImmutableToFooSimpleBoolean actual = underTest + .withFieldTransformer(upperCase) + .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); + + } + /** * Initializes the mocks required for testing method: {@code getDestFieldName}. * @param declaringClassName the declaring class name diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java b/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java new file mode 100644 index 000000000..a3fc6a6c9 --- /dev/null +++ b/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.transformer.error; + +/** + * Invalid transformation function exception. + */ +public class InvalidFunctionException extends RuntimeException { + /** + * Constructs a new invalid function transformer exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * @param message the detail message. The detail message is saved for later + * retrieval by the {@link #getMessage()} method. + * @param cause the given transformation function is not valid for the given object. + */ + public InvalidFunctionException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java index 92dcda4d1..831760c88 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java @@ -23,6 +23,8 @@ import java.util.function.Function; import java.util.function.Supplier; +import com.hotels.transformer.error.InvalidFunctionException; + import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; @@ -74,8 +76,13 @@ public FieldTransformer(final String destinationFieldName, final Supplier fie * Returns a transformed object by applying the defined transformed function or the supplier. * @param objectToTransform the object to transform * @return the transformed object + * @throws InvalidFunctionException if the defined function cannot be applied to the given type */ public final K getTransformedObject(final T objectToTransform) { - return nonNull(transformerFunction) ? transformerFunction.apply(objectToTransform) : transformerSupplier.get(); + try { + return nonNull(transformerFunction) ? transformerFunction.apply(objectToTransform) : transformerSupplier.get(); + } catch (final Exception e) { + throw new InvalidFunctionException("The transformer function defined for the field is not valid.", e); + } } } diff --git a/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java index ab26f94bc..b1120a376 100644 --- a/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/beans/transformer/AbstractTransformerTest.java @@ -37,6 +37,7 @@ import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.FromFooWithPrimitiveFields; import com.hotels.beans.sample.FromSubFoo; +import com.hotels.transformer.utils.ReflectionUtils; /** * Unit test for {@link com.hotels.transformer.Transformer}. @@ -68,6 +69,8 @@ public abstract class AbstractTransformerTest { protected static final Map> COMPLEX_MAP = new HashMap<>(); protected static final Map> VERY_COMPLEX_MAP = new HashMap<>(); protected static final Map> EXTREME_COMPLEX_MAP = new HashMap<>(); + protected static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; + protected static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); protected static final String ITEM_1 = "donald"; private static final String ITEM_2 = "duck"; private static final String SURNAME = "surname"; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index 369ea5179..96196bb7f 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -67,4 +67,13 @@ public MapTransformer withKeyTransformer(final FieldTransformer... keyFieldTrans } return this; } + + /** + * {@inheritDoc} + */ + @Override + public final void resetKeyTransformer() { + settings.getKeyFieldsTransformers().clear(); + cacheManager.removeMatchingKeys(transformerFunctionRegex); + } } diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index 8cdd99a91..7b725be1a 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -83,4 +83,9 @@ public interface MapTransformer extends Transformer { * @return the {@link Transformer} instance */ MapTransformer withKeyTransformer(FieldTransformer... keyFieldTransformer); + + /** + * Removes all the configured key transformer. + */ + void resetKeyTransformer(); } diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index 77549bfdc..091e73393 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -26,6 +26,7 @@ import java.util.Map; import com.hotels.beans.transformer.BeanTransformer; +import com.hotels.transformer.error.InvalidFunctionException; import com.hotels.transformer.model.FieldTransformer; /** @@ -122,8 +123,13 @@ private K getTransformedObject(final FieldTransformer fieldT * @param fieldTransformer the {@link FieldTransformer} function to apply * @param value the object on which the function has to be applied * @return the transformed value + * @throws InvalidFunctionException if the defined function is not valid */ private Object getTransformedObject(final FieldTransformer fieldTransformer, final Object value) { - return nonNull(fieldTransformer) ? fieldTransformer.getTransformedObject(value) : value; + try { + return nonNull(fieldTransformer) ? fieldTransformer.getTransformedObject(value) : value; + } catch (final Exception e) { + throw new InvalidFunctionException("The transformer function defined for the map key is not valid.", e); + } } } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 863b6c66d..8fc237712 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigInteger; @@ -35,6 +36,7 @@ import java.util.Map; import org.mockito.InjectMocks; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -44,7 +46,11 @@ import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.beans.transformer.AbstractTransformerTest; import com.hotels.beans.transformer.BeanTransformer; +import com.hotels.map.transformer.model.MapTransformerSettings; +import com.hotels.transformer.error.InvalidFunctionException; import com.hotels.transformer.model.FieldMapping; +import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.model.TransformerSettings; /** * Unit test for {@link MapTransformer}. @@ -69,6 +75,14 @@ public void beforeClass() { initObjects(); } + /** + * After method actions. + */ + @AfterMethod + public void afterMethod() { + underTest.resetKeyTransformer(); + } + /** * Test that the method {@code transform} raises an {@link IllegalArgumentException} if any parameter is null. * @param testCaseDescription the test case description @@ -153,6 +167,40 @@ public void testTransformWorksProperlyWithKeyMapping() { underTest.resetFieldsMapping(); } + /** + * Test that the given map is correctly transformed if key transformers are defined. + */ + @Test + public void testTransformWorksProperlyWithTransformer() { + //GIVEN + Map sourceMap = new HashMap<>(); + sourceMap.put(MAP_KEY_1, ZERO); + sourceMap.put(MAP_KEY_2, ONE); + underTest.withKeyTransformer(new FieldTransformer(MAP_KEY_1, String::toUpperCase)); + + //WHEN + Map actual = underTest.transform(sourceMap); + + //THEN + assertNotNull(actual); + assertEquals(actual.size(), sourceMap.size()); + assertTrue(actual.containsKey(MAP_KEY_1.toUpperCase())); + } + + /** + * Test that an {@link InvalidFunctionException} is raised if the transformer function defined is not valid. + */ + @Test(expectedExceptions = InvalidFunctionException.class) + public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { + //GIVEN + Map sourceMap = new HashMap<>(); + sourceMap.put(MAP_KEY_1, ZERO); + underTest.withKeyTransformer(new FieldTransformer<>(MAP_KEY_1, ONE::add)); + + //WHEN + underTest.transform(sourceMap); + } + /** * Test that the given map is correctly transformed and the elements are correctly transformed. */ @@ -193,4 +241,22 @@ public void testTransformWorksProperlyWithMapContainingList() { assertEquals(sampleList, entry.getValue()); } } + + /** + * Test that is possible to remove all the key transformer defined. + */ + @Test + public void testResetKeyTransformerWorksProperly() { + //GIVEN + underTest.withKeyTransformer(new FieldTransformer(MAP_KEY_1, String::toUpperCase)); + + //WHEN + underTest.resetKeyTransformer(); + MapTransformerSettings transformerSettings = + (MapTransformerSettings) REFLECTION_UTILS.getFieldValue(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); + + //THEN + assertTrue(transformerSettings.getKeyFieldsTransformers().isEmpty()); + underTest.resetKeyTransformer(); + } } From d9c929791cb1c647f0cb492cbca8ca202fa18aec Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Oct 2019 11:55:01 +0200 Subject: [PATCH 0837/1786] - Added generics tag where missing - Modified jacoco and sonar configuration in order to don't process model and constant classes --- README.md | 10 +++++----- .../transformer/AbstractBeanTransformerTest.java | 2 ++ .../ImmutableObjectTransformationTest.java | 11 ++++++----- .../transformer/MixedObjectTransformationTest.java | 4 ++-- .../hotels/transformer/AbstractTransformer.java | 2 +- .../test/java/com/hotels/beans/package-info.java | 2 +- .../transformer/AbstractTransformerTest.java | 2 +- .../{beans => }/transformer/package-info.java | 2 +- .../hotels/map/transformer/MapTransformerTest.java | 4 +++- docs/site/markdown/transformer/samples.md | 10 +++++----- pom.xml | 14 +++++++++----- 11 files changed, 36 insertions(+), 27 deletions(-) rename bull-common/src/test/java/com/hotels/{beans => }/transformer/AbstractTransformerTest.java (99%) rename bull-common/src/test/java/com/hotels/{beans => }/transformer/package-info.java (94%) diff --git a/README.md b/README.md index fa1d23e16..2dddd1780 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ public class FromBean { public class ToBean And one line code as: ~~~Java -beanUtils.getTransformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); +beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class); ~~~ ### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: @@ -168,8 +168,8 @@ public class FromBean { public class ToBean ~~~ the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: ~~~Java -FieldMapping serialNumberMapping = new FieldMapping("subObject.serialNumber", "serialNumber"); -FieldMapping creationDateMapping = new FieldMapping("subObject.creationDate", "creationDate"); +FieldMapping serialNumberMapping = new FieldMapping<>("subObject.serialNumber", "serialNumber"); +FieldMapping creationDateMapping = new FieldMapping<>("subObject.creationDate", "creationDate"); beanUtils.getTransformer() .withFieldMapping(serialNumberMapping, creationDateMapping) @@ -231,7 +231,7 @@ public class FromBean { public class ToBean FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); FieldTransformer localeTransformer = new FieldTransformer<>("locale", Locale::forLanguageTag); beanUtils.getTransformer() - .withFieldMapping(new FieldMapping("id", "identifier")) + .withFieldMapping(new FieldMapping<>("id", "identifier")) .withFieldTransformer(fieldTransformer).transform(fromBean, ToBean.class) .withFieldTransformer(localeTransformer); ~~~ @@ -366,7 +366,7 @@ Assuming that the value `x` should be mapped into field: `x` contained into the follow: ~~~Java ToBean toBean = beanUtils.getTransformer() - .withFieldMapping(new FieldMapping("x", "nestedObject.x")); + .withFieldMapping(new FieldMapping<>("x", "nestedObject.x")); ~~~ ### Apply a transformation function on all fields matching with the given one: diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index 58f2daaa9..d3d175898 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -22,6 +22,8 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; +import com.hotels.transformer.AbstractTransformerTest; + /** * Unit test for {@link BeanTransformer}. */ diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 47757b213..89710218b 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -60,6 +60,7 @@ import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; +import com.hotels.transformer.AbstractTransformerTest; import com.hotels.transformer.annotation.ConstructorArg; import com.hotels.transformer.cache.CacheManager; import com.hotels.transformer.error.InvalidBeanException; @@ -78,6 +79,7 @@ public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTe private static final String PRICE_FIELD_NAME = "price"; private static final String NET_PRICE_FIELD_NAME = "price.netPrice"; private static final String GROSS_PRICE_FIELD_NAME = "price.grossPrice"; + private static final String WORK_FIELD_NAME = "work"; private static final boolean ACTIVE = true; /** @@ -265,7 +267,7 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); + final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); //THEN @@ -487,7 +489,7 @@ public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { //GIVEN FromFooSimpleBooleanField fromFooSimpleNullFields = new FromFooSimpleBooleanField(); FieldTransformer nullToTrue = - new FieldTransformer<>("work", aBoolean -> aBoolean == null || aBoolean); + new FieldTransformer<>(WORK_FIELD_NAME, aBoolean -> aBoolean == null || aBoolean); //WHEN ImmutableToFooSimpleBoolean actual = underTest @@ -507,11 +509,10 @@ public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { //GIVEN FromFooSimpleBooleanField fromFooSimpleNullFields = new FromFooSimpleBooleanField(); FieldTransformer upperCase = - new FieldTransformer<>("work", String::toUpperCase); + new FieldTransformer<>(WORK_FIELD_NAME, String::toUpperCase); //WHEN - ImmutableToFooSimpleBoolean actual = underTest - .withFieldTransformer(upperCase) + underTest.withFieldTransformer(upperCase) .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index fdc4ebfe4..6385ac4a5 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -81,7 +81,7 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); + final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); //THEN @@ -106,7 +106,7 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTra FieldTransformer fieldTransformer = new FieldTransformer<>(IDENTIFIER_FIELD_NAME, BigInteger::negate); //WHEN - underTest.withFieldMapping(new FieldMapping(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)).withFieldTransformer(fieldTransformer); + underTest.withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)).withFieldTransformer(fieldTransformer); MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); //THEN diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java index 7e05093bd..ecfff4be6 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -69,7 +69,7 @@ public abstract class AbstractTransformer the key type + * @param the element type */ @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformMethodWithTwoArgument") public void testTransformRaisesExceptionIfItsCalledWithNullParameter(final String testCaseDescription, diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/samples.md index 61f3bb29c..870790e12 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/samples.md @@ -57,7 +57,7 @@ public class FromBean { public class ToBean And one line code as: ~~~Java -beanUtils.getTransformer().withFieldMapping(new FieldMapping("name", "differentName")).transform(fromBean, ToBean.class); +beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class); ~~~ ### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: @@ -89,8 +89,8 @@ public class FromBean { public class ToBean ~~~ the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: ~~~Java -FieldMapping serialNumberMapping = new FieldMapping("subObject.serialNumber", "serialNumber"); -FieldMapping creationDateMapping = new FieldMapping("subObject.creationDate", "creationDate"); +FieldMapping serialNumberMapping = new FieldMapping<>("subObject.serialNumber", "serialNumber"); +FieldMapping creationDateMapping = new FieldMapping<>("subObject.creationDate", "creationDate"); beanUtils.getTransformer() .withFieldMapping(serialNumberMapping, creationDateMapping) @@ -152,7 +152,7 @@ public class FromBean { public class ToBean FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); FieldTransformer localeTransformer = new FieldTransformer<>("locale", Locale::forLanguageTag); beanUtils.getTransformer() - .withFieldMapping(new FieldMapping("id", "identifier")) + .withFieldMapping(new FieldMapping<>("id", "identifier")) .withFieldTransformer(fieldTransformer).transform(fromBean, ToBean.class) .withFieldTransformer(localeTransformer); ~~~ @@ -287,7 +287,7 @@ Assuming that the value `x` should be mapped into field: `x` contained into the follow: ~~~Java ToBean toBean = beanUtils.getTransformer() - .withFieldMapping(new FieldMapping("x", "nestedObject.x")); + .withFieldMapping(new FieldMapping<>("x", "nestedObject.x")); ~~~ ### Apply a transformation function on all fields matching with the given one: diff --git a/pom.xml b/pom.xml index 46b5b0d68..070119999 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ 1.7.28 3.0.0 2.2.6 - + 0.8.3 1.0 0.90 @@ -53,6 +53,7 @@ 0.85 0.88 0.90 + **/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* 3.3.3 0.12 @@ -418,16 +419,19 @@ ${jacoco.check.skip} + com/hotels/transformer/** com/hotels/beans/** + com/hotels/map/** **/Test*.* **/*Test.* **/*Application.* - com/hotels/beans/model/** - com/hotels/beans/constant/** - com/hotels/beans/error/** - com/hotels/beans/annotation/** + com/hotels/transformer/AbstractTransformer.* + **/model/** + **/constant/** + **/error/** + **/annotation/** From f44e213e5314d91d76cb65ccb38bf2ed0292316c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Oct 2019 17:36:02 +0200 Subject: [PATCH 0838/1786] Updated changelog --- CHANGELOG-JDK8.md | 3 +++ CHANGELOG.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 4709287f9..76a6ba7e8 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -9,6 +9,9 @@ All notable changes to this project will be documented in this file. * `com.hotels.beans.model.FieldMapping` * `com.hotels.beans.model.FieldTransformer` * `com.hotels.beans.Transformer` +### Added +* New specific exception in case the Field Transformation function defined is not valid +* Implemented a new functionality that allows to transform also Map object applying transformation function and mappings ### [1.1.24] 2019.09.02 #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d52236f0..b390eddcf 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ All notable changes to this project will be documented in this file. * `com.hotels.beans.model.FieldMapping` * `com.hotels.beans.model.FieldTransformer` * `com.hotels.beans.Transformer` +### Added +* New specific exception in case the Field Transformation function defined is not valid +* Implemented a new functionality that allows to transform also Map object applying transformation function and mappings ### [1.5.1] 2019.09.02 #### Changed From 6fc655469342ff535f0c6fde027ddb2d7a237e87 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Oct 2019 17:05:32 +0200 Subject: [PATCH 0839/1786] Providing documentation for Map transformer functionalities --- README.md | 25 +++++++-- .../transformer/{ => bean}/performance.md | 0 .../transformer/{ => bean}/samples.md | 2 +- .../transformer/{ => bean}/testing.md | 0 .../{ => bean}/thirdPartyLibComparison.md | 0 .../markdown/transformer/beanTransformer.md | 8 +++ docs/site/markdown/transformer/map/samples.md | 52 +++++++++++++++++++ .../markdown/transformer/mapTransformer.md | 22 ++++++++ docs/site/site.xml | 17 +++--- 9 files changed, 115 insertions(+), 11 deletions(-) rename docs/site/markdown/transformer/{ => bean}/performance.md (100%) rename docs/site/markdown/transformer/{ => bean}/samples.md (99%) rename docs/site/markdown/transformer/{ => bean}/testing.md (100%) rename docs/site/markdown/transformer/{ => bean}/thirdPartyLibComparison.md (100%) create mode 100644 docs/site/markdown/transformer/beanTransformer.md create mode 100644 docs/site/markdown/transformer/map/samples.md create mode 100644 docs/site/markdown/transformer/mapTransformer.md diff --git a/README.md b/README.md index 2dddd1780..5526c8d18 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,9 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) -You can obtain BULL from Maven Central: +All BULL modules are available on Maven Central: + +* ### Bean Transformer ~~~ @@ -29,6 +31,16 @@ You can obtain BULL from Maven Central: ~~~ +* ### `Map` Transformer + +~~~ + + com.hotels.beans + bull-map-transformer + x.y.z + +~~~ + **The project provides two different builds**, one compatible with `jdk 8` (or above) and one with `jdk 11` or above. In case you need to integrate it in a `jdk 8` (or above project) please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) file or to [CHANGELOG](CHANGELOG.md) otherwise. @@ -77,11 +89,12 @@ mvnw.cmd clean install -P relaxed # Feature samples -* [Transformation](https://github.com/HotelsDotCom/bull#transformation-samples) -* [Validation](https://github.com/HotelsDotCom/bull#validation-samples) +* [Bean Transformation](https://github.com/HotelsDotCom/bull#transformation-samples) +* [Bean Validation](https://github.com/HotelsDotCom/bull#validation-samples) * [Primitive Type conversion](https://github.com/HotelsDotCom/bull#primitive-type-object-converter) +* [Map Transformation](https://hotelsdotcom.github.io/bull/transformer/map/samples.html) -## Transformation samples +## Bean transformation samples ### Simple case: @@ -752,6 +765,10 @@ byte converted = conversionFunction.map(processor -> processor.apply(c)).orElse( * in case the conversion is not needed as the primitive type and the destination type are the same it will return an empty `Optional` * in case the conversion function is unavailable or no not possible the method throws a : `TypeConversionException` +## `Map` transformation samples + +Samples on how to transform a `Map` and all others function applicable on it can be viewed [here](https://hotelsdotcom.github.io/bull/transformer/mapTransformer.html) + ## Documentation A detailed project documentation is available [here](https://hotelsdotcom.github.io/bull), including some samples for [testing the library](https://hotelsdotcom.github.io/bull/transformer/testing.html) inside your project. diff --git a/docs/site/markdown/transformer/performance.md b/docs/site/markdown/transformer/bean/performance.md similarity index 100% rename from docs/site/markdown/transformer/performance.md rename to docs/site/markdown/transformer/bean/performance.md diff --git a/docs/site/markdown/transformer/samples.md b/docs/site/markdown/transformer/bean/samples.md similarity index 99% rename from docs/site/markdown/transformer/samples.md rename to docs/site/markdown/transformer/bean/samples.md index 870790e12..6842f5e67 100644 --- a/docs/site/markdown/transformer/samples.md +++ b/docs/site/markdown/transformer/bean/samples.md @@ -2,7 +2,7 @@ Samples -# Transformation samples +# Bean Transformation samples ### Simple case: diff --git a/docs/site/markdown/transformer/testing.md b/docs/site/markdown/transformer/bean/testing.md similarity index 100% rename from docs/site/markdown/transformer/testing.md rename to docs/site/markdown/transformer/bean/testing.md diff --git a/docs/site/markdown/transformer/thirdPartyLibComparison.md b/docs/site/markdown/transformer/bean/thirdPartyLibComparison.md similarity index 100% rename from docs/site/markdown/transformer/thirdPartyLibComparison.md rename to docs/site/markdown/transformer/bean/thirdPartyLibComparison.md diff --git a/docs/site/markdown/transformer/beanTransformer.md b/docs/site/markdown/transformer/beanTransformer.md new file mode 100644 index 000000000..f1d626021 --- /dev/null +++ b/docs/site/markdown/transformer/beanTransformer.md @@ -0,0 +1,8 @@ + + Bean Transformer + + +# Bean Transformer + +is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. +It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. diff --git a/docs/site/markdown/transformer/map/samples.md b/docs/site/markdown/transformer/map/samples.md new file mode 100644 index 000000000..f19011d89 --- /dev/null +++ b/docs/site/markdown/transformer/map/samples.md @@ -0,0 +1,52 @@ + + Samples + + +# `Map` Transformation samples + +### `Map` clone: + +Given a simple `Map` defined as follow: + +~~~Java +Map> map = new HashMap<>(); +map.put("key", List.of("value1", "value2")); +~~~ + +it can be cloned using the following command: + +~~~Java +Map> newMap = new MapUtils().getTransformer().transform(map); +~~~ + +### Map a `Key` value into a different `Key` in the destination `Map`: + +Given a simple `Map` defined as follow: + +~~~Java +Map map = new HashMap<>(); +map.put("key1", "Hello"); +map.put("key2", "Dude"); +~~~ + +And assuming that we want that the `key2` value, in the destination map, has to be the `key1` one, +the only thing we need to do is to define the field mapping: + +~~~Java +FieldMapping keyMapping = new FieldMapping<>("key1", "key2"); +Map> newMap = new MapUtils().getTransformer() + .withFieldMapping(keyMapping) + .transform(map); +~~~ + +Then if we run the following command: + +~~~Java +System.out.println(newMap.get("key2")); +~~~ + +the output will be: + +~~~Java +Hello +~~~ diff --git a/docs/site/markdown/transformer/mapTransformer.md b/docs/site/markdown/transformer/mapTransformer.md new file mode 100644 index 000000000..59e8dc47a --- /dev/null +++ b/docs/site/markdown/transformer/mapTransformer.md @@ -0,0 +1,22 @@ + + Map Transformer + + +# Map Transformer + +is a Map to Map transformer that recursively copies data from one object to another giving the possibility to: + +* Apply transformation functions on key and/or elements of a Map. +* Map the source Map keys to a different place in the destination Map. + +You can obtain BULL from Maven Central: + +## Start using + +~~~ + + com.hotels.beans + bull-map-transformer + x.y.z + +~~~ \ No newline at end of file diff --git a/docs/site/site.xml b/docs/site/site.xml index 5de67f369..71537e1b9 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -5,7 +5,7 @@ org.apache.maven.skins maven-fluido-skin - 1.7 + 1.8 @@ -37,11 +37,16 @@ - - - - - + + + + + + + + + + From e44b77d16a8877be932efb8d9b35a4b7f28d6052 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 25 Oct 2019 17:37:27 +0200 Subject: [PATCH 0840/1786] Added documentation for the Map Key transformation --- docs/site/markdown/transformer/map/samples.md | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/docs/site/markdown/transformer/map/samples.md b/docs/site/markdown/transformer/map/samples.md index f19011d89..df3b980d2 100644 --- a/docs/site/markdown/transformer/map/samples.md +++ b/docs/site/markdown/transformer/map/samples.md @@ -50,3 +50,57 @@ the output will be: ~~~Java Hello ~~~ + +### Apply a transformation function on a `Map` key: + +Given a simple `Map` defined as follow: + +~~~Java +Map map = new HashMap<>(); +map.put("name", "John"); +map.put("surname", "Smith"); +~~~ + +And assuming that we want that the `name` correspondent key is made upper case, +the only thing we need to do is to apply a `FieldTransformer` to the `key` defined as following: + +~~~Java +FieldTransformer keyTransformer = new FieldTransformer<>("name", String::toUpperCase); +Map> newMap = new MapUtils().getTransformer() + .withKeyTransformer(keyTransformer) + .transform(map); +~~~ + +Then the key: "name" in the `newMap`will be: `NAME` + +### Apply a transformation function on a `Map` value: + +Given a simple `Map` defined as follow: + +~~~Java +Map map = new HashMap<>(); +map.put("key1", 30); +map.put("key2", 200); +~~~ + +And assuming that we want that the `key1` correspondent value is raised to the power of 2, +the only thing we need to do is to define a `FieldTransformer` as following: + +~~~Java +FieldTransformer keyPow = new FieldTransformer<>("key1", val -> Math.pow(val, 2)); +Map> newMap = new MapUtils().getTransformer() + .withFieldTransformer(keyPow) + .transform(map); +~~~ + +Then if we run the following command: + +~~~Java +System.out.println(newMap.get("key1")); +~~~ + +the output will be: + +~~~Java +900 +~~~ From b3366f9a19cb40e7fef2e93756c1d0d03567c07a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 27 Oct 2019 12:26:48 +0100 Subject: [PATCH 0841/1786] [travis skip] Added title of missing documentation --- docs/site/markdown/transformer/map/samples.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/site/markdown/transformer/map/samples.md b/docs/site/markdown/transformer/map/samples.md index df3b980d2..998f52f99 100644 --- a/docs/site/markdown/transformer/map/samples.md +++ b/docs/site/markdown/transformer/map/samples.md @@ -104,3 +104,5 @@ the output will be: ~~~Java 900 ~~~ + +### Transform `Map` `key` or `value` object into a different object From f2c2b35bd6ed1665b669c3824d7621fef460068a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2019 02:25:38 +0000 Subject: [PATCH 0842/1786] Bump hibernate-validator from 6.0.17.Final to 6.1.0.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.0.17.Final to 6.1.0.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/master/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.0.17.Final...6.1.0.Final) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5dd0e17c2..1a30effdd 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ 3.1.0 2.0.1.Final - 6.0.17.Final + 6.1.0.Final 1.7.28 3.0.0 2.2.6 From c59878bff335b39df3e96d021d6d08a1603511e7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Oct 2019 05:30:47 +0100 Subject: [PATCH 0843/1786] Completed Map documentation --- README.md | 13 ++- .../site/markdown/transformer/bean/samples.md | 12 +-- docs/site/markdown/transformer/map/samples.md | 91 +++++++++++++++++++ 3 files changed, 103 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 5526c8d18..1d7e2bacb 100644 --- a/README.md +++ b/README.md @@ -104,13 +104,12 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final List subBeanList; private final String name; private List list; private final List list; - private final FromSubBean subObject; private final List nestedObjectList; - private ImmutableToSubFoo nestedObject; + private final FromSubBean subObject; private final List subBeanList; + private ImmutableToSubFoo subObject; // all constructors // all args constructor - // getters and setters... // getters... -} - } + // getters and setters... // getters and setters... +} ~~~ And one line code as: ~~~Java @@ -129,7 +128,7 @@ public class FromBean { public class ToBean private final List list; private final List list; private final FromSubBean subObject; private final ToSubBean subObject; - // getters and setters... + // getters... public ToBean(final String differentName, final int id, } final List subBeanList, @@ -142,7 +141,7 @@ public class FromBean { public class ToBean this.subObject = subObject; } - // getters and setters... + // getters... } ~~~ diff --git a/docs/site/markdown/transformer/bean/samples.md b/docs/site/markdown/transformer/bean/samples.md index 6842f5e67..a836d0997 100644 --- a/docs/site/markdown/transformer/bean/samples.md +++ b/docs/site/markdown/transformer/bean/samples.md @@ -12,11 +12,11 @@ public class FromBean { public class ToBean private final BigInteger id; public BigInteger id; private final List subBeanList; private final String name; private List list; private final List list; - private final FromSubBean subObject; private final List nestedObjectList; - private ImmutableToSubFoo nestedObject; + private final FromSubBean subObject; private final List subBeanList; + private ImmutableToSubFoo subObject; // all constructors // all args constructor - // getters and setters... // getters... + // getters and setters... // getters and setters... } } ~~~ @@ -37,7 +37,7 @@ public class FromBean { public class ToBean private final List list; private final List list; private final FromSubBean subObject; private final ToSubBean subObject; - // getters and setters... + // getters... public ToBean(final String differentName, final int id, } final List subBeanList, @@ -50,14 +50,14 @@ public class FromBean { public class ToBean this.subObject = subObject; } - // getters and setters... + // getters... } ~~~ And one line code as: ~~~Java -beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class); +beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class);` ~~~ ### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: diff --git a/docs/site/markdown/transformer/map/samples.md b/docs/site/markdown/transformer/map/samples.md index 998f52f99..6726211c2 100644 --- a/docs/site/markdown/transformer/map/samples.md +++ b/docs/site/markdown/transformer/map/samples.md @@ -106,3 +106,94 @@ the output will be: ~~~ ### Transform `Map` `key` or `value` object into a different object + +Assuming that we have a map defined as follow: + +~~~Java +Map sourceMap = new HashMap<>(); +~~~ + +and we want to transform it in: + +~~~Java +Map map = new HashMap<>(); +~~~ + +where `FromBean` and `ToBean` are: + +~~~Java +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List subBeanList; + private ToSubBean subObject; + + // all constructors // all args constructor + // getters and setters... // getters and setters... +} +~~~ + +and `FromSubBean` and `ToSubBean` are: + +~~~Java +public class FromBean { public class ToBean { + private final String index; private final String index; + + // all constructor // all args constructor + // getters... // getters... +} +~~~ + +what we need to do is to specify the Map `Key` and `Element` class in the destination Map. + +In our case it will be: + +~~~Java +Map map = new MapUtils().getTransformer() + .transform(sourceMap, ToBean.class, ToSubBean.class); +~~~ + +### Configure a `BeanTransformer` and use it fo the `Map` transformation + +Assuming that we have two classes with different field names defined as follow: + +~~~Java +public class FromBean { public class ToBean { + + private final String name; private final String differentName; + private final int id; private final int id; + private final List subBeanList; private final List subBeanList; + private final List list; private final List list; + private final FromSubBean subObject; private final ToSubBean subObject; + + // all constructor // all args constructor + // getters... // getters... +} +~~~ + +and our source `Map` is: + +~~~Java +Map> sourceMap = new HashMap<>(); +~~~ + +and we want to transform it in: + +~~~Java +Map> map = new HashMap<>(); +~~~ + +we first need to define a `BeanTransformer` that maps the different field names: +~~~Java +BeanTransformer beanTransformer = new BeanUtils().getTransformer() + .withFieldMapping(new FieldMapping<>("name", "differentName")); +~~~ + +and then pass it as argument of our Map transformation method: + +~~~Java +Map> map = new MapUtils().getTransformer() + .transform(sourceMap, beanTransformer, ToBean.class, List.class); +~~~ \ No newline at end of file From 71899f916e8f4f4f9d3712391eb277c9215fa100 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Oct 2019 05:33:41 +0100 Subject: [PATCH 0844/1786] Made constructor protected --- .../main/java/com/hotels/transformer/AbstractTransformer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java index ecfff4be6..7e05093bd 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -69,7 +69,7 @@ public abstract class AbstractTransformer Date: Mon, 28 Oct 2019 05:35:32 +0100 Subject: [PATCH 0845/1786] Added @SuppressWarnings("SuspiciousMethodCalls") for method that uses generics in the map object removal --- .../main/java/com/hotels/transformer/AbstractTransformer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java index 7e05093bd..e6cf7fa45 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -107,6 +107,7 @@ public final T withFieldTransformer(final FieldTransformer... fieldTransformer) * {@inheritDoc} */ @Override + @SuppressWarnings("SuspiciousMethodCalls") public final void removeFieldMapping(final String destFieldName) { notNull(destFieldName, "The field name for which the mapping has to be removed cannot be null!"); settings.getFieldsNameMapping().remove(destFieldName); @@ -124,6 +125,7 @@ public final void resetFieldsMapping() { * {@inheritDoc} */ @Override + @SuppressWarnings("SuspiciousMethodCalls") public final void removeFieldTransformer(final String destFieldName) { notNull(destFieldName, "The field name for which the transformer function has to be removed cannot be null!"); settings.getFieldsTransformers().remove(destFieldName); From 2a6bf55d877a0cdc9b1cbd0995d7753bbcb73970 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Oct 2019 06:53:02 +0100 Subject: [PATCH 0846/1786] updated changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 6cb706a03..cb6f0a89b 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. * Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). * Updated `jacoco-maven-plugin` version to `0.8.4` (was `0.8.2`). * Updated `lombok` version to `1.18.10` (was `1.18.8`). +* Updated `hibernate-validator` version to `6.1.0.Final` (was `6.0.17.Final`). ### [1.1.24] 2019.09.02 #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ef9d6c71..7a7ea20ea 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. * Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). * Updated `jacoco-maven-plugin` version to `0.8.4` (was `0.8.2`). * Updated `lombok` version to `1.18.10` (was `1.18.8`). +* Updated `hibernate-validator` version to `6.1.0.Final` (was `6.0.17.Final`). ### [1.5.1] 2019.09.02 #### Changed From a3f02df4fe45443c4decf20d60b8b1b6cdbcffaf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Oct 2019 07:04:17 +0100 Subject: [PATCH 0847/1786] updated changelog description --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index a577a033d..f7079473e 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.1.25] TBD ### Removed -* Removed deprecated module `bean-utils-library` +* Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` * The following deprecated classes has been removed: * `com.hotels.beans.model.FieldMapping` * `com.hotels.beans.model.FieldTransformer` diff --git a/CHANGELOG.md b/CHANGELOG.md index 56fc83e78..cb56bcd7f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.6.0] TBD ### Removed -* Removed deprecated module `bean-utils-library` +* Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` * The following deprecated classes has been removed: * `com.hotels.beans.model.FieldMapping` * `com.hotels.beans.model.FieldTransformer` From 4f9e2f02dbfeb31c99d6fe70c0a7062bf5fb6c59 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Oct 2019 07:09:17 +0100 Subject: [PATCH 0848/1786] [maven-release-plugin] prepare release 1.6.0-RC --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 6 ++---- pom.xml | 4 ++-- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 50d1230c2..2edb93232 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-SNAPSHOT + 1.6.0-RC diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 61bb9ed12..c4e88cb36 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-SNAPSHOT + 1.6.0-RC diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 50c74e7db..df9bf310d 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-SNAPSHOT + 1.6.0-RC diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 581b6241e..f704711dd 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 BULL - Map Transformer bull-map-transformer @@ -11,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0-SNAPSHOT + 1.6.0-RC diff --git a/pom.xml b/pom.xml index 41d47caad..774860dbf 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0-SNAPSHOT + 1.6.0-RC pom 2019 @@ -73,7 +73,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.0-RC From 95be30a31d0ba763ce454a5c9788eba55d7dd84a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Oct 2019 07:09:24 +0100 Subject: [PATCH 0849/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 2edb93232..50d1230c2 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-RC + 1.6.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index c4e88cb36..61bb9ed12 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-RC + 1.6.0-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index df9bf310d..50c74e7db 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-RC + 1.6.0-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f704711dd..eed10909c 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0-RC + 1.6.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 774860dbf..41d47caad 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0-RC + 1.6.0-SNAPSHOT pom 2019 @@ -73,7 +73,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.0-RC + HEAD From 468ad697970dcb3cb9b6d6c7aca32f98a0180c4e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Oct 2019 12:04:44 +0100 Subject: [PATCH 0850/1786] [travis skip] improved changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index f7079473e..c2da53b4c 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. * New specific exception in case the Field Transformation function defined is not valid * Implemented a new functionality that allows to transform also Map object applying transformation function and mappings #### Changed +* `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` * Updated `spring-boot-starter-test` version to `2.1.8.RELEASE` (was `2.1.7.RELEASE`). * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `testng` version to `7.0.0` (was `6.14.3`). diff --git a/CHANGELOG.md b/CHANGELOG.md index cb56bcd7f..fadd2e31d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. * New specific exception in case the Field Transformation function defined is not valid * Implemented a new functionality that allows to transform also Map object applying transformation function and mappings #### Changed +* `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` * Updated `spring-boot-starter-test` version to `2.1.8.RELEASE` (was `2.1.7.RELEASE`). * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `testng` version to `7.0.0` (was `6.14.3`). From 6b9c4a0c7d5de43da8256981d3b978153dd01539 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Oct 2019 16:09:30 +0100 Subject: [PATCH 0851/1786] Removed code duplicates --- .../beans/transformer/TransformerImpl.java | 27 ++++++++++++++----- .../transformer/utils/ReflectionUtils.java | 26 +++++++++++------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 439e00fbe..b3292fd91 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -257,22 +257,20 @@ private Object[] getConstructorValuesFromFields(final T sourceObj, final */ private void injectAllFields(final T sourceObj, final K targetObject, final String breadcrumb) { final Class targetObjectClass = targetObject.getClass(); - classUtils.getDeclaredFields(targetObjectClass, true) - //.parallelStream() - .forEach(setFieldValue(sourceObj, targetObject, breadcrumb, targetObjectClass)); + injectFields(classUtils.getDeclaredFields(targetObjectClass, true), sourceObj, targetObject, targetObjectClass, breadcrumb); } /** * Creates a {@link Consumer} that sets the field value in the given class. * @param sourceObj sourceObj the source object * @param targetObject the destination object instance - * @param breadcrumb the full path of the current field starting from his ancestor * @param targetObjectClass the target object class + * @param breadcrumb the full path of the current field starting from his ancestor * @param the sourceObj object type * @param the target object type * @return a {@link Consumer} that sets the field value in the target object */ - private Consumer setFieldValue(final T sourceObj, final K targetObject, final String breadcrumb, final Class targetObjectClass) { + private Consumer setFieldValue(final T sourceObj, final K targetObject, final Class targetObjectClass, final String breadcrumb) { return field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb)); } @@ -287,9 +285,24 @@ private Consumer setFieldValue(final T sourceObj, final K targetOb */ private void injectNotFinalFields(final T sourceObj, final K targetObject, final String breadcrumb) { final Class targetObjectClass = targetObject.getClass(); - classUtils.getNotFinalFields(targetObjectClass, true) + injectFields(classUtils.getNotFinalFields(targetObjectClass, true), sourceObj, targetObject, targetObjectClass, breadcrumb); + } + + /** + * Injects the values for given final fields. + * @param fieldList the list of field to inject + * @param sourceObj sourceObj the source object + * @param targetObject the destination object instance + * @param targetObjectClass the destination object class + * @param breadcrumb the full path of the current field starting from his ancestor + * @param the sourceObj object type + * @param the target object type + * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value + */ + private void injectFields(final List fieldList, final T sourceObj, final K targetObject, final Class targetObjectClass, final String breadcrumb) { + fieldList //.parallelStream() - .forEach(setFieldValue(sourceObj, targetObject, breadcrumb, targetObjectClass)); + .forEach(setFieldValue(sourceObj, targetObject, targetObjectClass, breadcrumb)); } /** diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index 744e8ac03..e8dfd324d 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -32,6 +32,7 @@ import java.lang.annotation.Annotation; import java.lang.invoke.CallSite; import java.lang.invoke.MethodHandles; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -212,14 +213,7 @@ private Function getGetterMethodFunction(final Class fieldClass, final String */ public A getFieldAnnotation(final Field field, final Class annotationClazz) { final String cacheKey = "FieldAnnotation-" + field.getDeclaringClass().getName() + "-" + field.getName() + "-" + annotationClazz.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, annotationClazz).orElseGet(() -> { - A annotation = null; - if (field.isAnnotationPresent(annotationClazz)) { - annotation = field.getAnnotation(annotationClazz); - } - CACHE_MANAGER.cacheObject(cacheKey, annotation); - return annotation; - }); + return getAnnotation(field, annotationClazz, cacheKey); } /** @@ -232,10 +226,22 @@ public A getFieldAnnotation(final Field field, final Clas */ public A getParameterAnnotation(final Parameter parameter, final Class annotationClazz, final String declaringClassName) { final String cacheKey = "ParameterAnnotation-" + declaringClassName + "-" + parameter.getName() + "-" + annotationClazz.getName(); + return getAnnotation(parameter, annotationClazz, cacheKey); + } + + /** + * Returns (if existing) the element's given type annotation. + * @param element the element that should have the annotation + * @param annotationClazz the annotation type + * @param cacheKey the cache key to use + * @param the annotation type object + * @return the annotation + */ + private A getAnnotation(final AnnotatedElement element, final Class annotationClazz, final String cacheKey) { return CACHE_MANAGER.getFromCache(cacheKey, annotationClazz).orElseGet(() -> { A annotation = null; - if (parameter.isAnnotationPresent(annotationClazz)) { - annotation = parameter.getAnnotation(annotationClazz); + if (element.isAnnotationPresent(annotationClazz)) { + annotation = element.getAnnotation(annotationClazz); } CACHE_MANAGER.cacheObject(cacheKey, annotation); return annotation; From ea7a8627f140e2d5f0c70312b047484a21a6fcf1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 28 Oct 2019 17:29:43 +0100 Subject: [PATCH 0852/1786] Bumped Spring Boot version --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- pom.xml | 9 +++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index c2da53b4c..0a5fe05c3 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -14,7 +14,7 @@ All notable changes to this project will be documented in this file. * Implemented a new functionality that allows to transform also Map object applying transformation function and mappings #### Changed * `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` -* Updated `spring-boot-starter-test` version to `2.1.8.RELEASE` (was `2.1.7.RELEASE`). +* Updated `spring-boot-starter-test` version to `2.2.0.RELEASE` (was `2.1.7.RELEASE`). * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `testng` version to `7.0.0` (was `6.14.3`). * Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). diff --git a/CHANGELOG.md b/CHANGELOG.md index fadd2e31d..5004b2a72 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ All notable changes to this project will be documented in this file. * Implemented a new functionality that allows to transform also Map object applying transformation function and mappings #### Changed * `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` -* Updated `spring-boot-starter-test` version to `2.1.8.RELEASE` (was `2.1.7.RELEASE`). +* Updated `spring-boot-starter-test` version to `2.2.0.RELEASE` (was `2.1.7.RELEASE`). * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `testng` version to `7.0.0` (was `6.14.3`). * Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). diff --git a/pom.xml b/pom.xml index 41d47caad..cb12af776 100644 --- a/pom.xml +++ b/pom.xml @@ -32,14 +32,13 @@ 11 ${jdk.version} ${jdk.version} - 2.1.9.RELEASE + 2.2.0.RELEASE 1.18.10 3.9 0.11 2.8.6 7.0.0 1.3.0 - 3.1.0 2.0.1.Final 6.1.0.Final @@ -116,6 +115,12 @@ spring-boot-starter-test ${spring-boot.version} test + + + org.mockito + mockito-junit-jupiter + + org.slf4j From c523fcf465a45fddf8f7b57c5657f08b02e1644a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 10:15:18 +0100 Subject: [PATCH 0853/1786] modified travis comment --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 40480bab5..347f0d752 100755 --- a/.travis.yml +++ b/.travis.yml @@ -15,10 +15,10 @@ env: install: skip jobs: include: - # If the branch is not master it just builds the application - stage: "Build" name: "Build and Test" script: travis_retry mvn clean install + # If is not a PR and a tag is available - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present @@ -34,6 +34,7 @@ jobs: keep-history: true on: tags: true + # If is not a PR and a tag is available - stage: "Release" name: "Releasing artifacts" if: type NOT IN (pull_request) AND tag IS present From 2f1caf6df8305129c0d0e7c14256d702e2dade5d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 10:22:28 +0100 Subject: [PATCH 0854/1786] [travis skip] updated changelog date --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 0a5fe05c3..cce8b3a59 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.1.25] TBD +### [1.1.25] 2019.10.30 ### Removed * Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` * The following deprecated classes has been removed: diff --git a/CHANGELOG.md b/CHANGELOG.md index 5004b2a72..56a340330 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.0] TBD +### [1.6.0] 2019.10.30 ### Removed * Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` * The following deprecated classes has been removed: From b2f746e6ecb27f7f335073dea5108f57975d0ec8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 10:26:45 +0100 Subject: [PATCH 0855/1786] [maven-release-plugin] prepare release 1.6.0 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 50d1230c2..4d2b2b6f5 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-SNAPSHOT + 1.6.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 61bb9ed12..e76a192a7 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-SNAPSHOT + 1.6.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 50c74e7db..937bd050f 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-SNAPSHOT + 1.6.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index eed10909c..e9ab7890f 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0-SNAPSHOT + 1.6.0 diff --git a/pom.xml b/pom.xml index cb12af776..f5efda0a7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0-SNAPSHOT + 1.6.0 pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.0 From 13a4a03f23b6cf1119b4780a66b97fef935713a6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 10:26:53 +0100 Subject: [PATCH 0856/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 4d2b2b6f5..ec2d73f9c 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e76a192a7..271b32dc6 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 937bd050f..005810557 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index e9ab7890f..867655768 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index f5efda0a7..183ccdbfc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0 + 1.6.1-SNAPSHOT pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.0 + HEAD From 4f0b9d6f25c7715d69d1c5931ef8c7d21ed090cb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 10:55:10 +0100 Subject: [PATCH 0857/1786] [travis skip] changed version --- CHANGELOG.md | 2 +- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56a340330..bb6925069 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.0] 2019.10.30 +### [1.6.0.1] 2019.10.30 ### Removed * Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` * The following deprecated classes has been removed: diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index ec2d73f9c..bdb4f1f7e 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 271b32dc6..e5b8081a4 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 005810557..7f8100ba2 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 867655768..3752b68cb 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.1-SNAPSHOT + 1.6.0.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 183ccdbfc..fb08725f8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.1-SNAPSHOT + 1.6.0.1-SNAPSHOT pom 2019 From 904127042eaab9618152964c6864f5c5f6ebc1b6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 10:56:23 +0100 Subject: [PATCH 0858/1786] [maven-release-plugin] prepare release 1.6.0.1 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index bdb4f1f7e..f3c070f6d 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0.1-SNAPSHOT + 1.6.0.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e5b8081a4..c0d61007f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0.1-SNAPSHOT + 1.6.0.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 7f8100ba2..fee4199a4 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0.1-SNAPSHOT + 1.6.0.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 3752b68cb..0c7094f58 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0.1-SNAPSHOT + 1.6.0.1 diff --git a/pom.xml b/pom.xml index fb08725f8..28243a274 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0.1-SNAPSHOT + 1.6.0.1 pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.0.1 From e0b0b0c5846afa3a09a87a8a7b4aaf8ba74798fb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 10:56:32 +0100 Subject: [PATCH 0859/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index f3c070f6d..ec2d73f9c 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0.1 + 1.6.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index c0d61007f..271b32dc6 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0.1 + 1.6.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index fee4199a4..005810557 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0.1 + 1.6.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0c7094f58..867655768 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0.1 + 1.6.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 28243a274..183ccdbfc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0.1 + 1.6.1-SNAPSHOT pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.0.1 + HEAD From af50e3339d1d75d9ab09af847fff390f62767159 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 11:25:07 +0100 Subject: [PATCH 0860/1786] [travis skip] version update --- CHANGELOG.md | 2 +- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb6925069..56a340330 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.0.1] 2019.10.30 +### [1.6.0] 2019.10.30 ### Removed * Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` * The following deprecated classes has been removed: diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index ec2d73f9c..50d1230c2 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 271b32dc6..61bb9ed12 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 005810557..50c74e7db 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 867655768..eed10909c 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.1-SNAPSHOT + 1.6.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 183ccdbfc..cb12af776 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.1-SNAPSHOT + 1.6.0-SNAPSHOT pom 2019 From 5a293ed697f5acb4242a8a23ca22dcd2e4f9a214 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 11:28:44 +0100 Subject: [PATCH 0861/1786] [maven-release-plugin] prepare release 1.6.0 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 50d1230c2..4d2b2b6f5 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-SNAPSHOT + 1.6.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 61bb9ed12..e76a192a7 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-SNAPSHOT + 1.6.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 50c74e7db..937bd050f 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0-SNAPSHOT + 1.6.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index eed10909c..e9ab7890f 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0-SNAPSHOT + 1.6.0 diff --git a/pom.xml b/pom.xml index cb12af776..f5efda0a7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0-SNAPSHOT + 1.6.0 pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.0 From 5c86ac40c03d642b8ea40caabc65e3db598c520f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 11:28:53 +0100 Subject: [PATCH 0862/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 4d2b2b6f5..ec2d73f9c 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e76a192a7..271b32dc6 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 937bd050f..005810557 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index e9ab7890f..867655768 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index f5efda0a7..183ccdbfc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0 + 1.6.1-SNAPSHOT pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.0 + HEAD From fbf1235a072c2aaf437009dc9dc3a1a274559642 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 12:19:47 +0100 Subject: [PATCH 0863/1786] [maven-release-plugin] prepare release 1.6.0 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index ec2d73f9c..4d2b2b6f5 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 271b32dc6..e76a192a7 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 005810557..937bd050f 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 867655768..e9ab7890f 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.1-SNAPSHOT + 1.6.0 diff --git a/pom.xml b/pom.xml index 183ccdbfc..f5efda0a7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.1-SNAPSHOT + 1.6.0 pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.0 From 43a16fea77e34896b61dd7ef93d2e6a403d31868 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 12:19:55 +0100 Subject: [PATCH 0864/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 4d2b2b6f5..ec2d73f9c 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e76a192a7..271b32dc6 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 937bd050f..005810557 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index e9ab7890f..867655768 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0 + 1.6.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index f5efda0a7..183ccdbfc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0 + 1.6.1-SNAPSHOT pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.0 + HEAD From df5ad87a82b1a2e4cde53f06bf76b1491caceb08 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 15:44:09 +0100 Subject: [PATCH 0865/1786] [maven-release-plugin] prepare release 1.6.0.2 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index ec2d73f9c..ec07c44ff 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 271b32dc6..ec718c135 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 005810557..f0a11c8df 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.0.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 867655768..f78d27950 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.1-SNAPSHOT + 1.6.0.2 diff --git a/pom.xml b/pom.xml index 183ccdbfc..a06869ab8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.1-SNAPSHOT + 1.6.0.2 pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.0.2 From 629a451bf76e95fb3987f31f553cf0852cbcfab0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 15:44:18 +0100 Subject: [PATCH 0866/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index ec07c44ff..ec2d73f9c 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0.2 + 1.6.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index ec718c135..271b32dc6 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0.2 + 1.6.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index f0a11c8df..005810557 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.0.2 + 1.6.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f78d27950..867655768 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.0.2 + 1.6.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index a06869ab8..183ccdbfc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.0.2 + 1.6.1-SNAPSHOT pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.0.2 + HEAD From 9ba5cd74db03a773ba281d9ffb33f8fec6a53569 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 30 Oct 2019 16:09:14 +0100 Subject: [PATCH 0867/1786] [travis skip] updated lib version in the changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56a340330..eef5e97cc 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.0] 2019.10.30 +### [1.6.0.2] 2019.10.30 ### Removed * Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` * The following deprecated classes has been removed: From be5aef46b683c880b0f66efb6828e81e1826ebd1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 31 Oct 2019 11:28:10 +0000 Subject: [PATCH 0868/1786] Bump jacoco-maven-plugin from 0.8.3 to 0.8.5 Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.3 to 0.8.5. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.3...v0.8.5) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 183ccdbfc..6e1289b13 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ 3.0.0 2.2.6 - 0.8.3 + 0.8.5 1.0 0.90 1.0 From 7797699b07275104cdd6cc4b612e50debf962976 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 31 Oct 2019 11:28:11 +0000 Subject: [PATCH 0869/1786] Bump hotels-oss-parent from 4.1.0 to 4.2.0 Bumps [hotels-oss-parent](https://github.com/HotelsDotCom/hotels-oss-parent) from 4.1.0 to 4.2.0. - [Release notes](https://github.com/HotelsDotCom/hotels-oss-parent/releases) - [Changelog](https://github.com/HotelsDotCom/hotels-oss-parent/blob/master/CHANGELOG.md) - [Commits](https://github.com/HotelsDotCom/hotels-oss-parent/compare/hotels-oss-parent-4.1.0...hotels-oss-parent-4.2.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 183ccdbfc..a921fc3e8 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.hotels hotels-oss-parent - 4.1.0 + 4.2.0 From 293a159a45f4ba2bd59a0885800080ed150d179f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 31 Oct 2019 12:42:17 +0100 Subject: [PATCH 0870/1786] [travis skip] updated changelog --- CHANGELOG-JDK8.md | 4 +++- CHANGELOG.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index cce8b3a59..59dd67976 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +### [1.1.26] TBD +* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). + ### [1.1.25] 2019.10.30 ### Removed * Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` @@ -15,7 +18,6 @@ All notable changes to this project will be documented in this file. #### Changed * `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` * Updated `spring-boot-starter-test` version to `2.2.0.RELEASE` (was `2.1.7.RELEASE`). -* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `testng` version to `7.0.0` (was `6.14.3`). * Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). * Updated `jacoco-maven-plugin` version to `0.8.4` (was `0.8.2`). diff --git a/CHANGELOG.md b/CHANGELOG.md index eef5e97cc..6b09ccd48 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +### [1.6.1] TBD +* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). + ### [1.6.0.2] 2019.10.30 ### Removed * Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` @@ -15,7 +18,6 @@ All notable changes to this project will be documented in this file. #### Changed * `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` * Updated `spring-boot-starter-test` version to `2.2.0.RELEASE` (was `2.1.7.RELEASE`). -* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `testng` version to `7.0.0` (was `6.14.3`). * Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). * Updated `jacoco-maven-plugin` version to `0.8.4` (was `0.8.2`). From 3c7fa784139299e680bacad3be0228b70eda0046 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 31 Oct 2019 12:46:24 +0100 Subject: [PATCH 0871/1786] [travis skip] updated changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 59dd67976..3702c0bd0 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.1.26] TBD * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). +* Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). ### [1.1.25] 2019.10.30 ### Removed diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b09ccd48..8a670b5a5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.6.1] TBD * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). +* Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). ### [1.6.0.2] 2019.10.30 ### Removed From ccb209a8fc74b28b7d078c92ab79e419b2298025 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2019 02:41:23 +0000 Subject: [PATCH 0872/1786] Bump slf4j-api from 1.7.28 to 1.7.29 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.28 to 1.7.29. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/commits) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b2bb2d794..a9d9778f1 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ 2.0.1.Final 6.1.0.Final - 1.7.28 + 1.7.29 3.0.0 2.2.6 From f701936c9d2f157b303325be25df059ab20dd6ff Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 1 Nov 2019 09:11:30 +0100 Subject: [PATCH 0873/1786] [travis skip] updated changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 3702c0bd0..b23da3efb 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.1.26] TBD * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). +* Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). ### [1.1.25] 2019.10.30 ### Removed diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a670b5a5..97c2869bc 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.1] TBD * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). +* Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). ### [1.6.0.2] 2019.10.30 ### Removed From 9e2e6d6e722b75d3bc7fe8a7c689271ba1995529 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2019 02:20:46 +0000 Subject: [PATCH 0874/1786] Bump spring-boot-starter-test from 2.2.0.RELEASE to 2.2.1.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.2.0.RELEASE to 2.2.1.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.2.0.RELEASE...v2.2.1.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a9d9778f1..ae62e9ebf 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ 11 ${jdk.version} ${jdk.version} - 2.2.0.RELEASE + 2.2.1.RELEASE 1.18.10 3.9 0.11 From 8bb0f555631e80c3f2e363783c2297d67350e51d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 7 Nov 2019 13:41:52 +0100 Subject: [PATCH 0875/1786] updated changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index b23da3efb..a44ac62a8 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). * Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). +* Updated `spring-boot-starter-test` version to `2.2.1.RELEASE` (was `2.2.0.RELEASE`). ### [1.1.25] 2019.10.30 ### Removed diff --git a/CHANGELOG.md b/CHANGELOG.md index 97c2869bc..e2d02a8ef 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). * Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). +* Updated `spring-boot-starter-test` version to `2.2.1.RELEASE` (was `2.2.0.RELEASE`). ### [1.6.0.2] 2019.10.30 ### Removed From f3fccc65bc5cce826f51761e13643123c77bcbc9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2019 02:23:57 +0000 Subject: [PATCH 0876/1786] Bump wagon-ssh from 3.3.3 to 3.3.4 Bumps wagon-ssh from 3.3.3 to 3.3.4. Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ae62e9ebf..bff1a9dbc 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 0.90 **/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* - 3.3.3 + 3.3.4 0.12 github 3.8.2 From 822a297dc12add87c6da4842a138351f5677e642 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 12 Nov 2019 09:09:50 +0100 Subject: [PATCH 0877/1786] Modified changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index a44ac62a8..a9d4b516b 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). * Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). * Updated `spring-boot-starter-test` version to `2.2.1.RELEASE` (was `2.2.0.RELEASE`). +* Updated `wagon-ssh` version to `3.3.4` (was `3.3.3`). ### [1.1.25] 2019.10.30 ### Removed diff --git a/CHANGELOG.md b/CHANGELOG.md index e2d02a8ef..308e666da 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). * Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). * Updated `spring-boot-starter-test` version to `2.2.1.RELEASE` (was `2.2.0.RELEASE`). +* Updated `wagon-ssh` version to `3.3.4` (was `3.3.3`). ### [1.6.0.2] 2019.10.30 ### Removed From a61f304f3e63833c9de27f543e192c2e4c1a58df Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 15 Nov 2019 16:38:27 +0100 Subject: [PATCH 0878/1786] Fixed check that was preventing the transformation of Mixed Java Beans without an all args constructor. --- CHANGELOG-JDK8.md | 3 +++ CHANGELOG.md | 3 +++ .../java/com/hotels/beans/transformer/TransformerImpl.java | 3 +-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index a9d4b516b..85f81ac64 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. ### [1.1.26] TBD +### Fixed +* Fixed check that was preventing the transformation of Mixed Java Beans without an all args constructor. +#### Changed * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). * Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 308e666da..ea8d32136 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. ### [1.6.1] TBD +### Fixed +* Fixed check that was preventing the transformation of Mixed Java Beans without an all args constructor. +#### Changed * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). * Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index b3292fd91..10fe3490a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -141,8 +141,7 @@ private String getFormattedConstructorArgs(final Class targetClass, final private boolean canBeInjectedByConstructorParams(final Constructor constructor, final Class targetClass) { final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() - && (classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class)); + final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount(); cacheManager.cacheObject(cacheKey, res); return res; }); From daa0bf4b360476be3666027455d4fa8f705f0f1f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 15 Nov 2019 17:42:13 +0100 Subject: [PATCH 0879/1786] Updated readme --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 6ded29559..85e10057d 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,34 @@ All BULL modules are available on Maven Central: In case you need to integrate it in a `jdk 8` (or above project) please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) file or to [CHANGELOG](CHANGELOG.md) otherwise. +* #### Suggestions + +Some jdk versions removes the Java Bean constructor's argument names from the compiled code and this may cause problems to the library. +On top of that, it's suggested to configure the `maven-compiler-plugin`, inside your project, as follow: + +~~~ + + ... + + + ... + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + true + true + + + + + ... + +~~~ + ## Maven build Full build From b7b9d1e3369f6f5bec4f83761bb95b8d53fddf21 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 Nov 2019 11:41:28 +0100 Subject: [PATCH 0880/1786] - Specified the exception thrown in case constructor parameter names are not available in the compiled code - Removed redundant dependencies version from pom file --- .../beans/transformer/TransformerImpl.java | 19 ++++++++++++++----- bull-common/pom.xml | 4 ---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 10fe3490a..9577332f5 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -111,10 +111,18 @@ private K injectValues(final T sourceObj, final Class targetClass, fin try { return classUtils.getInstance(constructor, constructorArgs); } catch (final Exception e) { - throw new InvalidBeanException("Constructor invoked with arguments. Expected: " + constructor + "; Found: " - + getFormattedConstructorArgs(targetClass, constructorArgs) - + ". Double check that each " + targetClass.getSimpleName() + "'s field have the same type and name than the source object: " - + sourceObj.getClass().getName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(), e); + String errorMsg; + if (!classUtils.areParameterNamesAvailable(constructor)) { + errorMsg = "Constructor's parameters name have been removed from the compiled code. " + + "This caused a problems during the: " + targetClass.getSimpleName() + " injection, " + + "consider to add the property: true to your maven-compiler configuration"; + } else { + errorMsg = "Constructor invoked with arguments. Expected: " + constructor + "; Found: " + + getFormattedConstructorArgs(targetClass, constructorArgs) + + ". Double check that each " + targetClass.getSimpleName() + "'s field have the same type and name than the source object: " + + sourceObj.getClass().getName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(); + } + throw new InvalidBeanException(errorMsg, e); } } @@ -141,7 +149,8 @@ private String getFormattedConstructorArgs(final Class targetClass, final private boolean canBeInjectedByConstructorParams(final Constructor constructor, final Class targetClass) { final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount(); + final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() + && (classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class)); cacheManager.cacheObject(cacheKey, res); return res; }); diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 271b32dc6..deb0b7faa 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -21,22 +21,18 @@ javax.validation validation-api - ${validation-api.version} javax.el javax.el-api - ${javax.el-api.version} org.glassfish.web javax.el - ${glassfish.javax.el.version} org.hibernate.validator hibernate-validator - ${hibernate-validator.version} From 5fa06f926959e447d049dbba85b5e94e16c48ef3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 Nov 2019 11:59:28 +0100 Subject: [PATCH 0881/1786] Added warn logging in case the parameter names are not available in the compiled code --- CHANGELOG-JDK8.md | 1 + bull-common/pom.xml | 4 ++++ .../main/java/com/hotels/transformer/utils/ClassUtils.java | 7 +++++++ pom.xml | 1 - 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 85f81ac64..4684a4659 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -25,6 +25,7 @@ All notable changes to this project will be documented in this file. #### Changed * `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` * Updated `spring-boot-starter-test` version to `2.2.0.RELEASE` (was `2.1.7.RELEASE`). +* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `testng` version to `7.0.0` (was `6.14.3`). * Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). * Updated `jacoco-maven-plugin` version to `0.8.4` (was `0.8.2`). diff --git a/bull-common/pom.xml b/bull-common/pom.xml index deb0b7faa..d65480900 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -17,6 +17,10 @@ org.apache.commons commons-lang3 + + org.slf4j + slf4j-api + javax.validation diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index fd498ad5b..c19a4c586 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -68,9 +68,12 @@ import com.hotels.transformer.error.InstanceCreationException; import com.hotels.transformer.error.InvalidBeanException; +import lombok.extern.slf4j.Slf4j; + /** * Reflection utils for Class objects. */ +@Slf4j public final class ClassUtils { /** * Class nullability error message constant. @@ -622,6 +625,10 @@ public boolean areParameterNamesAvailable(final Constructor constructor) { return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = stream(getConstructorParameters(constructor)) .anyMatch(Parameter::isNamePresent); + if (!res) { + log.warn("WARNING: Constructor's parameters name have been removed from the compiled code." + + "This may prevent the correct working to library wo "); + } CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); diff --git a/pom.xml b/pom.xml index bff1a9dbc..17410fb4d 100644 --- a/pom.xml +++ b/pom.xml @@ -126,7 +126,6 @@ org.slf4j slf4j-api ${slf4j-api.version} - test com.shazam From 8d89d87ce0f2007eac52aa281d3f472d60f6cdbf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 Nov 2019 12:39:32 +0100 Subject: [PATCH 0882/1786] Added class for a better test of the InvalidBeanException --- .../beans/transformer/TransformerImpl.java | 2 +- .../ImmutableObjectTransformationTest.java | 7 ++-- .../ImmutableToFooDiffTypesFields.java | 37 +++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 9577332f5..36cdb7462 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -117,7 +117,7 @@ private K injectValues(final T sourceObj, final Class targetClass, fin + "This caused a problems during the: " + targetClass.getSimpleName() + " injection, " + "consider to add the property: true to your maven-compiler configuration"; } else { - errorMsg = "Constructor invoked with arguments. Expected: " + constructor + "; Found: " + errorMsg = "Constructor invoked with wrong arguments. Expected: " + constructor + "; Found: " + getFormattedConstructorArgs(targetClass, constructorArgs) + ". Double check that each " + targetClass.getSimpleName() + "'s field have the same type and name than the source object: " + sourceObj.getClass().getName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 89710218b..4909fce02 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -52,6 +52,7 @@ import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooDiffFields; +import com.hotels.beans.sample.immutable.ImmutableToFooDiffTypesFields; import com.hotels.beans.sample.immutable.ImmutableToFooInvalid; import com.hotels.beans.sample.immutable.ImmutableToFooMap; import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; @@ -197,7 +198,7 @@ public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsExceptio //GIVEN //WHEN - underTest.setValidationEnabled(true).transform(sourceObject, targetObjectClass); + underTest.setValidationEnabled(false).transform(sourceObject, targetObjectClass); } /** @@ -208,7 +209,7 @@ public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsExceptio private Object[][] dataConstructorErrorTesting() { FromFoo actual = new FromFoo(NAME, ID, null, null, null); return new Object[][] { - {"Test that an exception is thrown if the constructor invocation throws exception", actual, ImmutableToFooCustomAnnotation.class} + {"Test that an exception is thrown if the constructor is invoked with wrong type arguments", actual, ImmutableToFooDiffTypesFields.class} }; } @@ -425,7 +426,7 @@ public void testTransformationReturnsAMeaningfulException() { //GIVEN Class targetClass = ImmutableToFooSimpleWrongTypes.class; final String expectedExceptionMessageFormat = - "Constructor invoked with arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " + "Constructor invoked with wrong arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " + "Double check that each %s's field have the same type and name than the source object: %s otherwise specify a transformer configuration. " + "Error message: argument type mismatch"; String targetClassName = targetClass.getName(); diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java new file mode 100644 index 000000000..d0c35af94 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.immutable; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * Sample immutable object with different fields type than source object. + */ +@AllArgsConstructor +@Getter +@ToString +public class ImmutableToFooDiffTypesFields { + private final String name; + private final String id; + private final List list; + private final List nestedObjectList; + private final ImmutableToSubFoo nestedObject; +} From 01248cb45cb7365956c7ad982bb01ca31e3d50d8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 Nov 2019 13:55:58 +0100 Subject: [PATCH 0883/1786] Modified changelog --- CHANGELOG-JDK8.md | 6 +++--- CHANGELOG.md | 4 ++-- .../java/com/hotels/beans/transformer/TransformerImpl.java | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 4684a4659..f2fa555b2 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,9 +2,9 @@ All notable changes to this project will be documented in this file. -### [1.1.26] TBD -### Fixed -* Fixed check that was preventing the transformation of Mixed Java Beans without an all args constructor. +### [1.1.26] 2019.11.18 +### Added +* Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. #### Changed * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). diff --git a/CHANGELOG.md b/CHANGELOG.md index ea8d32136..e214c3f75 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,9 @@ All notable changes to this project will be documented in this file. -### [1.6.1] TBD +### [1.6.1] 2019.11.18 ### Fixed -* Fixed check that was preventing the transformation of Mixed Java Beans without an all args constructor. +* Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. #### Changed * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 36cdb7462..6c416b355 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -115,7 +115,8 @@ private K injectValues(final T sourceObj, final Class targetClass, fin if (!classUtils.areParameterNamesAvailable(constructor)) { errorMsg = "Constructor's parameters name have been removed from the compiled code. " + "This caused a problems during the: " + targetClass.getSimpleName() + " injection, " - + "consider to add the property: true to your maven-compiler configuration"; + + "consider to use: @ConstructorArg annotation: https://github.com/HotelsDotCom/bull#different-field-names-defining-constructor-args " + + "or add the property: true to your maven-compiler configuration"; } else { errorMsg = "Constructor invoked with wrong arguments. Expected: " + constructor + "; Found: " + getFormattedConstructorArgs(targetClass, constructorArgs) From b52ff868763a33ed09550b9d5362e2b2a758107a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 Nov 2019 14:50:49 +0100 Subject: [PATCH 0884/1786] Modified changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e214c3f75..f84d36539 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. ### [1.6.1] 2019.11.18 -### Fixed +### Added * Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. #### Changed * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). From 73ba4572c7c0b04316487c2775f355793c359f72 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 Nov 2019 15:04:35 +0100 Subject: [PATCH 0885/1786] Updated exception message --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 4 ++-- .../main/java/com/hotels/transformer/utils/ClassUtils.java | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 6c416b355..8cce03ae0 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -114,8 +114,8 @@ private K injectValues(final T sourceObj, final Class targetClass, fin String errorMsg; if (!classUtils.areParameterNamesAvailable(constructor)) { errorMsg = "Constructor's parameters name have been removed from the compiled code. " - + "This caused a problems during the: " + targetClass.getSimpleName() + " injection, " - + "consider to use: @ConstructorArg annotation: https://github.com/HotelsDotCom/bull#different-field-names-defining-constructor-args " + + "This caused a problems during the: " + targetClass.getSimpleName() + " injection. " + + "Consider to use: @ConstructorArg annotation: https://github.com/HotelsDotCom/bull#different-field-names-defining-constructor-args " + "or add the property: true to your maven-compiler configuration"; } else { errorMsg = "Constructor invoked with wrong arguments. Expected: " + constructor + "; Found: " diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index c19a4c586..3a33e4052 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -626,8 +626,10 @@ public boolean areParameterNamesAvailable(final Constructor constructor) { final boolean res = stream(getConstructorParameters(constructor)) .anyMatch(Parameter::isNamePresent); if (!res) { - log.warn("WARNING: Constructor's parameters name have been removed from the compiled code." - + "This may prevent the correct working to library wo "); + log.warn("Constructor's parameters name have been removed from the compiled code. " + + "This caused a problems with the Java Bean injection through constructor. " + + "Consider to use: @ConstructorArg annotation: https://github.com/HotelsDotCom/bull#different-field-names-defining-constructor-args " + + "or add the property: true to your maven-compiler configuration"); } CACHE_MANAGER.cacheObject(cacheKey, res); return res; From 0d45d03fe920874ca229b5fead335f63b1eea7a8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 Nov 2019 15:15:35 +0100 Subject: [PATCH 0886/1786] [maven-release-plugin] prepare release 1.6.1 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index ec2d73f9c..09e878140 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index d65480900..fc72c8b93 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 005810557..1ece27759 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1-SNAPSHOT + 1.6.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 867655768..e0cb7eebc 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.1-SNAPSHOT + 1.6.1 diff --git a/pom.xml b/pom.xml index 17410fb4d..40e342c9b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.1-SNAPSHOT + 1.6.1 pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.1 From d2a3f069c789e18961eefcb0e8c0b8023f6d6b2b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 Nov 2019 15:15:43 +0100 Subject: [PATCH 0887/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 09e878140..884426fea 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1 + 1.6.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index fc72c8b93..7ac80d7e8 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1 + 1.6.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 1ece27759..6978f470f 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1 + 1.6.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index e0cb7eebc..604fe94e4 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.1 + 1.6.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 40e342c9b..69f4bbc37 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.1 + 1.6.2-SNAPSHOT pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.1 + HEAD From 8050630ebe4a065b12eca80f2a3984f72833826b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 05:06:13 +0100 Subject: [PATCH 0888/1786] * Removed warning leg message in case the constructor parameter names are not available in the compiled code. * Removed `slf4j-api` dependency from the library jar. --- CHANGELOG-JDK8.md | 5 +++++ CHANGELOG.md | 5 +++++ bull-common/pom.xml | 4 ---- .../java/com/hotels/transformer/utils/ClassUtils.java | 9 --------- pom.xml | 1 + 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index f2fa555b2..d09457d4a 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.1.27] 2019.11.22 +#### Changed +* Removed warning leg message in case the constructor parameter names are not available in the compiled code. +* Removed `slf4j-api` dependency from the library jar. + ### [1.1.26] 2019.11.18 ### Added * Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. diff --git a/CHANGELOG.md b/CHANGELOG.md index f84d36539..8481b241b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.6.1.1] 2019.11.22 +#### Changed +* Removed warning leg message in case the constructor parameter names are not available in the compiled code. +* Removed `slf4j-api` dependency from the library jar. + ### [1.6.1] 2019.11.18 ### Added * Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 7ac80d7e8..760bd0f39 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -17,10 +17,6 @@ org.apache.commons commons-lang3 - - org.slf4j - slf4j-api - javax.validation diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 3a33e4052..fd498ad5b 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -68,12 +68,9 @@ import com.hotels.transformer.error.InstanceCreationException; import com.hotels.transformer.error.InvalidBeanException; -import lombok.extern.slf4j.Slf4j; - /** * Reflection utils for Class objects. */ -@Slf4j public final class ClassUtils { /** * Class nullability error message constant. @@ -625,12 +622,6 @@ public boolean areParameterNamesAvailable(final Constructor constructor) { return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = stream(getConstructorParameters(constructor)) .anyMatch(Parameter::isNamePresent); - if (!res) { - log.warn("Constructor's parameters name have been removed from the compiled code. " - + "This caused a problems with the Java Bean injection through constructor. " - + "Consider to use: @ConstructorArg annotation: https://github.com/HotelsDotCom/bull#different-field-names-defining-constructor-args " - + "or add the property: true to your maven-compiler configuration"); - } CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); diff --git a/pom.xml b/pom.xml index 69f4bbc37..37200b881 100644 --- a/pom.xml +++ b/pom.xml @@ -126,6 +126,7 @@ org.slf4j slf4j-api ${slf4j-api.version} + test com.shazam From 288d855b7c74a7455f5a8023a1f9df3c4f9532e0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 07:10:37 +0100 Subject: [PATCH 0889/1786] Preparing release --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 884426fea..13267937a 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.2-SNAPSHOT + 1.6.1.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 760bd0f39..9ae9715ec 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.2-SNAPSHOT + 1.6.1.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 6978f470f..06e7b57a7 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.2-SNAPSHOT + 1.6.1.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 604fe94e4..165def9d5 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.2-SNAPSHOT + 1.6.1.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 37200b881..b36530cf0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.2-SNAPSHOT + 1.6.1.1-SNAPSHOT pom 2019 From 192712dc7ad5d00e6949d26e3aa01ef5792fe509 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 07:12:36 +0100 Subject: [PATCH 0890/1786] [maven-release-plugin] prepare release 1.6.1.1 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 13267937a..a9ca8500d 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1.1-SNAPSHOT + 1.6.1.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 9ae9715ec..233438a85 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1.1-SNAPSHOT + 1.6.1.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 06e7b57a7..43c8f3421 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1.1-SNAPSHOT + 1.6.1.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 165def9d5..247a841d2 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.1.1-SNAPSHOT + 1.6.1.1 diff --git a/pom.xml b/pom.xml index b36530cf0..a0a4d80ad 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.1.1-SNAPSHOT + 1.6.1.1 pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.1.1 From e50cff2475fdd8153add13a204e88260dbbc3d58 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 07:12:44 +0100 Subject: [PATCH 0891/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index a9ca8500d..884426fea 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1.1 + 1.6.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 233438a85..760bd0f39 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1.1 + 1.6.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 43c8f3421..6978f470f 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.1.1 + 1.6.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 247a841d2..604fe94e4 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.1.1 + 1.6.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index a0a4d80ad..37200b881 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.1.1 + 1.6.2-SNAPSHOT pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.1.1 + HEAD From 9cc2e62b29d887ed7c8cd75770e26248711c57ca Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 15:40:17 +0100 Subject: [PATCH 0892/1786] Testing build with jdk8 automatically --- .travis.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 347f0d752..b32bd81f2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,9 @@ language: java cache: directories: - "~/.m2/repository" -jdk: openjdk11 +jdk: + - openjdk11 + - oraclejdk8 env: global: # HCOM OSS Sonatype jira info @@ -17,7 +19,14 @@ jobs: include: - stage: "Build" name: "Build and Test" + if: branch !=~ ^.*-jdk8$ script: travis_retry mvn clean install + - stage: "JDK8 Build" + name: "Build and Test JDK8" + if: branch =~ ^.*-jdk8$ + script: + - jdk_switcher use oraclejdk8 + - travis_retry mvn clean install # If is not a PR and a tag is available - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" From 0ad491298e872b569289b82fd63b4c667d3dfa49 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 16:15:12 +0100 Subject: [PATCH 0893/1786] test build jdk8 --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b32bd81f2..0b933857a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -17,16 +17,15 @@ env: install: skip jobs: include: - - stage: "Build" - name: "Build and Test" - if: branch !=~ ^.*-jdk8$ - script: travis_retry mvn clean install - stage: "JDK8 Build" name: "Build and Test JDK8" if: branch =~ ^.*-jdk8$ script: - jdk_switcher use oraclejdk8 - travis_retry mvn clean install + - stage: "Build" + name: "Build and Test" + script: travis_retry mvn clean install # If is not a PR and a tag is available - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" From e4b99e5a1e5ae6844aad9f9e969cf053f58b8e8c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 16:24:40 +0100 Subject: [PATCH 0894/1786] Test --- .travis.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0b933857a..f3b2ff1f8 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,9 @@ language: java cache: directories: - "~/.m2/repository" -jdk: - - openjdk11 - - oraclejdk8 +#jdk: +# - openjdk11 +# - oraclejdk8 env: global: # HCOM OSS Sonatype jira info @@ -25,7 +25,9 @@ jobs: - travis_retry mvn clean install - stage: "Build" name: "Build and Test" - script: travis_retry mvn clean install + script: + - jdk_switcher use openjdk11 + - travis_retry mvn clean install # If is not a PR and a tag is available - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" From 7d9836f311a14aa38bd3e554627f192a99596ba5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 16:34:04 +0100 Subject: [PATCH 0895/1786] test jdk switch --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f3b2ff1f8..7782a45f9 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,7 @@ language: java cache: directories: - "~/.m2/repository" -#jdk: -# - openjdk11 -# - oraclejdk8 +jdk: openjdk11 env: global: # HCOM OSS Sonatype jira info @@ -19,6 +17,7 @@ jobs: include: - stage: "JDK8 Build" name: "Build and Test JDK8" + jdk: oraclejdk8 if: branch =~ ^.*-jdk8$ script: - jdk_switcher use oraclejdk8 From 974be5afbe0dc84aeeceab2fabc1dc91026b4581 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 17:01:15 +0100 Subject: [PATCH 0896/1786] configure travis job in order to build and release jdk8 artifacts --- .travis.yml | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7782a45f9..6b0eecd49 100755 --- a/.travis.yml +++ b/.travis.yml @@ -15,22 +15,22 @@ env: install: skip jobs: include: + ### JDK11 build + - stage: "JDK11 Build" + name: "JDK11 Build and Test" + if: branch =~ ^((?!-jdk8).)*$ + script: + - travis_retry mvn clean install + ### JDK8 build - stage: "JDK8 Build" - name: "Build and Test JDK8" + name: "JDK8 Build and Test" jdk: oraclejdk8 if: branch =~ ^.*-jdk8$ script: - - jdk_switcher use oraclejdk8 - - travis_retry mvn clean install - - stage: "Build" - name: "Build and Test" - script: - - jdk_switcher use openjdk11 - travis_retry mvn clean install - # If is not a PR and a tag is available - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" - if: type NOT IN (pull_request) AND tag IS present + if: type NOT IN (pull_request) AND tag IS present AND branch =~ ^((?!-jdk8).)*$ script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} @@ -43,10 +43,26 @@ jobs: keep-history: true on: tags: true - # If is not a PR and a tag is available - - stage: "Release" - name: "Releasing artifacts" - if: type NOT IN (pull_request) AND tag IS present + ### JDK11 release + - stage: "JDK11 Release" + name: "Releasing artifacts for JDK11" + if: type NOT IN (pull_request) AND tag IS present AND branch =~ ^((?!-jdk8).)*$ + script: skip + before_deploy: + - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d + - mvn versions:set -D newVersion=${TRAVIS_TAG} + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate + deploy: + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true + ### JDK8 release + - stage: "JDK8 Release" + name: "Releasing artifacts for JDK8" + jdk: oraclejdk8 + if: type NOT IN (pull_request) AND tag IS present AND branch =~ ^.*-jdk8$ script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d From 4b939125454881e7930be6de71d6d3b2ad10e40d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 17:05:37 +0100 Subject: [PATCH 0897/1786] Specified jdk for each build job --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6b0eecd49..9252641ac 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ jobs: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" + jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install @@ -30,6 +31,7 @@ jobs: - travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" + jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND branch =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -46,6 +48,7 @@ jobs: ### JDK11 release - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" + jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND branch =~ ^((?!-jdk8).)*$ script: skip before_deploy: From a0fdb7f78567d0440c37870a5714bcccbd41f1d0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 17:52:25 +0100 Subject: [PATCH 0898/1786] - Modified travis configuration to release both jdk8 and jdk11 artifacts - Added drafr release process file --- .travis.yml | 17 +++-- RELEASE.md | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+), 9 deletions(-) create mode 100644 RELEASE.md diff --git a/.travis.yml b/.travis.yml index 9252641ac..73067c57c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: java cache: directories: - "~/.m2/repository" -jdk: openjdk11 env: global: # HCOM OSS Sonatype jira info @@ -19,20 +18,20 @@ jobs: - stage: "JDK11 Build" name: "JDK11 Build and Test" jdk: openjdk11 - if: branch =~ ^((?!-jdk8).)*$ + if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" - jdk: oraclejdk8 - if: branch =~ ^.*-jdk8$ + jdk: openjdk8 + if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" - jdk: openjdk11 - if: type NOT IN (pull_request) AND tag IS present AND branch =~ ^((?!-jdk8).)*$ + jdk: openjdk8 + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} @@ -49,7 +48,7 @@ jobs: - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" jdk: openjdk11 - if: type NOT IN (pull_request) AND tag IS present AND branch =~ ^((?!-jdk8).)*$ + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d @@ -64,8 +63,8 @@ jobs: ### JDK8 release - stage: "JDK8 Release" name: "Releasing artifacts for JDK8" - jdk: oraclejdk8 - if: type NOT IN (pull_request) AND tag IS present AND branch =~ ^.*-jdk8$ + jdk: openjdk8 + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk8$ script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 000000000..30f012507 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,199 @@ +# Release process for BULL + +## Explanation of the process sequence + +Assumption that the current state of *master* will constitute the release... + +#### 1. Pre-release checks + +Make the following checks before performing a release: + * Do all unit tests pass? + * Do all examples work? + * Does documentation build? + + +#### 2. Update VERSION and CHANGELOG + +##### Increment the version number. + +The version number is in the [`VERSION`](VERSION) file. This is picked up by the documentation build process. + +It consists of two lines. The first carries the version number. The structure is: *major* **.** *minor* **.** *revision*. +The *revision* part is *not included* if it is zero '0' (just after a *major* or *minor* increment). + * *major* = significant incompatible change (e.g. partial or whole rewrite). + * *minor* = some new functionality or changes that are mostly/wholly backward compatible. + * *revision* = very minor changes, e.g. bugfixes. + +The 2nd line carries the state - whether this is the "latest" code in the master branch, or whether it is a "release". +Leave this as "latest" for the moment. + + +##### Update the change log + +The is in the [`CHANGELOG.md`](CHANGELOG.md) file. Ensure it mentions any noteworthy changes since the previous release. + + +#### 3. Create release branch + +Create the branch, naming it after the release version number (just the number). + +In the branch, now modify (and commit) the VERSION file, changing "latest" to "release". + + +#### 4. Create a new release on GitHub based on the new branch + +Put a shorter summary of the new changelog items into the release notes. Make the tag name the version number +- the same as the branch name. + + +#### 5. Update documentation builds on gh-pages + +Run the documentation build process to build documentation for: + +* This new "release" branch ("new") +* *master* branch ("latest") + +Note that these are slightly different (because of the 2nd line in the `VERSION` file) + +Checkout the [gh-pages](https://github.com/bbc/dial-discovery-ios/tree/gh-pages) branch and make the following commits: + +* replace the contents of [`docs/latest`](https://github.com/bbc/dial-discovery-ios/tree/gh-pages/docs/latest) + with the documentation build for the "latest" state of master. + +* put into `docs/XXXX` the documentation build for the "new" release branch, where XXXX is the version number + +Then push the commits up to GitHub. + +#### 6. Release new CocoaPod version + +The process originally followed to register and setup first time was [this one](https://code.tutsplus.com/tutorials/creating-your-first-cocoapod--cms-24332). You need to be registered with CocoaPods Trunk +repository to be able to publish a pod. Instructions to register with CocoaPods Trunk are available [here](https://guides.cocoapods.org/making/getting-setup-with-trunk.html) + + +For subsequent releases, increment the version number in the PodSpec file and push the new pod version . + + $ pod trunk push dial-discovery-ios.podspec + + +- - - - - + +## Example of release process sequence + +This example assumes your local repository is a clone and the working copy is currently at the head of the master branch, and that this is all +synced with GitHub. The following steps will do a release "X.Y.Z" + + $ git status + On branch master + Your branch is up-to-date with 'origin/master'. + nothing to commit, working directory clean + +### 1. Run checks + +Run unit tests: + + $ xcodebuild test -workspace Example/dial-discovery-ios.xcworkspace -scheme dial-discovery-ios-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty + $ pod lib lint + + +Also check the documentation builds: + + $ cd docs + $ jazzy --config jazzy.yaml + +... and manually review areas where it will have changed + +And run all examples and check they work! + + + +### 2. Update VERSION and CHANGELOG + +Update the version number in `master`, e.g. using `vi`: + + $ vi VERSION + .. change version number line only .. + $ vi CHANGELOG.md + .. update change log .. + $ git add VERSION + $ git add CHANGELOG.md + $ git commit -m "Version number increment and Changelog update ready for release" + +And push to GitHub: + + $ git push origin master + +### 3. Create release branch + +Create new branch (locally) + + $ git checkout -b 'X.Y.Z' + +Update VERSION to mark as "release" within the branch + + $ vi VERSION + .. change "latest" to "release" + $ git add VERSION + $ git commit -m "Version marked as release." + +Push branch up to github (and set local repository to track the upstream branch on origin): + + $ git push -u origin 'X.Y.Z' + + +### 4. Create a new release on GitHub based on the new branch + +Now use the [new release](https://github.com/bbc/dial-discovery-ios/releases/new) function on GitHub's web interface to +mark the branch 'X.Y.Z' as a new release. + +### 5. Update documentation builds on gh-pages + +First, build and copy the documentation for the release and stash it somewhere temporarily. + + $ git status + On branch X.Y.Z + Your branch is up-to-date with 'origin/master'. + nothing to commit, working directory clean + + $ cd docs + $ jazzy --config jazzy.yaml + $ cp -R build/ /tmp/X.Y.Z + +Now switch back to master and do the same for the latest state of master: + + $ git checkout master + $ jazzy --config jazzy.yaml + $ cp -R build/ tmp/latest + $ cd .. + +Now switch to gh-pages and ensure it is synced with GitHub: + + $ git checkout gh-pages + $ git pull origin gh-pages + +And put the new documentation builds in place: + + $ cp -R /tmp/X.Y.Z docs/X.Y.Z + $ git add docs/X.Y.Z + + $ git rm docs/latest + $ cp -R /tmp/latest docs/latest + $ git add docs/latest + + $ git commit -m "Updated docs for new release and latest changes in master" + +At this point the `docs` dir should contain: + +* a subdir `X.Y.Z` (named after the release version) containing the HTML documentation for + that version. `index.html` should describe the release version as being *"X.Y.Z-release"* + +* a subdir `latest` containing the HTML documentation built from *master*. `index.html` should describe the + release version as being *"X.Y.Z-latest"* + +Push to GitHub: + + $ git push origin gh-pages + +Upload to CocoaPods Trunk: + + $ git checkout <> + $ pod trunk push dial-discovery-ios.podspec \ No newline at end of file From ee658b0ecf78f277a8d97b171f0af85d1cd756e6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 Nov 2019 18:22:49 +0100 Subject: [PATCH 0899/1786] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 73067c57c..36b14da11 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: java cache: directories: - - "~/.m2/repository" + - $HOME/.m2 env: global: # HCOM OSS Sonatype jira info From 0dee1d9e5d3b8c32595ae0c624b429b435efd121 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Nov 2019 07:53:21 +0100 Subject: [PATCH 0900/1786] Test single travis jdk declaration --- .travis.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 36b14da11..c6867cc8f 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,9 @@ language: java cache: directories: - $HOME/.m2 +jdk: + - openjdk11 + - openjdk8 env: global: # HCOM OSS Sonatype jira info @@ -17,20 +20,17 @@ jobs: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" - jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" - jdk: openjdk8 if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" - jdk: openjdk8 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -47,7 +47,6 @@ jobs: ### JDK11 release - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" - jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -63,7 +62,6 @@ jobs: ### JDK8 release - stage: "JDK8 Release" name: "Releasing artifacts for JDK8" - jdk: openjdk8 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk8$ script: skip before_deploy: From b4b835165308031492abe7ec9b32d792eec98b55 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Nov 2019 07:58:13 +0100 Subject: [PATCH 0901/1786] removed single travis jdk declaration --- .travis.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c6867cc8f..36b14da11 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,6 @@ language: java cache: directories: - $HOME/.m2 -jdk: - - openjdk11 - - openjdk8 env: global: # HCOM OSS Sonatype jira info @@ -20,17 +17,20 @@ jobs: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" + jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" + jdk: openjdk8 if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" + jdk: openjdk8 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -47,6 +47,7 @@ jobs: ### JDK11 release - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" + jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -62,6 +63,7 @@ jobs: ### JDK8 release - stage: "JDK8 Release" name: "Releasing artifacts for JDK8" + jdk: openjdk8 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk8$ script: skip before_deploy: From 0882a0eb18619a51f5de1e1764f9486cb6cf026f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Nov 2019 07:59:58 +0100 Subject: [PATCH 0902/1786] testing single travis jdk declaration --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 36b14da11..5837dd2e8 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,9 @@ language: java cache: directories: - $HOME/.m2 +jdk: + - openjdk11 + - openjdk8 env: global: # HCOM OSS Sonatype jira info @@ -17,20 +20,17 @@ jobs: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" - jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" - jdk: openjdk8 if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" - jdk: openjdk8 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -47,7 +47,6 @@ jobs: ### JDK11 release - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" - jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: From 04b5da2c585448eb5124cdc3cb0e221284c1f6f0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Nov 2019 08:06:34 +0100 Subject: [PATCH 0903/1786] added jdk switcher --- .travis.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5837dd2e8..74ce32f8e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -22,17 +22,20 @@ jobs: name: "JDK11 Build and Test" if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: + - jdk_switcher use openjdk11 - travis_retry mvn clean install ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: + - jdk_switcher use openjdk8 - travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ - script: skip + script: + - jdk_switcher use openjdk11 before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release @@ -48,7 +51,8 @@ jobs: - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ - script: skip + script: + - jdk_switcher use openjdk11 before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} @@ -62,9 +66,9 @@ jobs: ### JDK8 release - stage: "JDK8 Release" name: "Releasing artifacts for JDK8" - jdk: openjdk8 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk8$ - script: skip + script: + - jdk_switcher use openjdk11 before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} From 865974fd83ee6122d1c0ea52f71770c6576beb35 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 23 Nov 2019 08:18:04 +0100 Subject: [PATCH 0904/1786] restored travis config --- .travis.yml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 74ce32f8e..36b14da11 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,6 @@ language: java cache: directories: - $HOME/.m2 -jdk: - - openjdk11 - - openjdk8 env: global: # HCOM OSS Sonatype jira info @@ -20,22 +17,22 @@ jobs: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" + jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - - jdk_switcher use openjdk11 - travis_retry mvn clean install ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" + jdk: openjdk8 if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - - jdk_switcher use openjdk8 - travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" + jdk: openjdk8 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ - script: - - jdk_switcher use openjdk11 + script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release @@ -50,9 +47,9 @@ jobs: ### JDK11 release - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" + jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ - script: - - jdk_switcher use openjdk11 + script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} @@ -66,9 +63,9 @@ jobs: ### JDK8 release - stage: "JDK8 Release" name: "Releasing artifacts for JDK8" + jdk: openjdk8 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk8$ - script: - - jdk_switcher use openjdk11 + script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} From 33e2d413f5ffa0e3b1cda4bec6eb525ed0ff0411 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Nov 2019 08:03:26 +0100 Subject: [PATCH 0905/1786] Completed automatic release for jdk8 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 36b14da11..f7c6ded89 100755 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ jobs: - travis_retry mvn clean install - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" - jdk: openjdk8 + jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -69,7 +69,7 @@ jobs: before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate + - mvn install javadoc:aggregate -P default,site-release deploy: - provider: script script: config/travis/deploy.sh From ae08c58da622a586189dc371b6b80a479313dae7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 26 Nov 2019 15:26:15 +0100 Subject: [PATCH 0906/1786] Implemented release instruction --- README.md | 4 + RELEASE.md | 235 +++++++++++++++++++++++++---------------------------- 2 files changed, 116 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index 85e10057d..4c99a0859 100644 --- a/README.md +++ b/README.md @@ -814,6 +814,10 @@ The application's logo has been designed by: Rob Light. - DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) - InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[PT-BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] +## Release + +All the instructions for releasing a new version are available at: [RELEASES.md](RELEASE.md) + ## Legal This project is available under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html). diff --git a/RELEASE.md b/RELEASE.md index 30f012507..c3df9a3bc 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -10,190 +10,179 @@ Make the following checks before performing a release: * Do all unit tests pass? * Do all examples work? * Does documentation build? - + * Have the new features been applied on a separate branch with compatibility with `jdk8? #### 2. Update VERSION and CHANGELOG -##### Increment the version number. +#### Increment the version number. -The version number is in the [`VERSION`](VERSION) file. This is picked up by the documentation build process. +The application is released with the compatibility for both: `jdk11` and `jdk8`, the latest version number are: +in the [CHANGELOG](CHANGELOG.md) file for `jdk11` and [CHANGELOG-JDK](CHANGELOG-JDK8.md) file for `jdk8`. -It consists of two lines. The first carries the version number. The structure is: *major* **.** *minor* **.** *revision*. -The *revision* part is *not included* if it is zero '0' (just after a *major* or *minor* increment). +The version number structure is: *major* **.** *minor* **.** *revision*. * *major* = significant incompatible change (e.g. partial or whole rewrite). * *minor* = some new functionality or changes that are mostly/wholly backward compatible. * *revision* = very minor changes, e.g. bugfixes. + +For `jdk8` only, the version number is the same as the `jdk11` one, with the suffix: `-jdk8`. -The 2nd line carries the state - whether this is the "latest" code in the master branch, or whether it is a "release". -Leave this as "latest" for the moment. - - -##### Update the change log - -The is in the [`CHANGELOG.md`](CHANGELOG.md) file. Ensure it mentions any noteworthy changes since the previous release. - - -#### 3. Create release branch - -Create the branch, naming it after the release version number (just the number). - -In the branch, now modify (and commit) the VERSION file, changing "latest" to "release". - - -#### 4. Create a new release on GitHub based on the new branch +e.g. if the new release version would be `1.8.0` then the `jdk8` correspondent one is: `1.8.0-jdk8 -Put a shorter summary of the new changelog items into the release notes. Make the tag name the version number -- the same as the branch name. +#### Update the change log +The changes, that are going to be released, needs to be specified in the `CHANGELOG` file. +Ensure it mentions any noteworthy changes since the previous release. -#### 5. Update documentation builds on gh-pages +Make the following check before performing a release: +* Add the version is going to be released +* Place the release date next to the version number (the format is: `yyyy.mm.dd`) +* Specify under the `### Added` label everything that has been introduced by the new version +* Specify under the `### Changed` label everything that has been changed in the new version +* Specify under the `### Removed` label everything that has been removed in the new version -Run the documentation build process to build documentation for: +the same changes must be reported in [CHANGELOG-JDK](CHANGELOG-JDK8.md) -* This new "release" branch ("new") -* *master* branch ("latest") +#### 3. Prepare the jdk8 release -Note that these are slightly different (because of the 2nd line in the `VERSION` file) +All the changes implemented needs to be reported to the `jdk8` compatible version. +The BULL code for the `jdk8` is slightly different so all the changes needs to be reported on the other version starting +from it's latest release tag. +The first thing to do is to create a branch (that would have the same name as the `jdk11` one plus the suffix: `-jd8`) +starting from the latest `jdk8` release tag: -Checkout the [gh-pages](https://github.com/bbc/dial-discovery-ios/tree/gh-pages) branch and make the following commits: +~~~ +$ git checkout -b [branch name]-jdk8 [latest jdk8 release tag] +~~~ -* replace the contents of [`docs/latest`](https://github.com/bbc/dial-discovery-ios/tree/gh-pages/docs/latest) - with the documentation build for the "latest" state of master. +e.g. if the latest `jdk8` release tag is: `1.7.0-jdk8` and the new feature branch is: `feature/my-new-feature` +the command to perform is: -* put into `docs/XXXX` the documentation build for the "new" release branch, where XXXX is the version number +~~~ +$ git checkout -b feature/my-new-feature-jdk8 1.7.0-jdk8 +~~~ -Then push the commits up to GitHub. +**IMPORTANT:** In the new branch, apply only the changes introduced comparing the code with the `jdk11` branch. -#### 6. Release new CocoaPod version - -The process originally followed to register and setup first time was [this one](https://code.tutsplus.com/tutorials/creating-your-first-cocoapod--cms-24332). You need to be registered with CocoaPods Trunk -repository to be able to publish a pod. Instructions to register with CocoaPods Trunk are available [here](https://guides.cocoapods.org/making/getting-setup-with-trunk.html) - - -For subsequent releases, increment the version number in the PodSpec file and push the new pod version . - - $ pod trunk push dial-discovery-ios.podspec - - -- - - - - +when completed, commit your code and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. ## Example of release process sequence -This example assumes your local repository is a clone and the working copy is currently at the head of the master branch, and that this is all -synced with GitHub. The following steps will do a release "X.Y.Z" - - $ git status - On branch master - Your branch is up-to-date with 'origin/master'. - nothing to commit, working directory clean - -### 1. Run checks - -Run unit tests: - - $ xcodebuild test -workspace Example/dial-discovery-ios.xcworkspace -scheme dial-discovery-ios-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty - $ pod lib lint +The following examples assume that your local repository is: +* a clone and the working copy is currently at the head of the master branch +* is all synced with GitHub +* the Pull Request has been approved and merged on master -Also check the documentation builds: +### JDK8 - $ cd docs - $ jazzy --config jazzy.yaml +The following steps will do a release "`X.Y.Z-jdk8`" -... and manually review areas where it will have changed +~~~ +$ git status +On branch master +Your branch is up-to-date with 'origin/master'. +nothing to commit, working directory clean +~~~ -And run all examples and check they work! +#### 1. Create a branch from the latest JDK8 release tag +Assuming that: +* the latest release for `jdk8` was: `A.B.C-jdk8` +* your new feature branch is: `feature/my-new-feature` +* the new release version is: `X.Y.Z-jdk8` -### 2. Update VERSION and CHANGELOG +the release branch would be: `release/my-new-feature-jdk8` -Update the version number in `master`, e.g. using `vi`: +~~~ +$ git checkout -b release/my-new-feature-jdk8 A.B.C-jdk8 +~~~ - $ vi VERSION - .. change version number line only .. - $ vi CHANGELOG.md - .. update change log .. - $ git add VERSION - $ git add CHANGELOG.md - $ git commit -m "Version number increment and Changelog update ready for release" +#### 2. Apply the changes to the new branch -And push to GitHub: +Apply all the changes you implemented to this branch. - $ git push origin master +#### 3. Change the maven version -### 3. Create release branch +The maven version is now set with the latest released, but you need to change it with the new one you are going to release: -Create new branch (locally) +~~~ +$ mvn versions:set -D newVersion=X.Y.Z-jdk8 +~~~ - $ git checkout -b 'X.Y.Z' +Commit all the changes. -Update VERSION to mark as "release" within the branch +#### 4. Create a new tag for the release version - $ vi VERSION - .. change "latest" to "release" - $ git add VERSION - $ git commit -m "Version marked as release." +Once you will have created the tag, and pushed it to the remote repo, an automatic release will be performed by Travis. -Push branch up to github (and set local repository to track the upstream branch on origin): +~~~ +$ git tag -a X.Y.Z-jdk8 -m "my version X.Y.Z-jdk8" +$ git push origin --tags +~~~ - $ git push -u origin 'X.Y.Z' +#### 5. Remove the no longer needed branch +If the release went successfully, you can now delete the branch: -### 4. Create a new release on GitHub based on the new branch +~~~ +$ git branch -D release/my-new-feature-jdk8 +$ git push --delete release/my-new-feature-jdk8 +~~~ -Now use the [new release](https://github.com/bbc/dial-discovery-ios/releases/new) function on GitHub's web interface to -mark the branch 'X.Y.Z' as a new release. +**IMPORTANT:** In case something goes wrong, do not leave ghost tags or tags not related to a successful release. -### 5. Update documentation builds on gh-pages +### JDK11 -First, build and copy the documentation for the release and stash it somewhere temporarily. +The following steps will do a release "`X.Y.Z`" - $ git status - On branch X.Y.Z - Your branch is up-to-date with 'origin/master'. - nothing to commit, working directory clean +~~~ +$ git status +On branch master +Your branch is up-to-date with 'origin/master'. +nothing to commit, working directory clean +~~~ - $ cd docs - $ jazzy --config jazzy.yaml - $ cp -R build/ /tmp/X.Y.Z +#### 1. Create a branch from the master branch -Now switch back to master and do the same for the latest state of master: +Assuming that: - $ git checkout master - $ jazzy --config jazzy.yaml - $ cp -R build/ tmp/latest - $ cd .. +* the latest release for `jdk11` was: `A.B.C` +* your new feature branch is: `feature/my-new-feature` +* the new release version is: `X.Y.Z` -Now switch to gh-pages and ensure it is synced with GitHub: +the release branch would be: `release/my-new-feature` - $ git checkout gh-pages - $ git pull origin gh-pages +~~~ +$ git checkout -b release/my-new-feature +~~~ -And put the new documentation builds in place: +#### 2. Change the maven version - $ cp -R /tmp/X.Y.Z docs/X.Y.Z - $ git add docs/X.Y.Z +The maven version is now set with the latest released, but you need to change it with the new one you are going to release: - $ git rm docs/latest - $ cp -R /tmp/latest docs/latest - $ git add docs/latest +~~~ +$ mvn versions:set -D newVersion=X.Y.Z +~~~ - $ git commit -m "Updated docs for new release and latest changes in master" +Commit all the changes. -At this point the `docs` dir should contain: +#### 3. Create a new tag for the release version -* a subdir `X.Y.Z` (named after the release version) containing the HTML documentation for - that version. `index.html` should describe the release version as being *"X.Y.Z-release"* +Once you will have created the tag, and pushed it to the remote repo, an automatic release will be performed by Travis. -* a subdir `latest` containing the HTML documentation built from *master*. `index.html` should describe the - release version as being *"X.Y.Z-latest"* +~~~ +$ git tag -a X.Y.Z -m "my version X.Y.Z" +$ git push origin --tags +~~~ -Push to GitHub: +#### 4. Remove the no longer needed branch - $ git push origin gh-pages +If the release went successfully, you can now delete the branch: -Upload to CocoaPods Trunk: +~~~ +$ git branch -D release/my-new-feature +$ git push --delete release/my-new-feature-jdk8 +~~~ - $ git checkout <> - $ pod trunk push dial-discovery-ios.podspec \ No newline at end of file +**IMPORTANT:** In case something goes wrong, do not leave ghost tags or tags not related to a successful release. \ No newline at end of file From 7403e1f545dbf27592166d9d22a08ebed64bb024 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 26 Nov 2019 15:37:55 +0100 Subject: [PATCH 0907/1786] - Release process documentation refactoring - Reviewed PR checklist --- PULL_REQUEST_TEMPLATE.md | 3 +++ RELEASE.md | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 7e56dadeb..9870c7a5a 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -28,3 +28,6 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] Any dependent changes have been merged and published in downstream modules - [ ] My changes have no bad impacts on performances - [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file +- [ ] Any implemented change has been added in the [CHANGELOG-JDK8.md](./CHANGELOG-JDK8.md) file +- [ ] My changes have been applied on a separate branch too with compatibility with Java 8. Follow this (instructions)[https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#3-prepare-the-jdk8-release] for help. +- [ ] The maven version has been increased. diff --git a/RELEASE.md b/RELEASE.md index c3df9a3bc..0d10a8e85 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,4 +1,4 @@ -# Release process for BULL +# Release process ## Explanation of the process sequence @@ -10,7 +10,7 @@ Make the following checks before performing a release: * Do all unit tests pass? * Do all examples work? * Does documentation build? - * Have the new features been applied on a separate branch with compatibility with `jdk8? + * Have the new features been applied on a separate branch with compatibility with `jdk8`? #### 2. Update VERSION and CHANGELOG @@ -26,7 +26,7 @@ The version number structure is: *major* **.** *minor* **.** *revision*. For `jdk8` only, the version number is the same as the `jdk11` one, with the suffix: `-jdk8`. -e.g. if the new release version would be `1.8.0` then the `jdk8` correspondent one is: `1.8.0-jdk8 +e.g. if the new release version would be `1.8.0` then the `jdk8` correspondent one is: `1.8.0-jdk8` #### Update the change log @@ -62,8 +62,7 @@ $ git checkout -b feature/my-new-feature-jdk8 1.7.0-jdk8 ~~~ **IMPORTANT:** In the new branch, apply only the changes introduced comparing the code with the `jdk11` branch. - -when completed, commit your code and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. +When completed, commit your code and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. ## Example of release process sequence @@ -73,6 +72,11 @@ The following examples assume that your local repository is: * is all synced with GitHub * the Pull Request has been approved and merged on master +* [JDK8](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk8) +* [JDK11](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk11) + +**IMPORTANT:** In case something goes wrong, do not leave ghost tags or tags not related to a successful release. + ### JDK8 The following steps will do a release "`X.Y.Z-jdk8`" @@ -130,8 +134,6 @@ $ git branch -D release/my-new-feature-jdk8 $ git push --delete release/my-new-feature-jdk8 ~~~ -**IMPORTANT:** In case something goes wrong, do not leave ghost tags or tags not related to a successful release. - ### JDK11 The following steps will do a release "`X.Y.Z`" @@ -183,6 +185,4 @@ If the release went successfully, you can now delete the branch: ~~~ $ git branch -D release/my-new-feature $ git push --delete release/my-new-feature-jdk8 -~~~ - -**IMPORTANT:** In case something goes wrong, do not leave ghost tags or tags not related to a successful release. \ No newline at end of file +~~~ \ No newline at end of file From 338d8786f0fdb6d931b1a33f38f716134610c614 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 27 Nov 2019 11:36:25 +0100 Subject: [PATCH 0908/1786] Modified release guide --- RELEASE.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 0d10a8e85..cbeaa92ae 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -17,7 +17,7 @@ Make the following checks before performing a release: #### Increment the version number. The application is released with the compatibility for both: `jdk11` and `jdk8`, the latest version number are: -in the [CHANGELOG](CHANGELOG.md) file for `jdk11` and [CHANGELOG-JDK](CHANGELOG-JDK8.md) file for `jdk8`. +in the [CHANGELOG.md](CHANGELOG.md) file for `jdk11` and [CHANGELOG-JDK8.md](CHANGELOG-JDK8.md) file for `jdk8`. The version number structure is: *major* **.** *minor* **.** *revision*. * *major* = significant incompatible change (e.g. partial or whole rewrite). @@ -26,7 +26,7 @@ The version number structure is: *major* **.** *minor* **.** *revision*. For `jdk8` only, the version number is the same as the `jdk11` one, with the suffix: `-jdk8`. -e.g. if the new release version would be `1.8.0` then the `jdk8` correspondent one is: `1.8.0-jdk8` +e.g. if the new release version would be `X.Y.Z` then the `jdk8` correspondent one is: `X.Y.Z-jdk8` #### Update the change log @@ -40,13 +40,15 @@ Make the following check before performing a release: * Specify under the `### Changed` label everything that has been changed in the new version * Specify under the `### Removed` label everything that has been removed in the new version -the same changes must be reported in [CHANGELOG-JDK](CHANGELOG-JDK8.md) +the same changes must be reported in [CHANGELOG-JDK8.md](CHANGELOG-JDK8.md) #### 3. Prepare the jdk8 release -All the changes implemented needs to be reported to the `jdk8` compatible version. +All the changes implemented needs to be reported to a `jdk8` compatible version. + The BULL code for the `jdk8` is slightly different so all the changes needs to be reported on the other version starting from it's latest release tag. + The first thing to do is to create a branch (that would have the same name as the `jdk11` one plus the suffix: `-jd8`) starting from the latest `jdk8` release tag: @@ -72,12 +74,14 @@ The following examples assume that your local repository is: * is all synced with GitHub * the Pull Request has been approved and merged on master -* [JDK8](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk8) -* [JDK11](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk11) +The guide explains how to do a release both the `jdk11` and `jdk8` compatible: + +* [JDK8 Release](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk8) +* [JDK11 Release](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk11) **IMPORTANT:** In case something goes wrong, do not leave ghost tags or tags not related to a successful release. -### JDK8 +### JDK8 Release The following steps will do a release "`X.Y.Z-jdk8`" @@ -134,7 +138,7 @@ $ git branch -D release/my-new-feature-jdk8 $ git push --delete release/my-new-feature-jdk8 ~~~ -### JDK11 +### JDK11 Release The following steps will do a release "`X.Y.Z`" From 777faca82efb6c0bc93e432d97392dd3c8c5cdaf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 27 Nov 2019 11:37:01 +0100 Subject: [PATCH 0909/1786] Modified link --- RELEASE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index cbeaa92ae..c3700b483 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -76,8 +76,8 @@ The following examples assume that your local repository is: The guide explains how to do a release both the `jdk11` and `jdk8` compatible: -* [JDK8 Release](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk8) -* [JDK11 Release](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk11) +* [JDK8 Release](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk8-release) +* [JDK11 Release](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk11-release) **IMPORTANT:** In case something goes wrong, do not leave ghost tags or tags not related to a successful release. From 1a27f7ca6a53e8b47223e9660d182cc252fdbb4e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 27 Nov 2019 11:46:18 +0100 Subject: [PATCH 0910/1786] Updating release process instructions --- CHANGELOG-JDK8.md | 4 ++++ RELEASE.md | 1 + 2 files changed, 5 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index d09457d4a..6c0e6c800 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.6.1.1-jdk8] 2019.11.27 +#### Changed +* Aligned `jdk8` version to the `jdk11` one + ### [1.1.27] 2019.11.22 #### Changed * Removed warning leg message in case the constructor parameter names are not available in the compiled code. diff --git a/RELEASE.md b/RELEASE.md index c3700b483..8d0775053 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -104,6 +104,7 @@ the release branch would be: `release/my-new-feature-jdk8` ~~~ $ git checkout -b release/my-new-feature-jdk8 A.B.C-jdk8 +$ git push --set-upstream origin release/my-new-feature-jdk8 ~~~ #### 2. Apply the changes to the new branch From f89b65669fc4342445e768ca1db17b07752d9510 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 27 Nov 2019 11:50:20 +0100 Subject: [PATCH 0911/1786] Add the Travis build link in the release file --- RELEASE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 8d0775053..db8837dd5 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -109,7 +109,7 @@ $ git push --set-upstream origin release/my-new-feature-jdk8 #### 2. Apply the changes to the new branch -Apply all the changes you implemented to this branch. +Apply all the changes you implemented to this branch. #### 3. Change the maven version @@ -119,7 +119,7 @@ The maven version is now set with the latest released, but you need to change it $ mvn versions:set -D newVersion=X.Y.Z-jdk8 ~~~ -Commit all the changes. +Commit all the changes and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. #### 4. Create a new tag for the release version @@ -172,7 +172,7 @@ The maven version is now set with the latest released, but you need to change it $ mvn versions:set -D newVersion=X.Y.Z ~~~ -Commit all the changes. +Commit all the changes and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. #### 3. Create a new tag for the release version From da9c9ac03569a0e08226a8fcbd295abc7fc3e8a0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 27 Nov 2019 15:10:38 +0100 Subject: [PATCH 0912/1786] Added maven "quite" option to reduce the number of lines logged --- .travis.yml | 14 +++++++------- config/travis/deploy.sh | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index f7c6ded89..03d948cc7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ jobs: jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - - travis_retry mvn clean install + - travis_retry mvn clean install -q ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" @@ -34,8 +34,8 @@ jobs: if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release + - mvn versions:set -D newVersion=${TRAVIS_TAG} -q + - travis_retry mvn install -q sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release deploy: provider: pages local-dir: target/site @@ -52,8 +52,8 @@ jobs: script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate + - mvn versions:set -D newVersion=${TRAVIS_TAG} -q + - mvn install -q -DskipTests -Dmaven.test.skip=true javadoc:aggregate deploy: - provider: script script: config/travis/deploy.sh @@ -68,8 +68,8 @@ jobs: script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} - - mvn install javadoc:aggregate -P default,site-release + - mvn versions:set -D newVersion=${TRAVIS_TAG} -q + - mvn install -q javadoc:aggregate -P default,site-release deploy: - provider: script script: config/travis/deploy.sh diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index d1344d580..32ce2141f 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -q -P default,release -DskipTests=true else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -q -P default,release -DskipTests=true fi fi \ No newline at end of file From 44b5f960a3ca5ce1a3db259283bd175b6f782026 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 27 Nov 2019 17:51:37 +0100 Subject: [PATCH 0913/1786] Preparing release --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 6c0e6c800..472f5045e 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.1.1-jdk8] 2019.11.27 +### [1.6.2-jdk8] 2019.11.27 #### Changed * Aligned `jdk8` version to the `jdk11` one diff --git a/CHANGELOG.md b/CHANGELOG.md index 8481b241b..22f3a7790 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.1.1] 2019.11.22 +### [1.6.2] 2019.11.22 #### Changed * Removed warning leg message in case the constructor parameter names are not available in the compiled code. * Removed `slf4j-api` dependency from the library jar. From 4f4fe7623d1737418767d1951c08aa38d35f82f7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 27 Nov 2019 20:25:58 +0100 Subject: [PATCH 0914/1786] [maven-release-plugin] prepare release 1.6.2 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 884426fea..7f8acc366 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.2-SNAPSHOT + 1.6.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 760bd0f39..4c761fe8d 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.2-SNAPSHOT + 1.6.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 6978f470f..80b42c63b 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.2-SNAPSHOT + 1.6.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 604fe94e4..1960eaee7 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.2-SNAPSHOT + 1.6.2 diff --git a/pom.xml b/pom.xml index 37200b881..201df5ddd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.2-SNAPSHOT + 1.6.2 pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.2 From c5237b0e4aa33812d3686c6930eab24fdabceb78 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 27 Nov 2019 20:26:07 +0100 Subject: [PATCH 0915/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 7f8acc366..0567c2817 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.2 + 1.6.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 4c761fe8d..5681e929e 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.2 + 1.6.3-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 80b42c63b..545e044ba 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.2 + 1.6.3-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 1960eaee7..7888abd5a 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.2 + 1.6.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index 201df5ddd..fc9cb434f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.2 + 1.6.3-SNAPSHOT pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.2 + HEAD From 66efc6f9b5990629583ebd94f9609fdd4f49e415 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 29 Nov 2019 07:23:45 +0100 Subject: [PATCH 0916/1786] Updated maven wrapper version to 3.6.3 (was 3.6.2) --- .mvn/wrapper/maven-wrapper.properties | 2 +- CHANGELOG-JDK8.md | 4 ++++ CHANGELOG.md | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 4b38d3904..76655c7c1 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,4 +1,4 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip wrapper.url=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar # Path where the maven-wrapper.jar will be saved to. diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 472f5045e..4cffaedbe 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.6.3-jdk8] TBD +#### Changed +* Updated maven wrapper version to `3.6.3` (was `3.6.2`). + ### [1.6.2-jdk8] 2019.11.27 #### Changed * Aligned `jdk8` version to the `jdk11` one diff --git a/CHANGELOG.md b/CHANGELOG.md index 22f3a7790..75f058d1e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.6.3] TBD +#### Changed +* Updated maven wrapper version to `3.6.3` (was `3.6.2`). + ### [1.6.2] 2019.11.22 #### Changed * Removed warning leg message in case the constructor parameter names are not available in the compiled code. From 80cfd5e0c4077c425206b21df60df265898fa5d1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 30 Nov 2019 06:42:01 +0100 Subject: [PATCH 0917/1786] Modified travis configuration in order to don't print out in the log all the dependencies download made from maven. This would avoid that the Travis build fails due to the log limit that is exceeded --- .travis.yml | 16 ++++++++-------- .../src/main/resources/logback.xml | 2 +- .../src/main/resources/logback.xml | 2 +- config/travis/deploy.sh | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 03d948cc7..fc7fbb72d 100755 --- a/.travis.yml +++ b/.travis.yml @@ -20,22 +20,22 @@ jobs: jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - - travis_retry mvn clean install -q + - travis_retry mvn clean install -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" jdk: openjdk8 if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - - travis_retry mvn clean install + - travis_retry mvn clean install -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} -q - - travis_retry mvn install -q sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release + - mvn versions:set -D newVersion=${TRAVIS_TAG} -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - travis_retry mvn install -q sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn deploy: provider: pages local-dir: target/site @@ -52,8 +52,8 @@ jobs: script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} -q - - mvn install -q -DskipTests -Dmaven.test.skip=true javadoc:aggregate + - mvn versions:set -D newVersion=${TRAVIS_TAG} -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn deploy: - provider: script script: config/travis/deploy.sh @@ -68,8 +68,8 @@ jobs: script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} -q - - mvn install -q javadoc:aggregate -P default,site-release + - mvn versions:set -D newVersion=${TRAVIS_TAG} -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn install javadoc:aggregate -P default,site-release -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn deploy: - provider: script script: config/travis/deploy.sh diff --git a/bull-bean-transformer/src/main/resources/logback.xml b/bull-bean-transformer/src/main/resources/logback.xml index e5238fa85..4da7aad36 100644 --- a/bull-bean-transformer/src/main/resources/logback.xml +++ b/bull-bean-transformer/src/main/resources/logback.xml @@ -28,7 +28,7 @@ - + diff --git a/bull-map-transformer/src/main/resources/logback.xml b/bull-map-transformer/src/main/resources/logback.xml index 7e554a30c..37cdb1081 100644 --- a/bull-map-transformer/src/main/resources/logback.xml +++ b/bull-map-transformer/src/main/resources/logback.xml @@ -28,7 +28,7 @@ - + diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 32ce2141f..693e3eea2 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -q -P default,release -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -q -P default,release -DskipTests=true + mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn fi fi \ No newline at end of file From d48916ef40f20fcf7a9161d84cf29505bb957451 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 30 Nov 2019 19:09:07 +0100 Subject: [PATCH 0918/1786] Removed quiet property from maven build --- .travis.yml | 14 +++++++------- config/travis/deploy.sh | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index fc7fbb72d..d85947136 100755 --- a/.travis.yml +++ b/.travis.yml @@ -20,22 +20,22 @@ jobs: jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - - travis_retry mvn clean install -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" jdk: openjdk8 if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - - travis_retry mvn clean install -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install -q sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn deploy: provider: pages local-dir: target/site @@ -52,7 +52,7 @@ jobs: script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn deploy: - provider: script @@ -68,8 +68,8 @@ jobs: script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install javadoc:aggregate -P default,site-release -q -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn install javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn deploy: - provider: script script: config/travis/deploy.sh diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index 693e3eea2..a00e33d67 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn fi fi \ No newline at end of file From 57a62a4df793fda8da8872d823f1880d3d5168bc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 30 Nov 2019 19:16:46 +0100 Subject: [PATCH 0919/1786] Added maven quite setting for the javadoc aggregation job --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d85947136..3637b6ff3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: provider: pages local-dir: target/site @@ -53,7 +53,7 @@ jobs: before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: - provider: script script: config/travis/deploy.sh @@ -69,7 +69,7 @@ jobs: before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn install javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: - provider: script script: config/travis/deploy.sh From 0a56f86e5bf50d551468e0fa1d7216aefc64ed0b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 11:47:13 +0100 Subject: [PATCH 0920/1786] Added retry mechanism on the bean injection in case the parameter name are not available in the compiled code. --- CHANGELOG-JDK8.md | 4 +- CHANGELOG.md | 4 +- .../beans/transformer/TransformerImpl.java | 53 ++++++++++++++----- .../transformer/BeanTransformerTest.java | 51 ++++++++++++++++++ 4 files changed, 96 insertions(+), 16 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 4cffaedbe..ec3035e1d 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,9 @@ All notable changes to this project will be documented in this file. -### [1.6.3-jdk8] TBD +### [1.6.3-jdk8] 2019.12.02 +### Added +* Added retry mechanism on the bean injection in case the parameter name are not available in the compiled code. #### Changed * Updated maven wrapper version to `3.6.3` (was `3.6.2`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 75f058d1e..8834d5044 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ All notable changes to this project will be documented in this file. -### [1.6.3] TBD +### [1.6.3] 2019.12.02 +### Added +* Added retry mechanism on the bean injection in case the parameter name are not available in the compiled code. #### Changed * Updated maven wrapper version to `3.6.3` (was `3.6.2`). diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 8cce03ae0..9ccfdb43a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -68,7 +68,7 @@ protected final K transform(final T sourceObj, final Class t throw new InvalidBeanException(e.getMessage(), e); } } else { - k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb); + k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb, false); if (classType.is(MIXED)) { injectNotFinalFields(sourceObj, k, breadcrumb); } @@ -96,14 +96,15 @@ protected final void transform(final T sourceObj, final K targetObject, f * @param targetClass the destination object class * @param constructor the all args constructor * @param breadcrumb the full path of the current field starting from his ancestor + * @param forceConstructorInjection if true it forces the injection trough constructor * @param the sourceObj object type * @param the target object type * @return a copy of the source object into the destination object * @throws InvalidBeanException {@link InvalidBeanException} if the target object is not compliant with the requirements */ - private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { + private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb, final boolean forceConstructorInjection) { final Object[] constructorArgs; - if (canBeInjectedByConstructorParams(constructor, targetClass)) { + if (forceConstructorInjection || canBeInjectedByConstructorParams(constructor, targetClass)) { constructorArgs = getConstructorArgsValues(sourceObj, targetClass, constructor, breadcrumb); } else { constructorArgs = getConstructorValuesFromFields(sourceObj, targetClass, breadcrumb); @@ -111,20 +112,44 @@ private K injectValues(final T sourceObj, final Class targetClass, fin try { return classUtils.getInstance(constructor, constructorArgs); } catch (final Exception e) { - String errorMsg; - if (!classUtils.areParameterNamesAvailable(constructor)) { - errorMsg = "Constructor's parameters name have been removed from the compiled code. " - + "This caused a problems during the: " + targetClass.getSimpleName() + " injection. " - + "Consider to use: @ConstructorArg annotation: https://github.com/HotelsDotCom/bull#different-field-names-defining-constructor-args " - + "or add the property: true to your maven-compiler configuration"; + return handleInjectionException(sourceObj, targetClass, constructor, breadcrumb, constructorArgs, forceConstructorInjection, e); + } + } + + /** + * Handles the exception thrown by method: {@code injectValues}. + * In case an exception is raised due to missing parameter names it tries to inject through the constructor anyway. + * @param sourceObj sourceObj the source object + * @param targetClass the destination object class + * @param constructor the all args constructor + * @param breadcrumb the full path of the current field starting from his ancestor + * @param constructorArgs the constructor arguments + * @param forceConstructorInjection if true it forces the injection trough constructor + * @param e the raised exception + * @param the sourceObj object type + * @param the target object type + * @return a copy of the source object into the destination object + * @throws InvalidBeanException {@link InvalidBeanException} if the target object is not compliant with the requirements + */ + private K handleInjectionException(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb, + final Object[] constructorArgs, final boolean forceConstructorInjection, final Exception e) { + String errorMsg; + if (!classUtils.areParameterNamesAvailable(constructor)) { + if (!forceConstructorInjection) { + return injectValues(sourceObj, targetClass, constructor, breadcrumb, true); } else { - errorMsg = "Constructor invoked with wrong arguments. Expected: " + constructor + "; Found: " - + getFormattedConstructorArgs(targetClass, constructorArgs) - + ". Double check that each " + targetClass.getSimpleName() + "'s field have the same type and name than the source object: " - + sourceObj.getClass().getName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(); + errorMsg = "Constructor's parameters name have been removed from the compiled code. " + + "This caused a problems during the: " + targetClass.getSimpleName() + " injection. " + + "Consider to use: @ConstructorArg annotation: https://github.com/HotelsDotCom/bull#different-field-names-defining-constructor-args " + + "or add the property: true to your maven-compiler configuration"; } - throw new InvalidBeanException(errorMsg, e); + } else { + errorMsg = "Constructor invoked with wrong arguments. Expected: " + constructor + "; Found: " + + getFormattedConstructorArgs(targetClass, constructorArgs) + + ". Double check that each " + targetClass.getSimpleName() + "'s field have the same type and name than the source object: " + + sourceObj.getClass().getName() + " otherwise specify a transformer configuration. Error message: " + e.getMessage(); } + throw new InvalidBeanException(errorMsg, e); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 1b0bfc36c..760d960ec 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -35,6 +35,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -43,6 +44,7 @@ import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooAdvFields; import com.hotels.transformer.cache.CacheManager; import com.hotels.transformer.error.InvalidBeanException; @@ -66,6 +68,7 @@ public class BeanTransformerTest extends AbstractBeanTransformerTest { private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; private static final String GET_TRANSFORMER_VALUE_METHOD_NAME = "getTransformedValue"; private static final String GET_CONSTRUCTOR_ARGS_VALUES_METHOD_NAME = "getConstructorArgsValues"; + private static final String HANDLE_INJECTION_EXCEPTION_METHOD_NAME = "handleInjectionException"; /** * Test that is possible to remove a field mapping for a given field. @@ -495,4 +498,52 @@ private Object[][] dataConversionAnalyzerInitializationTesting() { {"Tests that the ConversionAnalyzer object is created if the automatic conversion is enabled", true, false} }; } + + /** + * Test that the method: {@code handleInjectionException} works as expected. + * @param testCaseDescription the test case description + * @param forceConstructorInjection if true it forces the injection trough constructor + * @param expectedReturnType the expected return type class + * @throws Exception if the invoke method fails + */ + @Test(dataProvider = "dataHandleInjectionExceptionTesting") + public void testHandleInjectionExceptionWorksAsExpected(final String testCaseDescription, final boolean forceConstructorInjection, + final Class expectedReturnType) throws Exception { + //GIVEN + ClassUtils classUtils = mock(ClassUtils.class); + when(classUtils.areParameterNamesAvailable(any(Constructor.class))).thenReturn(false); + when(classUtils.getConstructorParameters(any())).thenReturn(new Parameter[] {}); + when(classUtils.getInstance(any(), any())).thenReturn(new MutableToFoo()); + setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + + Method handleInjectionExceptionMethod = underTest.getClass().getDeclaredMethod(HANDLE_INJECTION_EXCEPTION_METHOD_NAME, Object.class, + Class.class, Constructor.class, String.class, Object[].class, boolean.class, Exception.class); + handleInjectionExceptionMethod.setAccessible(true); + + //WHEN + Object actual; + try { + actual = handleInjectionExceptionMethod.invoke(underTest, fromFoo, MutableToFoo.class, null, "", null, forceConstructorInjection, new Exception()); + } catch (InvocationTargetException e) { + actual = e.getTargetException(); + } + + //THEN + assertNotNull(actual); + assertEquals(expectedReturnType, actual.getClass()); + restoreUnderTestObject(); + } + + /** + * Creates the parameters to be used for testing the method {@code handleInjectionExceptionTesting}. + * @return parameters to be used for testing the the method {@code handleInjectionExceptionTesting}. + */ + @DataProvider + private Object[][] dataHandleInjectionExceptionTesting() { + return new Object[][] { + {"Tests that the handleInjectionException returns an error message if the forceConstructorInjection is true", true, InvalidBeanException.class}, + {"Tests that the handleInjectionException invokes the injectValues (that throws a MutableToFoo object) if the forceConstructorInjection is false", + false, MutableToFoo.class} + }; + } } From 698a7a6dc9ee4467fa6d7f26c3eb5368af6a775d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 12:06:47 +0100 Subject: [PATCH 0921/1786] minor: fixed typo in the change log file --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index ec3035e1d..cfb3bdf37 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.6.3-jdk8] 2019.12.02 ### Added -* Added retry mechanism on the bean injection in case the parameter name are not available in the compiled code. +* Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. #### Changed * Updated maven wrapper version to `3.6.3` (was `3.6.2`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 8834d5044..55fcd75ca 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.6.3] 2019.12.02 ### Added -* Added retry mechanism on the bean injection in case the parameter name are not available in the compiled code. +* Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. #### Changed * Updated maven wrapper version to `3.6.3` (was `3.6.2`). From 7bb69ad2d1356bc7d4060971c7f389c09feb9407 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 12:10:18 +0100 Subject: [PATCH 0922/1786] [maven-release-plugin] prepare release 1.6.3 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 0567c2817..4dc6928f9 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3-SNAPSHOT + 1.6.3 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 5681e929e..7646c9158 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3-SNAPSHOT + 1.6.3 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 545e044ba..0fdbfad87 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3-SNAPSHOT + 1.6.3 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 7888abd5a..58668dc29 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.3-SNAPSHOT + 1.6.3 diff --git a/pom.xml b/pom.xml index fc9cb434f..51c1a07ab 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.3-SNAPSHOT + 1.6.3 pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.3 From 8f3c4d687bf0125d0a9bbd52cc934662971df686 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 12:10:27 +0100 Subject: [PATCH 0923/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 4dc6928f9..418562f45 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3 + 1.6.4-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 7646c9158..c6157cb28 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3 + 1.6.4-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 0fdbfad87..1a80d605a 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3 + 1.6.4-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 58668dc29..022056e21 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.3 + 1.6.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index 51c1a07ab..d8bb2fe43 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.3 + 1.6.4-SNAPSHOT pom 2019 @@ -72,7 +72,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.3 + HEAD From bf17bbe78b44eadc087c67d6e29d3b2787ff9b51 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 12:21:09 +0100 Subject: [PATCH 0924/1786] minor: removed maven "quiet" option on the site job build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3637b6ff3..fa1d8cc6e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -53,7 +53,7 @@ jobs: before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn deploy: - provider: script script: config/travis/deploy.sh From baac43a2426a9c8031cd8ee30862873a0df1cbac Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 14:24:49 +0100 Subject: [PATCH 0925/1786] - Made the project compatible with the jdk > 11 - Testing multiple jdk testing --- .travis.yml | 7 ++++--- pom.xml | 7 +++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index fa1d8cc6e..41ec005b8 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,10 @@ language: java cache: directories: - $HOME/.m2 +jdk: + - openjdk11 + - openjdk12 + - openjdk13 env: global: # HCOM OSS Sonatype jira info @@ -17,7 +21,6 @@ jobs: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" - jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn @@ -30,7 +33,6 @@ jobs: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" - jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -47,7 +49,6 @@ jobs: ### JDK11 release - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" - jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: diff --git a/pom.xml b/pom.xml index d8bb2fe43..96c420aec 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,7 @@ 0.11 2.8.6 7.0.0 + 1.10.4 1.3.0 2.0.1.Final @@ -162,6 +163,12 @@ + + net.bytebuddy + byte-buddy + ${byte-buddy.version} + test + From 2b5f38be1755e0345c4e5a2703896358da52aeef Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 14:28:11 +0100 Subject: [PATCH 0926/1786] Modified travis config to run the build with multiple jdks --- .travis.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 41ec005b8..a6f453bb8 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,6 @@ language: java cache: directories: - $HOME/.m2 -jdk: - - openjdk11 - - openjdk12 - - openjdk13 env: global: # HCOM OSS Sonatype jira info @@ -21,6 +17,10 @@ jobs: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" + jdk: + - openjdk11 + - openjdk12 + - openjdk13 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn @@ -33,6 +33,7 @@ jobs: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" + jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -49,12 +50,13 @@ jobs: ### JDK11 release - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" + jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: - provider: script script: config/travis/deploy.sh From 6a60a86a8dd89d7b3c2d06352ff02fe33ea5d689 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 14:34:16 +0100 Subject: [PATCH 0927/1786] building with a single jdk --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index a6f453bb8..3637b6ff3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -17,10 +17,7 @@ jobs: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" - jdk: - - openjdk11 - - openjdk12 - - openjdk13 + jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn From 9b85eadf58e3d4fdfbc7d3d1de9aa03b3743190c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 14:48:04 +0100 Subject: [PATCH 0928/1786] Excluded mockito dependency from spring-boot and added specific dependency for it --- pom.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pom.xml b/pom.xml index 96c420aec..2b7fe3c98 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,7 @@ 2.8.6 7.0.0 1.10.4 + 3.2.0 1.3.0 2.0.1.Final @@ -121,6 +122,10 @@ org.mockito mockito-junit-jupiter + + org.mockito + mockito-core + @@ -169,6 +174,12 @@ ${byte-buddy.version} test + + org.mockito + mockito-core + ${mockito-core.version} + test + @@ -190,6 +201,11 @@ testng test + + org.mockito + mockito-core + test + From 314cfedf4f076f6c400e260dd6f3ae81bdf3cf22 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 14:54:46 +0100 Subject: [PATCH 0929/1786] testing multiple jdk build through travis --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3637b6ff3..b85daed6f 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,10 @@ language: java cache: directories: - $HOME/.m2 +jdk: + - openjdk11 + - openjdk12 + - openjdk13 env: global: # HCOM OSS Sonatype jira info @@ -11,13 +15,14 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= +script: skip install: skip jobs: include: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" - jdk: openjdk11 +# jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn From cb30f35ed19cd851750052d02d85e7d6356aa56a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 14:57:35 +0100 Subject: [PATCH 0930/1786] testing single job with multiple jdks --- .travis.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index b85daed6f..a7071a347 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,6 @@ language: java cache: directories: - $HOME/.m2 -jdk: - - openjdk11 - - openjdk12 - - openjdk13 env: global: # HCOM OSS Sonatype jira info @@ -22,7 +18,10 @@ jobs: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" -# jdk: openjdk11 + jdk: + - openjdk11 + - openjdk12 + - openjdk13 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn From eda62f2ba24a1fc9b34fef5dc2cd486a51f5ff87 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 15:03:14 +0100 Subject: [PATCH 0931/1786] Added compatibility check with the newer jdks --- .travis.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index a7071a347..53398442b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,17 +11,18 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -script: skip +# Testing compatibility with newer jdk(s) +jdk: + - openjdk12 + - openjdk13 +script: mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install: skip jobs: include: ### JDK11 build - stage: "JDK11 Build" name: "JDK11 Build and Test" - jdk: - - openjdk11 - - openjdk12 - - openjdk13 + jdk: openjdk11 if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ script: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn From 296e72996bec2bc7ef21c5fffafa7b7b4377dff1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 15:15:05 +0100 Subject: [PATCH 0932/1786] removed not needed byte-buddy dependency --- .travis.yml | 8 +------- pom.xml | 7 ------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 53398442b..718cffe4a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -13,19 +13,13 @@ env: - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) jdk: + - openjdk11 - openjdk12 - openjdk13 script: mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install: skip jobs: include: - ### JDK11 build - - stage: "JDK11 Build" - name: "JDK11 Build and Test" - jdk: openjdk11 - if: branch =~ ^((?!-jdk8).)*$ OR tag =~ ^((?!-jdk8).)*$ - script: - - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" diff --git a/pom.xml b/pom.xml index 2b7fe3c98..f163fcc3c 100644 --- a/pom.xml +++ b/pom.xml @@ -38,7 +38,6 @@ 0.11 2.8.6 7.0.0 - 1.10.4 3.2.0 1.3.0 @@ -168,12 +167,6 @@ - - net.bytebuddy - byte-buddy - ${byte-buddy.version} - test - org.mockito mockito-core From 916b7bc2c319f6c2a848d911ba963cc823b062a5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 15:18:15 +0100 Subject: [PATCH 0933/1786] Added travis retry option --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 718cffe4a..17035f1a5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn +script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install: skip jobs: include: From d7f666f618dbe203fa4e839c97be058c2e5fce4e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 15:34:52 +0100 Subject: [PATCH 0934/1786] Updated changelog with the latest changes --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index cfb3bdf37..2778f4571 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.3-jdk8] 2019.12.02 ### Added * Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. +* Modified Travis configuration in order to test the compatibility with other JDKs versions #### Changed * Updated maven wrapper version to `3.6.3` (was `3.6.2`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 55fcd75ca..527968f6e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.3] 2019.12.02 ### Added * Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. +* Modified Travis configuration in order to test the compatibility with other JDKs versions #### Changed * Updated maven wrapper version to `3.6.3` (was `3.6.2`). From ddf1468afa378797234f5cfcf167b2de81e08c26 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Dec 2019 17:10:14 +0100 Subject: [PATCH 0935/1786] Added apache license into the pom file --- pom.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pom.xml b/pom.xml index f163fcc3c..62557e250 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,20 @@ + 4.0.0 BULL - Bean Utils Light Library From 2e5b6a6f7549bd9a77e201c7f367a61fc77c7509 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 4 Dec 2019 13:36:20 +0100 Subject: [PATCH 0936/1786] Added wildcard type support --- .travis.yml | 2 +- .../beans/transformer/TransformerImpl.java | 9 ++- .../hotels/transformer/utils/ClassUtils.java | 26 +++++++-- .../transformer/utils/ReflectionUtils.java | 56 ++++++++++++++++--- .../transformer/utils/ClassUtilsTest.java | 6 +- pom.xml | 9 +++ 6 files changed, 93 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 17035f1a5..2f8542502 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn +script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: include: diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 9ccfdb43a..2f93851e0 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -553,9 +553,14 @@ private FieldTransformer getPrimitiveTypeTransformer(final Class sourceObject private Object getFieldValue(final Class targetClass, final Field field, final Object fieldValue, final String breadcrumb) { return getPopulator(field.getType(), fieldValue.getClass(), this) .map(populator -> populator.getPopulatedObject(targetClass, field.getName(), fieldValue)) - .orElseGet(() -> + .orElseGet(() -> { // recursively inject object - transform(fieldValue, field.getType(), breadcrumb) + Class concreteType = field.getType(); + if (field.getType().isInterface()) { + concreteType = fieldValue.getClass(); + } + return transform(fieldValue, concreteType, breadcrumb); + } ); } } diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index fd498ad5b..9ba0f3c7c 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -56,9 +56,11 @@ import java.time.temporal.Temporal; import java.util.ArrayList; import java.util.Currency; +import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Properties; import java.util.Set; import java.util.function.Predicate; import java.util.function.Supplier; @@ -157,7 +159,7 @@ public boolean isSpecialType(final Class clazz) { final String cacheKey = "isSpecial-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || Temporal.class.isAssignableFrom(clazz) - || clazz.isSynthetic(); + || clazz.equals(Date.class) || clazz.equals(Properties.class) || clazz.isSynthetic(); CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); @@ -374,9 +376,9 @@ public List getDeclaredFields(final Class clazz, final boolean skipSta stream(getDeclaredFields(clazz)) .filter(field -> !skipStatic || !isStatic(field.getModifiers())) .forEach(field -> { - field.setAccessible(true); - res.add(field); - }); + field.setAccessible(true); + res.add(field); + }); CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); @@ -396,6 +398,22 @@ private Field[] getDeclaredFields(final Class clazz) { }); } + /** + * Returns the concrete class of a field. + * @param field the field for which the concrete class has to be retrieved. + * @param objectInstance the object instance. + * @param the object instance class. + * @return the concrete class of a field + */ + public Class getConcreteClass(final Field field, final T objectInstance) { + final String cacheKey = "ConcreteFieldClass-" + field.getName() + "-" + field.getDeclaringClass(); + return CACHE_MANAGER.getFromCache(cacheKey, Class.class).orElseGet(() -> { + Class res = reflectionUtils.getFieldValue(objectInstance, field).getClass(); + CACHE_MANAGER.cacheObject(cacheKey, res); + return res; + }); + } + /** * Checks if the destination class has accessible constructor. * @param targetClass the destination object class diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index e8dfd324d..6634bd91b 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -22,6 +22,7 @@ import static java.lang.invoke.MethodType.methodType; import static java.lang.reflect.Modifier.isPublic; +import static org.apache.commons.lang3.ArrayUtils.isEmpty; import static org.apache.commons.lang3.StringUtils.capitalize; import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; @@ -39,6 +40,7 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.UndeclaredThrowableException; +import java.lang.reflect.WildcardType; import java.util.List; import java.util.Map; import java.util.Optional; @@ -429,16 +431,48 @@ public Class getGenericFieldType(final Field field) { return CACHE_MANAGER.getFromCache(cacheKey, Class.class).orElseGet(() -> { Class res = null; if (ParameterizedType.class.isAssignableFrom(field.getGenericType().getClass())) { - final Type[] fieldArgTypes = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); - if (fieldArgTypes.length != 0) { - res = (Class) fieldArgTypes[0]; - } + res = getGenericClassType((ParameterizedType) field.getGenericType()); } CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); } + /** + * Retrieves the generic class of a {@link ParameterizedType}. + * @param genericType the generic type for which the class has to be retrieved + * @return the generic class type + */ + private Class getGenericClassType(final ParameterizedType genericType) { + return getGenericClassType(genericType.getActualTypeArguments()); + } + + /** + * Retrieves the generic class of a {@link WildcardType}. + * @param genericType the generic type for which the class has to be retrieved + * @return the generic class type + */ + private Class getGenericClassType(final WildcardType genericType) { + return getGenericClassType(isEmpty(genericType.getLowerBounds()) ? genericType.getUpperBounds() : genericType.getLowerBounds()); + } + + /** + * Retrieves the generic class from the field's argument types. + * @param actualTypeArguments the field type arguments + * @return the generic class type + */ + private Class getGenericClassType(final Type[] actualTypeArguments) { + Class res = null; + if (actualTypeArguments.length != 0) { + if (WildcardType.class.isAssignableFrom(actualTypeArguments[0].getClass())) { + res = getGenericClassType((WildcardType) actualTypeArguments[0]); + } else { + res = (Class) actualTypeArguments[0]; + } + } + return res; + } + /** * Gets the generic infer type of a map object. * @param fieldType the field containing the generic @@ -454,9 +488,15 @@ public MapType getMapGenericType(final Type fieldType, final String declaringCla throw new IllegalArgumentException("Type for object: " + fieldName + " is invalid. " + "It cannot be assigned from: " + Map.class.getName() + "."); } - final ParameterizedType genericType = (ParameterizedType) fieldType; - final MapElemType keyType = getMapElemType(genericType.getActualTypeArguments()[0], declaringClass, fieldName); - final MapElemType elemType = getMapElemType(genericType.getActualTypeArguments()[1], declaringClass, fieldName); + MapElemType keyType, elemType; + if (ParameterizedType.class.isAssignableFrom(fieldType.getClass())) { + final ParameterizedType genericType = (ParameterizedType) fieldType; + keyType = getMapElemType(genericType.getActualTypeArguments()[0], declaringClass, fieldName); + elemType = getMapElemType(genericType.getActualTypeArguments()[1], declaringClass, fieldName); + } else { + keyType = buildItemType(fieldType, declaringClass, fieldName); + elemType = buildItemType(fieldType, declaringClass, fieldName); + } final MapType mapType = new MapType(keyType, elemType); CACHE_MANAGER.cacheObject(cacheKey, mapType); return mapType; @@ -524,6 +564,8 @@ public Class getArgumentTypeClass(final Object argument, final String declari res = getNestedGenericClass ? getArgumentTypeClass(((ParameterizedType) argument).getActualTypeArguments()[0], declaringClass, fieldName, false) : (Class) ((ParameterizedType) argument).getRawType(); + } else if (WildcardType.class.isAssignableFrom(argument.getClass())) { + res = getGenericClassType((WildcardType) argument); } CACHE_MANAGER.cacheObject(cacheKey, res, EmptyValue.class); return res; diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 10a1e1f03..ff4732672 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -35,8 +35,10 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.time.Instant; +import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Properties; import java.util.function.Predicate; import java.util.function.Supplier; @@ -171,7 +173,9 @@ private Object[][] dataSpecialTypeObjectTesting() { return new Object[][] { {"Tests that the method returns true if the class is a special type object", Locale.class, true}, {"Tests that the method returns false if the class is not a special type object", BigDecimal.class, false}, - {"Tests that the method returns true if the class is an instance of Temporal interface", Instant.class, true} + {"Tests that the method returns true if the class is an instance of Temporal interface", Instant.class, true}, + {"Tests that the method returns true if the class is an instance of Properties class", Properties.class, true}, + {"Tests that the method returns true if the class is an instance of Date class", Date.class, true} }; } diff --git a/pom.xml b/pom.xml index 62557e250..cc00e7c4f 100644 --- a/pom.xml +++ b/pom.xml @@ -287,6 +287,15 @@ + + compatibility-mode + + true + + + bull-map-transformer + + release From 99adb26eba3d7f745647207caa1e29d42c76b495 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 6 Dec 2019 17:56:32 +0100 Subject: [PATCH 0937/1786] Implemented getConcreteClass method test --- .../transformer/utils/ClassUtilsTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index ff4732672..dcd555797 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -36,6 +36,7 @@ import java.math.BigInteger; import java.time.Instant; import java.util.Date; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Properties; @@ -904,4 +905,22 @@ private Object[][] dataIsByteArrayTesting() { {"Tests that the method returns false if the class is not a byte[]", byte.class, false} }; } + + /** + * Tests that the method {@code getConcreteClass} works as expected. + * @throws Exception if the field is not retrieved + */ + @Test + public void testGetConcreteClassWorksAsExpected() throws Exception { + // GIVEN + FromFoo fromFoo = new FromFoo(NAME, null, null, new LinkedList<>(), null); + Field listField = fromFoo.getClass().getDeclaredField("list"); + listField.setAccessible(true); + + // WHEN + Class actual = underTest.getConcreteClass(listField, fromFoo); + + // THEN + assertEquals(LinkedList.class, actual); + } } From fd7d5356762e06b2ebbc011efe525503584b0e1d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2019 02:22:32 +0000 Subject: [PATCH 0938/1786] Bump spring-boot-starter-test from 2.2.1.RELEASE to 2.2.2.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.2.1.RELEASE to 2.2.2.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.2.1.RELEASE...v2.2.2.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 62557e250..2da468386 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ 11 ${jdk.version} ${jdk.version} - 2.2.1.RELEASE + 2.2.2.RELEASE 1.18.10 3.9 0.11 From a3bc3a52caabde69c2945902f5f629cfd8da8c89 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 9 Dec 2019 09:37:27 +0100 Subject: [PATCH 0939/1786] Updated changelog --- CHANGELOG-JDK8.md | 4 ++++ CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 2778f4571..c058fbaeb 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.6.4-jdk8] TBD +#### Changed +* Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). + ### [1.6.3-jdk8] 2019.12.02 ### Added * Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. diff --git a/CHANGELOG.md b/CHANGELOG.md index 527968f6e..dffbd3aef 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.6.4.1] 2019.12.09 +#### Changed +* Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). + ### [1.6.3] 2019.12.02 ### Added * Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. From 69eedb62a8f14f369e9808d959c611e12d16df5a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 9 Dec 2019 09:41:42 +0100 Subject: [PATCH 0940/1786] Preparing release --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 418562f45..084813bcf 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.4.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index c6157cb28..e6c647683 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.4.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 1a80d605a..e51d7d775 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.4.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 022056e21..0947ea276 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.4-SNAPSHOT + 1.6.4.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 62557e250..5d73a6264 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.4-SNAPSHOT + 1.6.4.1-SNAPSHOT pom 2019 From d8f7647d5687f350b42a892602d4089169762a11 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 9 Dec 2019 09:42:55 +0100 Subject: [PATCH 0941/1786] Preparing release --- CHANGELOG.md | 2 +- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dffbd3aef..0fe049d0f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.4.1] 2019.12.09 +### [1.6.3.1] 2019.12.09 #### Changed * Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 084813bcf..2f4fe9f01 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4.1-SNAPSHOT + 1.6.3.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e6c647683..4ffe16e7f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4.1-SNAPSHOT + 1.6.3.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index e51d7d775..f63864de2 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4.1-SNAPSHOT + 1.6.3.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0947ea276..d2bc9d456 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.4.1-SNAPSHOT + 1.6.3.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 72a702b2a..bebc0566f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.4.1-SNAPSHOT + 1.6.3.1-SNAPSHOT pom 2019 From 3b6de6380e61095822aa1934e7aa0eb96f750780 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 9 Dec 2019 09:45:40 +0100 Subject: [PATCH 0942/1786] [maven-release-plugin] prepare release 1.6.3.1 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 2f4fe9f01..82f4e83fd 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.1-SNAPSHOT + 1.6.3.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 4ffe16e7f..d06121efc 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.1-SNAPSHOT + 1.6.3.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index f63864de2..094705b46 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.1-SNAPSHOT + 1.6.3.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index d2bc9d456..bd3ab6f88 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.3.1-SNAPSHOT + 1.6.3.1 diff --git a/pom.xml b/pom.xml index bebc0566f..ea3030238 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.3.1-SNAPSHOT + 1.6.3.1 pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.3.1 From 8d80e5567e211e7cf3bc79cade403b683ebc6d82 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 9 Dec 2019 09:45:48 +0100 Subject: [PATCH 0943/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 82f4e83fd..418562f45 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.1 + 1.6.4-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index d06121efc..c6157cb28 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.1 + 1.6.4-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 094705b46..1a80d605a 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.1 + 1.6.4-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index bd3ab6f88..022056e21 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.3.1 + 1.6.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index ea3030238..2da468386 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.3.1 + 1.6.4-SNAPSHOT pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.3.1 + HEAD From 28af73128bf1ba74534fe1b42831ef9847126989 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 9 Dec 2019 11:46:52 +0100 Subject: [PATCH 0944/1786] Added test on wildcard list --- .../ImmutableObjectTransformationTest.java | 2 +- .../hotels/beans/sample/FromFooAdvFields.java | 2 ++ .../immutable/ImmutableToFooAdvFields.java | 2 ++ .../sample/mutable/MutableToFooAdvFields.java | 2 ++ .../transformer/AbstractTransformerTest.java | 2 +- .../transformer/utils/ClassUtilsTest.java | 2 ++ .../utils/ReflectionUtilsTest.java | 26 ++++++++++++++++--- 7 files changed, 32 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 4909fce02..2558e5be4 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -74,7 +74,7 @@ * Unit test for all {@link BeanTransformer} functions related to Immutable Java Beans. */ public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTest { - private static final int TOTAL_ADV_CLASS_FIELDS = 6; + private static final int TOTAL_ADV_CLASS_FIELDS = 7; private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; private static final String PRICE_FIELD_NAME = "price"; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java index 57406c581..c826ffc00 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java @@ -16,6 +16,7 @@ package com.hotels.beans.sample; +import java.util.List; import java.util.Optional; import com.hotels.transformer.constant.ClassType; @@ -39,6 +40,7 @@ public class FromFooAdvFields implements Cloneable { private final ClassType classType; private final String locale; private final float price; + private final List list; public FromFooAdvFields clone() throws CloneNotSupportedException { return (FromFooAdvFields) super.clone(); diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java index a63cd8458..0a9d35885 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java @@ -16,6 +16,7 @@ package com.hotels.beans.sample.immutable; +import java.util.List; import java.util.Locale; import java.util.Optional; @@ -38,6 +39,7 @@ public class ImmutableToFooAdvFields { private final ClassType classType; private final Locale locale; private final Price price; + private final List list; } @AllArgsConstructor diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java index 141f49b54..40078b8b2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java @@ -16,6 +16,7 @@ package com.hotels.beans.sample.mutable; +import java.util.List; import java.util.Locale; import java.util.Optional; @@ -37,6 +38,7 @@ public class MutableToFooAdvFields { private String indexNumber; private ClassType classType; private Locale locale; + private List list; private void setIndex(final String indexNumber) { this.indexNumber = indexNumber; diff --git a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java index 60e36e163..056586661 100644 --- a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java @@ -144,7 +144,7 @@ private FromFooSubClass createFromFooSubClass() { * @return the {@link FromFooAdvFields} instance. */ private FromFooAdvFields createFromFooAdvFields() { - return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage(), PRICE); + return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage(), PRICE, sourceFooSimpleList); } /** diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index dcd555797..69d93a541 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -35,6 +35,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.time.Instant; +import java.util.Currency; import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -176,6 +177,7 @@ private Object[][] dataSpecialTypeObjectTesting() { {"Tests that the method returns false if the class is not a special type object", BigDecimal.class, false}, {"Tests that the method returns true if the class is an instance of Temporal interface", Instant.class, true}, {"Tests that the method returns true if the class is an instance of Properties class", Properties.class, true}, + {"Tests that the method returns true if the class is an instance of Currency class", Currency.class, true}, {"Tests that the method returns true if the class is an instance of Date class", Date.class, true} }; } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 69a820ecd..2d8ef5962 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -53,6 +53,7 @@ import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.FromSubFoo; import com.hotels.beans.sample.immutable.ImmutableToFoo; +import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; import com.hotels.beans.sample.immutable.ImmutableToSubFoo; import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooAdvFields; @@ -499,19 +500,36 @@ public void testGetDeclaredFieldTypeWorksProperly() { assertNotNull(actual); } + /** * Tests that the method {@code getGenericFieldType} works properly. + * @param testCaseDescription the test case description + * @param fieldName the field name for which the generic type has to be retrieved + * @param fieldClass the class owning the field + * @param expectedType the expected generic class type */ - @Test - public void testGetGenericFieldTypeWorksProperly() { + @Test(dataProvider = "dataGetGenericFieldTypeTesting") + public void testGetGenericFieldTypeWorksProperly(final String testCaseDescription, final String fieldName, final Class fieldClass, final Class expectedType) { // GIVEN - Field field = underTest.getDeclaredField(LIST_FIELD_NAME, ImmutableToFoo.class); + Field field = underTest.getDeclaredField(fieldName, fieldClass); // WHEN Class actual = underTest.getGenericFieldType(field); // THEN - assertEquals(String.class, actual); + assertEquals(expectedType, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code getGenericFieldType}. + * @return parameters to be used for testing the the method {@code getGenericFieldType}. + */ + @DataProvider + private Object[][] dataGetGenericFieldTypeTesting() { + return new Object[][] { + {"Tests that the method returns a type String.", LIST_FIELD_NAME, ImmutableToFoo.class, String.class}, + {"Tests that the method returns a type Object in case of wildcard types.", LIST_FIELD_NAME, ImmutableToFooAdvFields.class, Object.class} + }; } /** From eeb0e472db26256fb543f3fc7cd6153cadc7a8a2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 10 Dec 2019 12:05:50 +0100 Subject: [PATCH 0945/1786] Modified base bean object in order to test types with wildcards --- .../beans/transformer/ImmutableObjectTransformationTest.java | 2 +- .../main/java/com/hotels/transformer/utils/ClassUtils.java | 4 ++++ .../test/java/com/hotels/beans/sample/FromFooAdvFields.java | 4 ++++ .../beans/sample/immutable/ImmutableToFooAdvFields.java | 4 ++++ .../hotels/beans/sample/mutable/MutableToFooAdvFields.java | 4 ++++ .../java/com/hotels/transformer/AbstractTransformerTest.java | 3 ++- 6 files changed, 19 insertions(+), 2 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 2558e5be4..c0363b30b 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -74,7 +74,7 @@ * Unit test for all {@link BeanTransformer} functions related to Immutable Java Beans. */ public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTest { - private static final int TOTAL_ADV_CLASS_FIELDS = 7; + private static final int TOTAL_ADV_CLASS_FIELDS = 10; private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; private static final String PRICE_FIELD_NAME = "price"; diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 9ba0f3c7c..101382c4a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -28,6 +28,7 @@ import static java.util.Arrays.stream; import static java.util.Collections.max; import static java.util.Comparator.comparing; +import static java.util.Objects.isNull; import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; import static java.util.Set.of; @@ -113,6 +114,9 @@ public ClassUtils() { * @return true if is primitive or special type, false otherwise */ public boolean isPrimitiveOrSpecialType(final Class clazz) { + if (isNull(clazz)) { + return false; + } final String cacheKey = "isPrimitiveOrSpecial-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final Boolean res = isPrimitiveType(clazz) || isSpecialType(clazz); diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java index c826ffc00..b17701875 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java @@ -17,6 +17,7 @@ package com.hotels.beans.sample; import java.util.List; +import java.util.Map; import java.util.Optional; import com.hotels.transformer.constant.ClassType; @@ -41,6 +42,9 @@ public class FromFooAdvFields implements Cloneable { private final String locale; private final float price; private final List list; + private final List noGenericsList; + private final Map map; + private final Map noGenericsMap; public FromFooAdvFields clone() throws CloneNotSupportedException { return (FromFooAdvFields) super.clone(); diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java index 0a9d35885..3c9fb6c13 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Optional; import com.hotels.transformer.constant.ClassType; @@ -40,6 +41,9 @@ public class ImmutableToFooAdvFields { private final Locale locale; private final Price price; private final List list; + private final List noGenericsList; + private final Map map; + private final Map noGenericsMap; } @AllArgsConstructor diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java index 40078b8b2..77622bd8e 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Optional; import com.hotels.transformer.constant.ClassType; @@ -39,6 +40,9 @@ public class MutableToFooAdvFields { private ClassType classType; private Locale locale; private List list; + private List noGenericsList; + private Map map; + private Map noGenericsMap; private void setIndex(final String indexNumber) { this.indexNumber = indexNumber; diff --git a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java index 056586661..208496ed2 100644 --- a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java @@ -144,7 +144,8 @@ private FromFooSubClass createFromFooSubClass() { * @return the {@link FromFooAdvFields} instance. */ private FromFooAdvFields createFromFooAdvFields() { - return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage(), PRICE, sourceFooSimpleList); + return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage(), + PRICE, sourceFooSimpleList, sourceFooSimpleList, SAMPLE_MAP, SAMPLE_MAP); } /** From ffa6efa45569fa0510ee519f45beea736da7056b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 10 Dec 2019 14:13:47 +0100 Subject: [PATCH 0946/1786] Modified java beans to test wildcards too --- .../ImmutableObjectTransformationTest.java | 2 +- .../hotels/beans/sample/FromFooAdvFields.java | 6 +++-- .../com/hotels/beans/sample/FromSubFoo.java | 2 +- .../com/hotels/beans/sample/ISubClass.java | 23 +++++++++++++++++++ .../immutable/ImmutableToFooAdvFields.java | 7 ++++-- .../sample/immutable/ImmutableToSubFoo.java | 4 +++- .../sample/mutable/MutableToFooAdvFields.java | 7 ++++-- .../beans/sample/mutable/MutableToSubFoo.java | 4 +++- .../transformer/AbstractTransformerTest.java | 8 ++++--- 9 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index c0363b30b..59ef0677a 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -74,7 +74,7 @@ * Unit test for all {@link BeanTransformer} functions related to Immutable Java Beans. */ public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTest { - private static final int TOTAL_ADV_CLASS_FIELDS = 10; + private static final int TOTAL_ADV_CLASS_FIELDS = 11; private static final String GET_DEST_FIELD_NAME_METHOD_NAME = "getDestFieldName"; private static final String GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME = "getConstructorValuesFromFields"; private static final String PRICE_FIELD_NAME = "price"; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java index b17701875..c379f66e8 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java @@ -16,6 +16,7 @@ package com.hotels.beans.sample; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; @@ -42,9 +43,10 @@ public class FromFooAdvFields implements Cloneable { private final String locale; private final float price; private final List list; - private final List noGenericsList; + private final Collection collection; private final Map map; - private final Map noGenericsMap; + private final Map supertypeMap; + private final ISubClass nestedObject; public FromFooAdvFields clone() throws CloneNotSupportedException { return (FromFooAdvFields) super.clone(); diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java index fdddae4b8..ddf7b41cd 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java @@ -29,7 +29,7 @@ @AllArgsConstructor @Getter @ToString -public class FromSubFoo { +public class FromSubFoo implements ISubClass { private final String name; private final int[] phoneNumbers; private final Map sampleMap; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java new file mode 100644 index 000000000..b3884e885 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java @@ -0,0 +1,23 @@ +/** + * Copyright (C) 2019 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +/** + * Sample interface for sub class Java Bean. + */ +public interface ISubClass { +} diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java index 3c9fb6c13..a097a4383 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java @@ -16,11 +16,13 @@ package com.hotels.beans.sample.immutable; +import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; +import com.hotels.beans.sample.ISubClass; import com.hotels.transformer.constant.ClassType; import lombok.AllArgsConstructor; @@ -41,9 +43,10 @@ public class ImmutableToFooAdvFields { private final Locale locale; private final Price price; private final List list; - private final List noGenericsList; + private final Collection collection; private final Map map; - private final Map noGenericsMap; + private final Map supertypeMap; + private final ISubClass nestedObject; } @AllArgsConstructor diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java index e55119f6e..4ca010f2d 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.Map; +import com.hotels.beans.sample.ISubClass; + import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; @@ -29,7 +31,7 @@ @AllArgsConstructor @Getter @ToString -public class ImmutableToSubFoo { +public class ImmutableToSubFoo implements ISubClass { private final String name; private final int[] phoneNumbers; private final Map sampleMap; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java index 77622bd8e..c12968f01 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java @@ -16,11 +16,13 @@ package com.hotels.beans.sample.mutable; +import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; +import com.hotels.beans.sample.ISubClass; import com.hotels.transformer.constant.ClassType; import lombok.Getter; @@ -40,9 +42,10 @@ public class MutableToFooAdvFields { private ClassType classType; private Locale locale; private List list; - private List noGenericsList; + private Collection collection; private Map map; - private Map noGenericsMap; + private Map supertypeMap; + private ISubClass nestedObject; private void setIndex(final String indexNumber) { this.indexNumber = indexNumber; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java index ba52ad7c3..064052970 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.Map; +import com.hotels.beans.sample.ISubClass; + import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -29,7 +31,7 @@ @Getter @Setter @ToString -public class MutableToSubFoo { +public class MutableToSubFoo implements ISubClass { private String name; private int[] phoneNumbers; private Map sampleMap; diff --git a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java index 208496ed2..7b5d7407b 100644 --- a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java @@ -23,6 +23,7 @@ import java.math.BigDecimal; import java.math.BigInteger; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -132,8 +133,8 @@ private FromFooWithPrimitiveFields createFromFooWithPrimitiveFields() { } /** - * Creates a {@link FromFooSubClass} instance. - * @return the {@link FromFooSubClass} instance. + * Creates a {@link SubClass} instance. + * @return the {@link SubClass} instance. */ private FromFooSubClass createFromFooSubClass() { return new FromFooSubClass(fromFoo.getName(), fromFoo.getId(), fromFoo.getNestedObjectList(), fromFoo.getList(), fromFoo.getNestedObject(), SURNAME, PHONE, CHECK, AMOUNT); @@ -143,9 +144,10 @@ private FromFooSubClass createFromFooSubClass() { * Creates a {@link FromFooAdvFields} instance. * @return the {@link FromFooAdvFields} instance. */ + @SuppressWarnings("unchecked") private FromFooAdvFields createFromFooAdvFields() { return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage(), - PRICE, sourceFooSimpleList, sourceFooSimpleList, SAMPLE_MAP, SAMPLE_MAP); + PRICE, sourceFooSimpleList, (Collection) sourceFooSimpleList, SAMPLE_MAP, (Map) SAMPLE_MAP, fromSubFoo); } /** From 99130e0cfc411919174f2c61520227be3a828fce Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 10 Dec 2019 15:29:06 +0100 Subject: [PATCH 0947/1786] Bumped testng version --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + pom.xml | 6 +++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index c058fbaeb..09d664f9a 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.4-jdk8] TBD #### Changed * Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). +* Updated `testng` version to `7.1.0` (was `7.0.0`). ### [1.6.3-jdk8] 2019.12.02 ### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fe049d0f..4706c9e06 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.3.1] 2019.12.09 #### Changed * Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). +* Updated `testng` version to `7.1.0` (was `7.0.0`). ### [1.6.3] 2019.12.02 ### Added diff --git a/pom.xml b/pom.xml index fa1f3ae6c..fdb0a9483 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.9 0.11 2.8.6 - 7.0.0 + 7.1.0 3.2.0 1.3.0 @@ -181,6 +181,10 @@ com.google.guava guava + + org.yaml + snakeyaml + From 5e4848acbdfa202fa96d89c9a318754cd2ce2d1e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 10 Dec 2019 15:34:47 +0100 Subject: [PATCH 0948/1786] Added -u option to the maven build --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2f8542502..2395c6d13 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode +script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode -U install: skip jobs: include: @@ -26,7 +26,7 @@ jobs: jdk: openjdk8 if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -U - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 @@ -34,7 +34,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -U deploy: provider: pages local-dir: target/site @@ -52,7 +52,7 @@ jobs: before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -U deploy: - provider: script script: config/travis/deploy.sh @@ -68,7 +68,7 @@ jobs: before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - mvn install javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -U deploy: - provider: script script: config/travis/deploy.sh From 62f324cda987c70ee72d3c148e8b94d07daf3735 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 10 Dec 2019 15:37:48 +0100 Subject: [PATCH 0949/1786] Degraded testng version --- .travis.yml | 10 +++++----- CHANGELOG-JDK8.md | 1 - CHANGELOG.md | 1 - pom.xml | 6 +----- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2395c6d13..17035f1a5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode -U +script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install: skip jobs: include: @@ -26,7 +26,7 @@ jobs: jdk: openjdk8 if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -U + - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 @@ -34,7 +34,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -U + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: provider: pages local-dir: target/site @@ -52,7 +52,7 @@ jobs: before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -U + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: - provider: script script: config/travis/deploy.sh @@ -68,7 +68,7 @@ jobs: before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -U + - mvn install javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: - provider: script script: config/travis/deploy.sh diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 09d664f9a..c058fbaeb 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,7 +5,6 @@ All notable changes to this project will be documented in this file. ### [1.6.4-jdk8] TBD #### Changed * Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). -* Updated `testng` version to `7.1.0` (was `7.0.0`). ### [1.6.3-jdk8] 2019.12.02 ### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 4706c9e06..0fe049d0f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,6 @@ All notable changes to this project will be documented in this file. ### [1.6.3.1] 2019.12.09 #### Changed * Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). -* Updated `testng` version to `7.1.0` (was `7.0.0`). ### [1.6.3] 2019.12.02 ### Added diff --git a/pom.xml b/pom.xml index fdb0a9483..fa1f3ae6c 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.9 0.11 2.8.6 - 7.1.0 + 7.0.0 3.2.0 1.3.0 @@ -181,10 +181,6 @@ com.google.guava guava - - org.yaml - snakeyaml - From 5c54d6bace7d2ccdc074694affa145ce09b1d4a1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2019 02:15:39 +0000 Subject: [PATCH 0950/1786] Bump slf4j-api from 1.7.29 to 1.7.30 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.29 to 1.7.30. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.29...v_1.7.30) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2da468386..78f69ac28 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 2.0.1.Final 6.1.0.Final - 1.7.29 + 1.7.30 3.0.0 2.2.6 From 0d05b11d6904cd30e1df24c53be10d42b407e28c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2019 02:16:08 +0000 Subject: [PATCH 0951/1786] Bump mockito-core from 3.2.0 to 3.2.4 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.2.0 to 3.2.4. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.2.0...v3.2.4) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2da468386..e9d3cdba8 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 0.11 2.8.6 7.0.0 - 3.2.0 + 3.2.4 1.3.0 2.0.1.Final From 8c21fc4792d877d8521a509521a022f6b9fd4a6e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 17 Dec 2019 10:55:45 +0100 Subject: [PATCH 0952/1786] Updated changelog --- CHANGELOG-JDK8.md | 2 ++ CHANGELOG.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index c058fbaeb..a6faa998c 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. ### [1.6.4-jdk8] TBD #### Changed * Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). +* Updated `mockito-core` version to `3.2.4` (was `3.2.0`). +* Updated `slf4j-api` version to `1.7.30` (was `1.7.29`). ### [1.6.3-jdk8] 2019.12.02 ### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fe049d0f..d9f5dacab 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. ### [1.6.3.1] 2019.12.09 #### Changed * Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). +* Updated `mockito-core` version to `3.2.4` (was `3.2.0`). +* Updated `slf4j-api` version to `1.7.30` (was `1.7.29`). ### [1.6.3] 2019.12.02 ### Added From bfbbf89bbcc42f279438ebb534d7faa46f8ad544 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 19 Dec 2019 12:38:28 +0100 Subject: [PATCH 0953/1786] Added getter methods retrieval feature --- .../hotels/transformer/utils/ClassUtils.java | 22 ++++++++++++ .../transformer/utils/ReflectionUtils.java | 22 ++++++++++++ .../transformer/utils/ClassUtilsTest.java | 35 +++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index fd498ad5b..f0d1bb0c0 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -674,6 +674,28 @@ public List getSetterMethods(final Class clazz) { }); } + /** + * Retrieves all the setters method for the given class. + * @param clazz the clazz containing the methods. + * @return all the class setter methods + */ + @SuppressWarnings("unchecked") + public List getGetterMethods(final Class clazz) { + notNull(clazz, CLAZZ_CANNOT_BE_NULL); + final String cacheKey = "GetterMethods-" + clazz.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, List.class).orElseGet(() -> { + final List setterMethods = new LinkedList<>(); + if (hasSuperclass(clazz.getSuperclass())) { + setterMethods.addAll(getGetterMethods(clazz.getSuperclass())); + } + setterMethods.addAll(stream(getDeclaredMethods(clazz)) + .filter(reflectionUtils::isGetter) + .collect(toList())); + CACHE_MANAGER.cacheObject(cacheKey, setterMethods); + return setterMethods; + }); + } + /** * Gets the default value of a primitive type. * @param objectType the primitive object class diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index e8dfd324d..45430419d 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -68,6 +68,11 @@ public final class ReflectionUtils { */ private static final String SETTER_METHOD_NAME_REGEX = "^set[A-Z].*"; + /** + * Regex for identify getter methods. + */ + private static final String GETTER_METHOD_NAME_REGEX = "^(get|is)[A-Z].*"; + /** * Regex for identify dots into a string. */ @@ -116,6 +121,23 @@ public boolean isSetter(final Method method) { }); } + /** + * Checks if the given method is a getter. + * @param method the method to be checked + * @return true if the method is a getter method, false otherwise + */ + public boolean isGetter(final Method method) { + final String cacheKey = "IsGetter-" + method.getDeclaringClass().getName() + '-' + method.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { + boolean res = isPublic(method.getModifiers()) + && method.getName().matches(GETTER_METHOD_NAME_REGEX) + && method.getParameterTypes().length == 0 + && !method.getReturnType().equals(void.class); + CACHE_MANAGER.cacheObject(cacheKey, res); + return res; + }); + } + /** * Gets the value of a field. * @param target the field's class diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 10a1e1f03..a1b3a098b 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -50,6 +50,9 @@ import com.hotels.beans.sample.AbstractClass; import com.hotels.beans.sample.FromFoo; +import com.hotels.beans.sample.FromFooAdvFields; +import com.hotels.beans.sample.FromFooSimple; +import com.hotels.beans.sample.FromFooSimpleNoGetters; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; @@ -96,6 +99,8 @@ public class ClassUtilsTest { private static final long[] PRIMITIVE_LONG_ARRAY = {}; private static final Integer[] PRIMITIVE_INTEGER_ARRAY = {}; private static final FromFoo[] NOT_PRIMITIVE_ARRAY = {}; + private static final int FROM_FOO_ADV_FIELD_EXPECTED_GETTER_METHODS = 6; + private static final int FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS = 3; /** * The class to be tested. @@ -730,6 +735,36 @@ private Object[][] dataGetSetterMethodsTesting() { }; } + /** + * Tests that the method {@code getGetterMethods} works as expected. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedGetterMethods the total expected getter method + */ + @Test(dataProvider = "dataGetGetterMethodsTesting") + public void testGetGetterMethodsWorksAsExpected(final String testCaseDescription, final Class testClass, final int expectedGetterMethods) { + // GIVEN + + // WHEN + final List actual = underTest.getGetterMethods(testClass); + + // THEN + assertEquals(expectedGetterMethods, actual.size()); + } + + /** + * Creates the parameters to be used for testing the method {@code getGetterMethods}. + * @return parameters to be used for testing the the method {@code getGetterMethods}. + */ + @DataProvider + private Object[][] dataGetGetterMethodsTesting() { + return new Object[][] { + {"Tests that the method returns an empty list if the class has no getter methods", FromFooSimpleNoGetters.class, ZERO}, + {"Tests that the method returns only the getter methods discarding the not valid one", FromFooAdvFields.class, FROM_FOO_ADV_FIELD_EXPECTED_GETTER_METHODS}, + {"Tests that the method returns the boolean getter method too", FromFooSimple.class, FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS} + }; + } + /** * Tests that the method {@code getDefaultTypeValue} works as expected. */ From a4fad4b6575d82814d983b1ade207440a346abcd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 19 Dec 2019 13:01:13 +0100 Subject: [PATCH 0954/1786] Changelog update --- CHANGELOG-JDK8.md | 6 +++--- CHANGELOG.md | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index c058fbaeb..00cd55de3 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,9 +2,9 @@ All notable changes to this project will be documented in this file. -### [1.6.4-jdk8] TBD -#### Changed -* Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). +### [1.6.3.1-jdk8] 2019.12.19 +#### Added +* Added method for retrieving the class getter methods. ### [1.6.3-jdk8] 2019.12.02 ### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fe049d0f..faf823c25 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.6.3.2] 2019.12.19 +#### Changed +* Added method for retrieving the class getter methods. + ### [1.6.3.1] 2019.12.09 #### Changed * Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). From 3a8e2889cf9c3afcbd21fed6021be96414cd0000 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 19 Dec 2019 13:02:37 +0100 Subject: [PATCH 0955/1786] Updated version --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 418562f45..49c8a3574 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.3.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index c6157cb28..818c55da4 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.3.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 1a80d605a..d0193f16d 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.3.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 022056e21..d3fec6ed6 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.4-SNAPSHOT + 1.6.3.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 2da468386..3ed9324b1 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.4-SNAPSHOT + 1.6.3.2-SNAPSHOT pom 2019 From 472079f99ae228f910e3dec9379bd22f51878b35 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 19 Dec 2019 13:18:09 +0100 Subject: [PATCH 0956/1786] [maven-release-plugin] prepare release 1.6.3.2 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 49c8a3574..1f151dc39 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.2-SNAPSHOT + 1.6.3.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 818c55da4..56791226e 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.2-SNAPSHOT + 1.6.3.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index d0193f16d..fb855ff86 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.2-SNAPSHOT + 1.6.3.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index d3fec6ed6..bf0f77b9d 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.3.2-SNAPSHOT + 1.6.3.2 diff --git a/pom.xml b/pom.xml index 3ed9324b1..f9edbe558 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.3.2-SNAPSHOT + 1.6.3.2 pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.3.2 From 24ba38c3a06c9bdc0de1161f5fddf029aac6886d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 19 Dec 2019 13:18:17 +0100 Subject: [PATCH 0957/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 1f151dc39..418562f45 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.2 + 1.6.4-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 56791226e..c6157cb28 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.2 + 1.6.4-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index fb855ff86..1a80d605a 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.3.2 + 1.6.4-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index bf0f77b9d..022056e21 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.3.2 + 1.6.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index f9edbe558..2da468386 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.3.2 + 1.6.4-SNAPSHOT pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.3.2 + HEAD From a7e0a3b3e35b5cd4f2bbddd05e6e583484fd34d5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 20 Dec 2019 07:10:35 +0100 Subject: [PATCH 0958/1786] Update README.md Added dependant badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4c99a0859..4857e6bb0 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) +[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=HotelsDotCom/bull)](https://dependabot.com) All BULL modules are available on Maven Central: From e3935f1c6877a981e844212c13bce5d2a3386193 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 20 Dec 2019 17:33:14 +0100 Subject: [PATCH 0959/1786] Fixed Unit test --- .../test/java/com/hotels/transformer/utils/ClassUtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 624f7b7e5..f0c5583b4 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -103,7 +103,7 @@ public class ClassUtilsTest { private static final long[] PRIMITIVE_LONG_ARRAY = {}; private static final Integer[] PRIMITIVE_INTEGER_ARRAY = {}; private static final FromFoo[] NOT_PRIMITIVE_ARRAY = {}; - private static final int FROM_FOO_ADV_FIELD_EXPECTED_GETTER_METHODS = 6; + private static final int FROM_FOO_ADV_FIELD_EXPECTED_GETTER_METHODS = 11; private static final int FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS = 3; /** From 094390424c19a33c48b01dbcdef3b65289fbb4d7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 20 Dec 2019 17:55:08 +0100 Subject: [PATCH 0960/1786] Updated changelog with the new changes implemented --- CHANGELOG-JDK8.md | 5 +++++ CHANGELOG.md | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 33e4ba123..57aa4163f 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.6.4-jdk8] TBD +#### Added +* Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). +* Implemented transformation of field declared with their interface. + ### [1.6.3.1-jdk8] 2019.12.19 #### Added * Added method for retrieving the class getter methods. diff --git a/CHANGELOG.md b/CHANGELOG.md index ac5b84cd3..488ea3e92 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.6.4] TBD +#### Added +* Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). +* Implemented transformation of field declared with their interface. + ### [1.6.3.2] 2019.12.19 #### Changed * Added method for retrieving the class getter methods. From a1c9a3f6738535e15cb537600720e55f430611b2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 20 Dec 2019 17:58:59 +0100 Subject: [PATCH 0961/1786] Fixed changelog text --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 57aa4163f..76f47808a 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.4-jdk8] TBD #### Added * Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). -* Implemented transformation of field declared with their interface. +* Implemented transformation of a field declared with its interface. ### [1.6.3.1-jdk8] 2019.12.19 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 488ea3e92..14f704b80 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.4] TBD #### Added * Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). -* Implemented transformation of field declared with their interface. +* Implemented transformation of a field declared with its interface. ### [1.6.3.2] 2019.12.19 #### Changed From d354fa40e538be47b5710e3e6e422c427bde9832 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 21 Dec 2019 14:19:32 +0100 Subject: [PATCH 0962/1786] Extract getConcreteTypeClass in a separated method --- .../beans/transformer/TransformerImpl.java | 9 +--- .../hotels/transformer/utils/ClassUtils.java | 24 +++++++-- .../transformer/utils/ClassUtilsTest.java | 52 +++++++++++++++++-- 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 2f93851e0..c1a7b678a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -553,14 +553,9 @@ private FieldTransformer getPrimitiveTypeTransformer(final Class sourceObject private Object getFieldValue(final Class targetClass, final Field field, final Object fieldValue, final String breadcrumb) { return getPopulator(field.getType(), fieldValue.getClass(), this) .map(populator -> populator.getPopulatedObject(targetClass, field.getName(), fieldValue)) - .orElseGet(() -> { + .orElseGet(() -> // recursively inject object - Class concreteType = field.getType(); - if (field.getType().isInterface()) { - concreteType = fieldValue.getClass(); - } - return transform(fieldValue, concreteType, breadcrumb); - } + transform(fieldValue, classUtils.getConcreteClass(field, fieldValue), breadcrumb) ); } } diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 89c038d36..0b138cc65 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -409,12 +409,28 @@ private Field[] getDeclaredFields(final Class clazz) { * @param the object instance class. * @return the concrete class of a field */ - public Class getConcreteClass(final Field field, final T objectInstance) { + public Class getFieldClass(final Field field, final T objectInstance) { + return getConcreteClass(field, reflectionUtils.getFieldValue(objectInstance, field)); + } + + /** + * Returns the concrete class of a field. + * @param field the field for which the concrete class has to be retrieved. + * @param fieldValue the field value. + * @return the concrete class of a field + */ + public Class getConcreteClass(final Field field, final Object fieldValue) { final String cacheKey = "ConcreteFieldClass-" + field.getName() + "-" + field.getDeclaringClass(); return CACHE_MANAGER.getFromCache(cacheKey, Class.class).orElseGet(() -> { - Class res = reflectionUtils.getFieldValue(objectInstance, field).getClass(); - CACHE_MANAGER.cacheObject(cacheKey, res); - return res; + Class concreteType = field.getType(); + boolean isFieldValueNull = isNull(fieldValue); + if (field.getType().isInterface()) { + concreteType = isFieldValueNull ? Object.class : fieldValue.getClass(); + } + if (!isFieldValueNull) { + CACHE_MANAGER.cacheObject(cacheKey, concreteType); + } + return concreteType; }); } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index f0c5583b4..cd99624fa 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -105,6 +105,8 @@ public class ClassUtilsTest { private static final FromFoo[] NOT_PRIMITIVE_ARRAY = {}; private static final int FROM_FOO_ADV_FIELD_EXPECTED_GETTER_METHODS = 11; private static final int FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS = 3; + private static final LinkedList LINKED_LIST = new LinkedList<>(); + private static final String LIST_FIELD_NAME = "list"; /** * The class to be tested. @@ -948,16 +950,56 @@ private Object[][] dataIsByteArrayTesting() { * @throws Exception if the field is not retrieved */ @Test - public void testGetConcreteClassWorksAsExpected() throws Exception { + public void testGetFieldClassWorksAsExpected() throws Exception { // GIVEN - FromFoo fromFoo = new FromFoo(NAME, null, null, new LinkedList<>(), null); - Field listField = fromFoo.getClass().getDeclaredField("list"); - listField.setAccessible(true); + FromFoo fromFoo = createFromFoo(); + Field listField = getField(fromFoo, LIST_FIELD_NAME); // WHEN - Class actual = underTest.getConcreteClass(listField, fromFoo); + Class actual = underTest.getFieldClass(listField, fromFoo); // THEN assertEquals(LinkedList.class, actual); } + + /** + * Tests that the method {@code getConcreteClass} returns the expected value. + * @param testCaseDescription the test case description + * @param field the class field for which the concrete class has to be retrieved + * @param fieldValue the field value + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataGetConcreteClassTesting") + public void testGetConcreteClassWorksAsExpected(final String testCaseDescription, final Field field, final Object fieldValue, final Class expectedResult) { + // GIVEN + + // WHEN + Class actual = underTest.getConcreteClass(field, fieldValue); + + // THEN + assertEquals(expectedResult, actual); + } + + /** + * Creates the parameters to be used for testing the method {@code getConcreteClass}. + * @return parameters to be used for testing the the method {@code getConcreteClass}. + */ + @DataProvider + private Object[][] dataGetConcreteClassTesting() throws Exception { + Field listField = getField(createFromFoo(), LIST_FIELD_NAME); + return new Object[][] { + {"Tests that the method returns Object if the field value is null", listField, null, Object.class}, + {"Tests that the method returns LinkedList if the concrete field class is a LinkedList", listField, LINKED_LIST, LINKED_LIST.getClass()} + }; + } + + private Field getField(final T objectInstance, final String fieldName) throws NoSuchFieldException { + Field field = objectInstance.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } + + private FromFoo createFromFoo() { + return new FromFoo(NAME, null, null, LINKED_LIST, null); + } } From 94a2ccb370be9eb6de91dc771e61575468aef386 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 21 Dec 2019 14:44:33 +0100 Subject: [PATCH 0963/1786] Disabled javadoc generation for the compatibility check with other JDK versions --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 17035f1a5..54d73cbcc 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn +script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dmaven.javadoc.skip=true install: skip jobs: include: From 9fd898c398fc6f9bcfa970b9ac3a6257f085d1af Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 21 Dec 2019 14:50:37 +0100 Subject: [PATCH 0964/1786] disabled all checks for the jdk compatibility check --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 54d73cbcc..83f28a1f9 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dmaven.javadoc.skip=true +script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Pfast install: skip jobs: include: From 9bcf164fdd705b7d1ef6d4c4d7ae9e8980c1b8d8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 21 Dec 2019 14:58:41 +0100 Subject: [PATCH 0965/1786] [maven-release-plugin] prepare release 1.6.4-RC --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 418562f45..c81e323a6 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.4-RC diff --git a/bull-common/pom.xml b/bull-common/pom.xml index c6157cb28..72108b2b2 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.4-RC diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 1a80d605a..5f04ead17 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.4-RC diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 022056e21..7831d06e0 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.4-SNAPSHOT + 1.6.4-RC diff --git a/pom.xml b/pom.xml index 565df9f2f..e19585ec0 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.4-SNAPSHOT + 1.6.4-RC pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.4-RC From 3cbeef6badac7fbbaf899e534f4bbf8adcae87de Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 21 Dec 2019 14:58:48 +0100 Subject: [PATCH 0966/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c81e323a6..418562f45 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-RC + 1.6.4-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 72108b2b2..c6157cb28 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-RC + 1.6.4-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 5f04ead17..1a80d605a 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-RC + 1.6.4-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 7831d06e0..022056e21 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.4-RC + 1.6.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index e19585ec0..565df9f2f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.4-RC + 1.6.4-SNAPSHOT pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.4-RC + HEAD From 3ce4204ddba96597cf57787d5c07580f61069634 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 24 Dec 2019 08:45:01 +0100 Subject: [PATCH 0967/1786] Removed not needed check on the immutable bean constructor --- .../beans/transformer/TransformerImpl.java | 8 +-- .../ImmutableObjectTransformationTest.java | 30 ++-------- .../immutable/ImmutableToFooInvalid.java | 58 ------------------- 3 files changed, 9 insertions(+), 87 deletions(-) delete mode 100644 bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index c1a7b678a..b5b2bd41e 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -104,7 +104,7 @@ protected final void transform(final T sourceObj, final K targetObject, f */ private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb, final boolean forceConstructorInjection) { final Object[] constructorArgs; - if (forceConstructorInjection || canBeInjectedByConstructorParams(constructor, targetClass)) { + if (forceConstructorInjection || canBeInjectedByConstructorParams(constructor)) { constructorArgs = getConstructorArgsValues(sourceObj, targetClass, constructor, breadcrumb); } else { constructorArgs = getConstructorValuesFromFields(sourceObj, targetClass, breadcrumb); @@ -168,15 +168,13 @@ private String getFormattedConstructorArgs(final Class targetClass, final /** * Checks if the source class field names can be retrieved from the constructor parameters. * @param constructor the all args constructor - * @param targetClass the destination object class * @param the target object type * @return true if the parameter names are defined or the parameters are annotated with: {@link ConstructorArg} */ - private boolean canBeInjectedByConstructorParams(final Constructor constructor, final Class targetClass) { + private boolean canBeInjectedByConstructorParams(final Constructor constructor) { final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final boolean res = classUtils.getPrivateFinalFields(targetClass).size() == constructor.getParameterCount() - && (classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class)); + final boolean res = classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class); cacheManager.cacheObject(cacheKey, res); return res; }); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 59ef0677a..1f1729022 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -53,7 +53,6 @@ import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooDiffFields; import com.hotels.beans.sample.immutable.ImmutableToFooDiffTypesFields; -import com.hotels.beans.sample.immutable.ImmutableToFooInvalid; import com.hotels.beans.sample.immutable.ImmutableToFooMap; import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; @@ -215,33 +214,16 @@ private Object[][] dataConstructorErrorTesting() { /** * Test that an {@link InvalidBeanException} is thrown if the bean is not valid. - * @param testCaseDescription the test case description - * @param sourceObject the object to transform - * @param targetObjectClass the target object class + * @throws CloneNotSupportedException if the clone of an object fails */ - @Test(dataProvider = "dataInvalidBeanExceptionTesting", expectedExceptions = InvalidBeanException.class) - public void testTransformThrowsExceptionWhenImmutableIsInvalid(final String testCaseDescription, final FromFoo sourceObject, - final Class targetObjectClass) { + @Test(expectedExceptions = InvalidBeanException.class) + public void testTransformThrowsExceptionWhenImmutableIsInvalid() throws CloneNotSupportedException { //GIVEN - - //WHEN - underTest.setValidationEnabled(true).transform(sourceObject, targetObjectClass); - } - - /** - * Creates the parameters to be used for testing the exception raised in case of error during the constructor invocation. - * @return parameters to be used for testing the exception raised in case of error during the constructor invocation. - * @throws CloneNotSupportedException if the clone fails - */ - @DataProvider(parallel = true) - private Object[][] dataInvalidBeanExceptionTesting() throws CloneNotSupportedException { FromFoo fromFooNullId = AbstractTransformerTest.fromFoo.clone(); fromFooNullId.setId(null); - return new Object[][] { - {"Test that an exception is thrown if there the constructor args parameters have a different order for the mutable bean object.", - fromFoo, ImmutableToFooInvalid.class}, - {"Test that an exception is thrown if the destination object don't met the constraints.", fromFooNullId, ImmutableToFoo.class}, - }; + + //WHEN + underTest.setValidationEnabled(true).transform(fromFooNullId, ImmutableToFoo.class); } /** diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java deleted file mode 100644 index 014863100..000000000 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooInvalid.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (C) 2019 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample.immutable; - -import java.math.BigInteger; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import lombok.Getter; - -/** - * Sample immutable object with constructor containing parameter in a different order than expected. - */ -@Getter -public class ImmutableToFooInvalid { - @NotNull - private final String name; - @NotNull - private final BigInteger id; - - private final List list; - @NotNull - private final List nestedObjectList; - @NotNull - private final ImmutableToSubFoo nestedObject; - - /** - * Constructor. - */ - public ImmutableToFooInvalid(@NotNull final String name, @NotNull final BigInteger id, @NotNull final List nestedObjectList, - @NotNull final ImmutableToSubFoo nestedObject) { - this.name = name; - this.id = id; - this.list = null; - this.nestedObjectList = nestedObjectList; - this.nestedObject = nestedObject; - } - - @Override - public String toString() { - return "ImmutableToFooInvalid"; - } -} From d717e6fb552edb9c86887fefdcbb91b90b170c2c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 24 Dec 2019 09:07:37 +0100 Subject: [PATCH 0968/1786] Updated version --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 76f47808a..bcdc6c899 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.4-jdk8] TBD +### [1.6.3.2-jdk8] 2019.12.24 #### Added * Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). * Implemented transformation of a field declared with its interface. diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f704b80..e46ec08ca 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.4] TBD +### [1.6.4] 2019.12.24 #### Added * Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). * Implemented transformation of a field declared with its interface. From 23e2ee5a00eb2a967b508a8151297b772b746997 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 24 Dec 2019 09:10:30 +0100 Subject: [PATCH 0969/1786] [maven-release-plugin] prepare release 1.6.4 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 418562f45..de2543dec 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.4 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index c6157cb28..5d7060281 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.4 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 1a80d605a..445360a95 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4-SNAPSHOT + 1.6.4 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 022056e21..b7c117034 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.4-SNAPSHOT + 1.6.4 diff --git a/pom.xml b/pom.xml index 565df9f2f..53e952807 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.4-SNAPSHOT + 1.6.4 pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.4 From fc011222925e2145a91fef03e770006f5d69b2c7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 24 Dec 2019 09:10:39 +0100 Subject: [PATCH 0970/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index de2543dec..5b1ba035c 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4 + 1.6.5-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 5d7060281..d4a66721f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4 + 1.6.5-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 445360a95..2fc278f53 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.4 + 1.6.5-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index b7c117034..8ec6544a0 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.4 + 1.6.5-SNAPSHOT diff --git a/pom.xml b/pom.xml index 53e952807..5f9e1d55a 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.4 + 1.6.5-SNAPSHOT pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.4 + HEAD From e874cb5ccfb1094cb6f37e7af9061edcea89f21f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 25 Dec 2019 02:32:08 +0000 Subject: [PATCH 0971/1786] Bump testng from 7.0.0 to 7.1.0 Bumps [testng](https://github.com/cbeust/testng) from 7.0.0 to 7.1.0. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/commits) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5f9e1d55a..ed6da4f07 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.9 0.11 2.8.6 - 7.0.0 + 7.1.0 3.2.4 1.3.0 From cc95b5ac5ba9381185f2c3b2e22b71eb1c5e3553 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 26 Dec 2019 11:58:40 +0100 Subject: [PATCH 0972/1786] - Fixed dependency duplication issue - Updated changelog --- CHANGELOG-JDK8.md | 4 ++++ CHANGELOG.md | 4 ++++ pom.xml | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index bcdc6c899..2daad527a 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.6.4] TBD +#### Changed +* Updated `testng` version to `7.1.0` (was `7.0.0`). + ### [1.6.3.2-jdk8] 2019.12.24 #### Added * Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). diff --git a/CHANGELOG.md b/CHANGELOG.md index e46ec08ca..660719452 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.6.5] TBD +#### Changed +* Updated `testng` version to `7.1.0` (was `7.0.0`). + ### [1.6.4] 2019.12.24 #### Added * Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). diff --git a/pom.xml b/pom.xml index ed6da4f07..24d6be56f 100644 --- a/pom.xml +++ b/pom.xml @@ -181,6 +181,10 @@ com.google.guava guava + + org.yaml + snakeyaml + From 76e1fb1aa91c697cec81236556e7f8738fc45464 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 27 Dec 2019 09:20:26 +0100 Subject: [PATCH 0973/1786] fixed typos --- README.md | 10 +++++----- docs/site/markdown/index.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4857e6bb0..860e0376f 100644 --- a/README.md +++ b/README.md @@ -103,17 +103,17 @@ mvnw.cmd clean install -P relaxed * support copy with Java Collection type. e.g. `List => List` * support copy with nested map fields. e.g. `Map>` * support copy with array containing primitive types. e.g. `String[]` => `String[]` -* support copy with array type. e.g. `BeanA[]` => `BeanB[]` +* support copy with an array type. e.g. `BeanA[]` => `BeanB[]` * support copy with property name mapping. e.g. `int id => int userId` * support copy with recursion copy. * support validation through annotations. * support copy of beans with different field's name. * support lambda function field transformation. * support copy of java bean built through Builder. -* easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. -* allows to set the default value for all objects not existing in the source object. -* allows to skip transformation for a given set of fields. -* supports the values retrieval from getters if a field does not exists in the source object. +* easy usage, declarative way to define the property mapping (in case of different names) or simply adding the Lombok annotations. +* allows setting the default value for all objects not existing in the source object. +* allows skipping transformation for a given set of fields. +* supports the retrieval of the value from getters if a field does not exist in the source object. * supports the automatic conversion of primitive types. # Feature samples diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 79b21410d..5190a0876 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -22,17 +22,17 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou * support copy with Java Collection type. e.g. `List => List` * support copy with nested map fields. e.g. `Map>` * support copy with array containing primitive types. e.g. `String[]` => `String[]` -* support copy with array type. e.g. `BeanA[]` => `BeanB[]` +* support copy with an array type. e.g. `BeanA[]` => `BeanB[]` * support copy with property name mapping. e.g. `int id => int userId` * support copy with recursion copy. * support validation through annotations. * support copy of beans with different field's name. * support lambda function field transformation. * support copy of java bean built through Builder. -* easy usage, declarative way to define the property mapping (in case of different names) or simply adding the lombok annotations. -* allows to set the default value for all objects not existing in the source object. -* allows to skip transformation for a given set of fields. -* supports the values retrieval from getters if a field does not exists in the source object. +* easy usage, declarative way to define the property mapping (in case of different names) or simply adding the Lombok annotations. +* allows setting the default value for all objects not existing in the source object. +* allows skipping transformation for a given set of fields. +* supports the retrieval of the value from getters if a field does not exist in the source object. * supports the automatic conversion of primitive types. #### Bean Validation: From 09f278c44dd4c542eb840352763736f8826c7014 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2020 02:19:35 +0000 Subject: [PATCH 0974/1786] Bump hibernate-validator from 6.1.0.Final to 6.1.1.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.1.0.Final to 6.1.1.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/master/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.1.0.Final...6.1.1.Final) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 24d6be56f..340406368 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 1.3.0 2.0.1.Final - 6.1.0.Final + 6.1.1.Final 1.7.30 3.0.0 2.2.6 From 2c59f4b29302045c2438a774670267d8f2195a72 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2020 02:15:09 +0000 Subject: [PATCH 0975/1786] Bump spring-boot-starter-test from 2.2.2.RELEASE to 2.2.3.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.2.2.RELEASE to 2.2.3.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.2.2.RELEASE...v2.2.3.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 340406368..45a8c428c 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ 11 ${jdk.version} ${jdk.version} - 2.2.2.RELEASE + 2.2.3.RELEASE 1.18.10 3.9 0.11 From 746b1327913dbd7016ec15eca1990818c5879823 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 17 Jan 2020 08:16:24 +0100 Subject: [PATCH 0976/1786] Update CHANGELOG-JDK8.md --- CHANGELOG-JDK8.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 2daad527a..07c446d80 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file. ### [1.6.4] TBD #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). +* Updated spring-boot-starter-test version to 2.2.3.RELEASE (was 2.2.2.RELEASE). +). +* Updated `hibernate-validator` version to `6.1.1.Final` (was `6.1.0.Final`). ### [1.6.3.2-jdk8] 2019.12.24 #### Added From 6c3cc0f62554ee95e290e873bbff15e578946691 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 17 Jan 2020 08:18:23 +0100 Subject: [PATCH 0977/1786] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 660719452..161c732a5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file. ### [1.6.5] TBD #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). +* Updated spring-boot-starter-test version to 2.2.3.RELEASE (was 2.2.2.RELEASE). +). +* Updated `hibernate-validator` version to `6.1.1.Final` (was `6.1.0.Final`). ### [1.6.4] 2019.12.24 #### Added From 887affd139beb605ace7fdc90c795ae72e776003 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 17 Jan 2020 08:21:11 +0100 Subject: [PATCH 0978/1786] Update CHANGELOG.md --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 161c732a5..634f82527 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.5] TBD #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). -* Updated spring-boot-starter-test version to 2.2.3.RELEASE (was 2.2.2.RELEASE). -). +* Updated `spring-boot-starter-test` version to `2.2.3.RELEASE` (was `2.2.2.RELEASE`). * Updated `hibernate-validator` version to `6.1.1.Final` (was `6.1.0.Final`). ### [1.6.4] 2019.12.24 From 2c0101936f70d1ff3322c41106d13421f617787d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 17 Jan 2020 08:22:49 +0100 Subject: [PATCH 0979/1786] Update CHANGELOG-JDK8.md --- CHANGELOG-JDK8.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 07c446d80..8ad61341a 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,8 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.4] TBD #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). -* Updated spring-boot-starter-test version to 2.2.3.RELEASE (was 2.2.2.RELEASE). -). +* Updated `spring-boot-starter-test` version to `2.2.3.RELEASE` (was `2.2.2.RELEASE`). * Updated `hibernate-validator` version to `6.1.1.Final` (was `6.1.0.Final`). ### [1.6.3.2-jdk8] 2019.12.24 From af1d93a9ad8a4344e76fd75410ea954e429fe48f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2020 02:19:11 +0000 Subject: [PATCH 0980/1786] Bump spring-boot-starter-test from 2.2.3.RELEASE to 2.2.4.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.2.3.RELEASE to 2.2.4.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.2.3.RELEASE...v2.2.4.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 45a8c428c..6a55de209 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ 11 ${jdk.version} ${jdk.version} - 2.2.3.RELEASE + 2.2.4.RELEASE 1.18.10 3.9 0.11 From c269338f053fc6235f7c8b694321801bcfad68a0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 Jan 2020 09:09:29 +0100 Subject: [PATCH 0981/1786] Updates changelog --- CHANGELOG-JDK8.md | 4 ++-- CHANGELOG.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 8ad61341a..059d8794f 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,10 +2,10 @@ All notable changes to this project will be documented in this file. -### [1.6.4] TBD +### [1.6.4-jdk8] TBD #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). -* Updated `spring-boot-starter-test` version to `2.2.3.RELEASE` (was `2.2.2.RELEASE`). +* Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). * Updated `hibernate-validator` version to `6.1.1.Final` (was `6.1.0.Final`). ### [1.6.3.2-jdk8] 2019.12.24 diff --git a/CHANGELOG.md b/CHANGELOG.md index 634f82527..12308c84c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.5] TBD #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). -* Updated `spring-boot-starter-test` version to `2.2.3.RELEASE` (was `2.2.2.RELEASE`). +* Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). * Updated `hibernate-validator` version to `6.1.1.Final` (was `6.1.0.Final`). ### [1.6.4] 2019.12.24 From f30ebcf5f9e50b98ab5530fc2c514647590cb1d0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 Jan 2020 09:09:45 +0100 Subject: [PATCH 0982/1786] Updates changelog --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 059d8794f..af83fbaec 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.4-jdk8] TBD +### [1.6.4-jdk8] 2020.01.21 #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). * Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 12308c84c..2fa538775 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.5] TBD +### [1.6.5] 2020.01.21 #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). * Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). From e990859a1963c988a9891fe9dc233aec37c9f29e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 Jan 2020 09:49:59 +0100 Subject: [PATCH 0983/1786] [maven-release-plugin] prepare release 1.6.5 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 5b1ba035c..26e689e2f 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.5-SNAPSHOT + 1.6.5 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index d4a66721f..2c9391f15 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.5-SNAPSHOT + 1.6.5 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 2fc278f53..663411fff 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.5-SNAPSHOT + 1.6.5 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 8ec6544a0..74281ee4f 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.5-SNAPSHOT + 1.6.5 diff --git a/pom.xml b/pom.xml index 6a55de209..cf92a1372 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.5-SNAPSHOT + 1.6.5 pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.5 From 5e0eb0e1a21bbe767ecebafe3cc07ccaa6cc5d5a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 Jan 2020 09:50:11 +0100 Subject: [PATCH 0984/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- pom.xml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 26e689e2f..3bfd72547 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.5 + 1.6.6-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 2c9391f15..e4f641114 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.5 + 1.6.6-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 663411fff..ce92c61e6 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.5 + 1.6.6-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 74281ee4f..0d93e2fd9 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.5 + 1.6.6-SNAPSHOT diff --git a/pom.xml b/pom.xml index cf92a1372..8ce239b2d 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.5 + 1.6.6-SNAPSHOT pom 2019 @@ -89,7 +89,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.5 + HEAD From 15831c59a40aaf3794f838fd5be6325c4b08e1a8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 2 Feb 2020 18:35:36 +0100 Subject: [PATCH 0985/1786] Updated licences --- .../main/java/com/hotels/beans/BeanUtils.java | 2 +- .../java/com/hotels/beans/package-info.java | 2 +- .../hotels/beans/populator/ArrayPopulator.java | 2 +- .../beans/populator/CollectionPopulator.java | 2 +- .../beans/populator/ICollectionPopulator.java | 2 +- .../hotels/beans/populator/MapPopulator.java | 2 +- .../beans/populator/OptionalPopulator.java | 2 +- .../com/hotels/beans/populator/Populator.java | 2 +- .../beans/populator/PopulatorFactory.java | 2 +- .../hotels/beans/populator/package-info.java | 2 +- .../transformer/AbstractBeanTransformer.java | 2 +- .../beans/transformer/BeanTransformer.java | 17 ++++++++++++++++- .../beans/transformer/TransformerImpl.java | 5 ++--- .../hotels/beans/transformer/package-info.java | 2 +- .../src/main/resources/logback.xml | 2 +- .../java/com/hotels/beans/BeanUtilsTest.java | 2 +- .../java/com/hotels/beans/package-info.java | 2 +- .../beans/performance/PerformanceTest.java | 2 +- .../hotels/beans/performance/package-info.java | 2 +- .../beans/populator/ArrayPopulatorTest.java | 2 +- .../beans/populator/PopulatorFactoryTest.java | 2 +- .../hotels/beans/populator/package-info.java | 2 +- .../AbstractBeanTransformerTest.java | 2 +- .../beans/transformer/BeanTransformerTest.java | 2 +- .../BuilderObjectTransformationTest.java | 2 +- .../ImmutableObjectTransformationTest.java | 2 +- .../MixedObjectTransformationTest.java | 2 +- .../MutableObjectTransformationTest.java | 2 +- .../hotels/beans/transformer/package-info.java | 2 +- .../src/test/resources/logback-test.xml | 2 +- .../hotels/transformer/AbstractTransformer.java | 2 +- .../com/hotels/transformer/Transformer.java | 2 +- .../transformer/annotation/ConstructorArg.java | 2 +- .../transformer/annotation/package-info.java | 2 +- .../com/hotels/transformer/base/Defaults.java | 2 +- .../hotels/transformer/base/package-info.java | 2 +- .../hotels/transformer/cache/CacheManager.java | 2 +- .../transformer/cache/CacheManagerFactory.java | 2 +- .../hotels/transformer/cache/package-info.java | 2 +- .../hotels/transformer/constant/ClassType.java | 2 +- .../hotels/transformer/constant/Filters.java | 2 +- .../transformer/constant/MethodPrefix.java | 2 +- .../transformer/constant/Punctuation.java | 2 +- .../transformer/constant/package-info.java | 2 +- .../error/InstanceCreationException.java | 2 +- .../transformer/error/InvalidBeanException.java | 2 +- .../error/InvalidFunctionException.java | 2 +- .../error/MissingFieldException.java | 2 +- .../error/MissingMethodException.java | 2 +- .../hotels/transformer/error/package-info.java | 2 +- .../hotels/transformer/model/EmptyValue.java | 2 +- .../hotels/transformer/model/FieldMapping.java | 2 +- .../transformer/model/FieldTransformer.java | 2 +- .../com/hotels/transformer/model/ItemType.java | 2 +- .../hotels/transformer/model/MapElemType.java | 2 +- .../com/hotels/transformer/model/MapType.java | 2 +- .../transformer/model/TransformerSettings.java | 2 +- .../hotels/transformer/model/package-info.java | 2 +- .../com/hotels/transformer/package-info.java | 2 +- .../hotels/transformer/utils/ClassUtils.java | 2 +- .../transformer/utils/ReflectionUtils.java | 2 +- .../hotels/transformer/utils/package-info.java | 2 +- .../hotels/transformer/validator/Validator.java | 2 +- .../transformer/validator/ValidatorImpl.java | 2 +- .../transformer/validator/package-info.java | 2 +- .../java/com/hotels/beans/package-info.java | 2 +- .../com/hotels/beans/sample/AbstractClass.java | 2 +- .../java/com/hotels/beans/sample/FromFoo.java | 2 +- .../hotels/beans/sample/FromFooAdvFields.java | 2 +- .../com/hotels/beans/sample/FromFooMap.java | 2 +- .../com/hotels/beans/sample/FromFooNoField.java | 2 +- .../beans/sample/FromFooOnlyPrimitiveTypes.java | 2 +- .../com/hotels/beans/sample/FromFooSimple.java | 2 +- .../beans/sample/FromFooSimpleBooleanField.java | 2 +- .../beans/sample/FromFooSimpleNoGetters.java | 2 +- .../hotels/beans/sample/FromFooSubClass.java | 2 +- .../sample/FromFooWithPrimitiveFields.java | 2 +- .../com/hotels/beans/sample/FromSubFoo.java | 2 +- .../java/com/hotels/beans/sample/ISubClass.java | 2 +- .../sample/immutable/ImmutableFlatToFoo.java | 2 +- .../beans/sample/immutable/ImmutableToFoo.java | 2 +- .../immutable/ImmutableToFooAdvFields.java | 2 +- .../ImmutableToFooCustomAnnotation.java | 2 +- .../immutable/ImmutableToFooDiffFields.java | 2 +- .../ImmutableToFooDiffTypesFields.java | 2 +- .../sample/immutable/ImmutableToFooMap.java | 2 +- .../ImmutableToFooMissingCustomAnnotation.java | 2 +- .../immutable/ImmutableToFooNoConstructors.java | 2 +- .../ImmutableToFooNotExistingFields.java | 2 +- .../sample/immutable/ImmutableToFooSimple.java | 2 +- .../immutable/ImmutableToFooSimpleBoolean.java | 2 +- .../ImmutableToFooSimpleWrongTypes.java | 2 +- .../immutable/ImmutableToFooSubClass.java | 2 +- .../immutable/ImmutableToFooWithBuilder.java | 2 +- .../sample/immutable/ImmutableToSubFoo.java | 2 +- .../ImmutableToSubFooCustomAnnotation.java | 2 +- .../beans/sample/immutable/package-info.java | 2 +- .../hotels/beans/sample/mixed/MixedToFoo.java | 2 +- .../sample/mixed/MixedToFooDiffFields.java | 2 +- .../MixedToFooMissingAllArgsConstructor.java | 2 +- .../mixed/MixedToFooMissingConstructor.java | 2 +- .../sample/mixed/MixedToFooMissingField.java | 2 +- .../mixed/MixedToFooNotExistingFields.java | 2 +- .../sample/mixed/MixedToFooStaticField.java | 2 +- .../sample/mixed/MixedToFooWithBuilder.java | 2 +- .../mixed/MutableToFooOnlyPrimitiveTypes.java | 2 +- .../hotels/beans/sample/mixed/package-info.java | 2 +- .../beans/sample/mutable/MutableToFoo.java | 2 +- .../sample/mutable/MutableToFooAdvFields.java | 2 +- .../sample/mutable/MutableToFooInvalid.java | 2 +- .../mutable/MutableToFooNotExistingFields.java | 2 +- .../sample/mutable/MutableToFooSimple.java | 2 +- .../mutable/MutableToFooSimpleNoSetters.java | 2 +- .../sample/mutable/MutableToFooSubClass.java | 2 +- .../sample/mutable/MutableToFooWithBuilder.java | 2 +- ...ableToFooWithBuilderMultipleConstructor.java | 2 +- .../beans/sample/mutable/MutableToSubFoo.java | 2 +- .../beans/sample/mutable/package-info.java | 2 +- .../com/hotels/beans/sample/package-info.java | 2 +- .../transformer/AbstractTransformerTest.java | 2 +- .../hotels/transformer/base/DefaultsTest.java | 2 +- .../hotels/transformer/base/package-info.java | 2 +- .../cache/CacheManagerFactoryTest.java | 2 +- .../transformer/cache/CacheManagerTest.java | 2 +- .../hotels/transformer/cache/package-info.java | 2 +- .../com/hotels/transformer/package-info.java | 2 +- .../transformer/utils/ClassUtilsTest.java | 2 +- .../transformer/utils/ReflectionUtilsTest.java | 2 +- .../hotels/transformer/utils/package-info.java | 2 +- .../transformer/validator/ValidatorTest.java | 2 +- .../transformer/validator/package-info.java | 2 +- bull-common/src/test/resources/logback-test.xml | 2 +- .../com/hotels/beans/conversion/Converter.java | 2 +- .../hotels/beans/conversion/ConverterImpl.java | 2 +- .../conversion/analyzer/ConversionAnalyzer.java | 2 +- .../beans/conversion/analyzer/package-info.java | 2 +- .../error/TypeConversionException.java | 2 +- .../beans/conversion/error/package-info.java | 2 +- .../hotels/beans/conversion/package-info.java | 2 +- .../processor/ConversionProcessor.java | 2 +- .../processor/ConversionProcessorFactory.java | 2 +- .../impl/BigDecimalConversionProcessor.java | 2 +- .../impl/BigIntegerConversionProcessor.java | 2 +- .../impl/BooleanConversionProcessor.java | 2 +- .../impl/ByteArrayConversionProcessor.java | 2 +- .../processor/impl/ByteConversionProcessor.java | 2 +- .../impl/CharacterConversionProcessor.java | 2 +- .../impl/DoubleConversionProcessor.java | 2 +- .../impl/FloatConversionProcessor.java | 2 +- .../impl/IntegerConversionProcessor.java | 2 +- .../processor/impl/LongConversionProcessor.java | 2 +- .../impl/ShortConversionProcessor.java | 2 +- .../impl/StringConversionProcessor.java | 2 +- .../conversion/processor/impl/package-info.java | 2 +- .../conversion/processor/package-info.java | 2 +- .../conversion/AbstractConversionTest.java | 2 +- .../hotels/beans/conversion/ConverterTest.java | 2 +- .../analyzer/ConversionAnalyzerTest.java | 2 +- .../beans/conversion/analyzer/package-info.java | 2 +- .../hotels/beans/conversion/package-info.java | 2 +- .../ConversionProcessorFactoryTest.java | 2 +- .../impl/BigDecimalConversionTest.java | 2 +- .../impl/BigIntegerConversionTest.java | 2 +- .../processor/impl/BooleanConversionTest.java | 2 +- .../processor/impl/ByteArrayConversionTest.java | 2 +- .../processor/impl/ByteConversionTest.java | 2 +- .../processor/impl/CharacterConversionTest.java | 2 +- .../processor/impl/DoubleConversionTest.java | 2 +- .../processor/impl/FloatConversionTest.java | 2 +- .../processor/impl/IntegerConversionTest.java | 2 +- .../processor/impl/LongConversionTest.java | 2 +- .../processor/impl/ShortConversionTest.java | 2 +- .../processor/impl/StringConversionTest.java | 2 +- .../conversion/processor/impl/package-info.java | 2 +- .../conversion/processor/package-info.java | 2 +- .../src/main/java/com/hotels/map/MapUtils.java | 2 +- .../main/java/com/hotels/map/package-info.java | 2 +- .../map/transformer/AbstractMapTransformer.java | 2 +- .../hotels/map/transformer/MapTransformer.java | 2 +- .../map/transformer/MapTransformerImpl.java | 2 +- .../model/MapTransformerSettings.java | 2 +- .../map/transformer/model/package-info.java | 2 +- .../hotels/map/transformer/package-info.java | 2 +- .../src/main/resources/logback.xml | 2 +- .../test/java/com/hotels/map/MapUtilsTest.java | 2 +- .../test/java/com/hotels/map/package-info.java | 2 +- .../map/transformer/MapTransformerTest.java | 2 +- .../hotels/map/transformer/package-info.java | 2 +- .../src/test/resources/config/logback-test.xml | 2 +- 189 files changed, 205 insertions(+), 191 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java index bc7eeaf45..52644b9de 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java index 7b3b33b6a..c7c2d386a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index afa9c0bd3..f0d7cc5e6 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index 896b68c50..842bf8247 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java index b4415f1df..2384c45fd 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java index 10fb1d250..f3ab5bbab 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index 98c3cbbe1..1c7a37c17 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java index 733fc6853..d4561687b 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java index eaddc5ad0..f5fa41be5 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java index a2e61961d..945a99b9e 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java index a4e079fbc..9d2a90304 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index 218ecabb4..e2470cc72 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -1,5 +1,20 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * sour * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index b5b2bd41e..74ac0adda 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -168,10 +168,9 @@ private String getFormattedConstructorArgs(final Class targetClass, final /** * Checks if the source class field names can be retrieved from the constructor parameters. * @param constructor the all args constructor - * @param the target object type * @return true if the parameter names are defined or the parameters are annotated with: {@link ConstructorArg} */ - private boolean canBeInjectedByConstructorParams(final Constructor constructor) { + private boolean canBeInjectedByConstructorParams(final Constructor constructor) { final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class); diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java index 79093745c..a0504eb73 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019 Expedia, Inc. + * Copyright (C) 2019-2020 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/resources/logback.xml b/bull-bean-transformer/src/main/resources/logback.xml index 4da7aad36..8d4f400ab 100644 --- a/bull-bean-transformer/src/main/resources/logback.xml +++ b/bull-bean-transformer/src/main/resources/logback.xml @@ -1,5 +1,5 @@ 2.0.1.Final - 6.1.1.Final + 6.1.2.Final 1.7.30 3.0.0 2.2.6 From 6525be03ccbb9dd20314c5b73f626c815abc2fd7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Feb 2020 09:35:00 +0100 Subject: [PATCH 0987/1786] Updated changelog --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index af83fbaec..ec0e8de8b 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). * Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). -* Updated `hibernate-validator` version to `6.1.1.Final` (was `6.1.0.Final`). +* Updated `hibernate-validator` version to `6.1.2.Final` (was `6.1.0.Final`). ### [1.6.3.2-jdk8] 2019.12.24 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fa538775..2e2fa599d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). * Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). -* Updated `hibernate-validator` version to `6.1.1.Final` (was `6.1.0.Final`). +* Updated `hibernate-validator` version to `6.1.2.Final` (was `6.1.0.Final`). ### [1.6.4] 2019.12.24 #### Added From 61c44aa8fb679ef09e5672cba8276c7287897171 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Feb 2020 12:44:34 +0100 Subject: [PATCH 0988/1786] Removes wrong javadoc --- .../hotels/beans/transformer/BeanTransformer.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index e2470cc72..cee7999fa 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -13,21 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * sour - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package com.hotels.beans.transformer; From b9c9bf2518b8669c045ffce9e976fcb8e24f2f73 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Feb 2020 17:46:59 +0100 Subject: [PATCH 0989/1786] Disables the javadoc suppression on test classes and adds it on the missing classes --- .../src/test/java/com/hotels/beans/sample/FromFooSubClass.java | 3 +++ .../hotels/beans/sample/immutable/ImmutableToFooAdvFields.java | 3 +++ .../hotels/beans/sample/mutable/MutableToFooWithBuilder.java | 3 +++ .../mutable/MutableToFooWithBuilderMultipleConstructor.java | 3 +++ config/checkstyle/suppression.xml | 2 +- 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java index e75f2c984..82bac3b73 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java @@ -23,6 +23,9 @@ import lombok.Getter; import lombok.ToString; +/** + * Sample sub class. + */ @Getter @ToString public class FromFooSubClass extends FromFoo { diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java index 28e381d23..0b159d25a 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java @@ -49,6 +49,9 @@ public class ImmutableToFooAdvFields { private final ISubClass nestedObject; } +/** + * Nested class. + */ @AllArgsConstructor @Getter class Price { diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java index 91d02b44b..f0a68d42b 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java @@ -37,6 +37,9 @@ public final class MutableToFooWithBuilder { private MutableToFooWithBuilder() { } + /** + * Builder class. + */ public static class Builder { private String name; private BigInteger id; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java index a405c4146..32d18dd5f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java @@ -39,6 +39,9 @@ public final class MutableToFooWithBuilderMultipleConstructor { private MutableToFooWithBuilderMultipleConstructor() { } + /** + * Builder class. + */ static class Builder { private String name; private BigInteger id; diff --git a/config/checkstyle/suppression.xml b/config/checkstyle/suppression.xml index d9856d598..c325c9935 100644 --- a/config/checkstyle/suppression.xml +++ b/config/checkstyle/suppression.xml @@ -6,7 +6,7 @@ - From a10c0208627cf4e55dd7370d0cb927389cf83557 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2020 02:28:02 +0000 Subject: [PATCH 0990/1786] Bump hotels-oss-parent from 4.2.0 to 4.3.0 Bumps [hotels-oss-parent](https://github.com/HotelsDotCom/hotels-oss-parent) from 4.2.0 to 4.3.0. - [Release notes](https://github.com/HotelsDotCom/hotels-oss-parent/releases) - [Changelog](https://github.com/HotelsDotCom/hotels-oss-parent/blob/master/CHANGELOG.md) - [Commits](https://github.com/HotelsDotCom/hotels-oss-parent/commits) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8ca9450fa..2a2cad45f 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ com.hotels hotels-oss-parent - 4.2.0 + 4.3.0 From e7017d37ba593317b136181ea23fab2a9dc39670 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 6 Feb 2020 09:05:55 +0100 Subject: [PATCH 0991/1786] [travis skip] updates the changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index ec0e8de8b..17c517749 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. * Updated `testng` version to `7.1.0` (was `7.0.0`). * Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). * Updated `hibernate-validator` version to `6.1.2.Final` (was `6.1.0.Final`). +* Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). ### [1.6.3.2-jdk8] 2019.12.24 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e2fa599d..f22b5a764 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. * Updated `testng` version to `7.1.0` (was `7.0.0`). * Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). * Updated `hibernate-validator` version to `6.1.2.Final` (was `6.1.0.Final`). +* Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). ### [1.6.4] 2019.12.24 #### Added From df007694ceecd9134123bb00dd7c3b7d90b07097 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2020 02:26:34 +0000 Subject: [PATCH 0992/1786] Bump lombok from 1.18.10 to 1.18.12 Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.18.10 to 1.18.12. - [Release notes](https://github.com/rzwitserloot/lombok/releases) - [Changelog](https://github.com/rzwitserloot/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/rzwitserloot/lombok/compare/v1.18.10...v1.18.12) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2a2cad45f..0ba8c3698 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ ${jdk.version} ${jdk.version} 2.2.4.RELEASE - 1.18.10 + 1.18.12 3.9 0.11 2.8.6 From 0751aca11d508e3b463c3128152f684c2bca02a9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 7 Feb 2020 06:59:40 +0100 Subject: [PATCH 0993/1786] updates changelog --- CHANGELOG-JDK8.md | 6 +++++- CHANGELOG.md | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 17c517749..edead19b2 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,12 +2,16 @@ All notable changes to this project will be documented in this file. +### [1.6.5-jdk8] TBD +#### Changed +* Updated `lombok` version to `1.18.12` (was `1.18.10`). +* Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). + ### [1.6.4-jdk8] 2020.01.21 #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). * Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). * Updated `hibernate-validator` version to `6.1.2.Final` (was `6.1.0.Final`). -* Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). ### [1.6.3.2-jdk8] 2019.12.24 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index f22b5a764..cbdc799e1 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,16 @@ All notable changes to this project will be documented in this file. +### [1.6.6] TBD +#### Changed +* Updated `lombok` version to `1.18.12` (was `1.18.10`). +* Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). + ### [1.6.5] 2020.01.21 #### Changed * Updated `testng` version to `7.1.0` (was `7.0.0`). * Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). * Updated `hibernate-validator` version to `6.1.2.Final` (was `6.1.0.Final`). -* Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). ### [1.6.4] 2019.12.24 #### Added From 665b7f77de3507c14ca578fadde86bd4ad2cbee5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 7 Feb 2020 18:15:58 +0100 Subject: [PATCH 0994/1786] Skip the spotless maven plugin execution --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 0ba8c3698..745f01833 100644 --- a/pom.xml +++ b/pom.xml @@ -539,6 +539,13 @@ + + com.diffplug.spotless + spotless-maven-plugin + + true + + org.apache.maven.plugins From 4392d6bf792812ed503bfaa3ef0f61b45395589d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 8 Feb 2020 09:08:07 +0100 Subject: [PATCH 0995/1786] Configures the automatic import ordering plus: the automatic unused import removal and the trailing whitespace cleanup --- CHANGELOG-JDK8.md | 2 ++ CHANGELOG.md | 2 ++ .../beans/transformer/TransformerImpl.java | 2 +- .../transformer/constant/MethodPrefix.java | 1 - .../hotels/transformer/utils/ClassUtils.java | 4 +-- .../ImmutableToFooCustomAnnotation.java | 2 -- ...ImmutableToFooMissingCustomAnnotation.java | 2 -- .../ImmutableToSubFooCustomAnnotation.java | 2 -- .../analyzer/ConversionAnalyzer.java | 6 ++-- .../processor/ConversionProcessorFactory.java | 2 +- .../processor/impl/DoubleConversionTest.java | 1 - .../processor/impl/FloatConversionTest.java | 1 - .../processor/impl/IntegerConversionTest.java | 1 - .../processor/impl/LongConversionTest.java | 1 - .../hotels/map/transformer/package-info.java | 1 - pom.xml | 31 ++++++++++++++----- 16 files changed, 35 insertions(+), 26 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index edead19b2..c437e5099 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. ### [1.6.5-jdk8] TBD +### Added +* Added `maven-spotless-plugin` for the code automatic formatting during the maven build #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). diff --git a/CHANGELOG.md b/CHANGELOG.md index cbdc799e1..2f5249b86 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. ### [1.6.6] TBD +### Added +* Added `maven-spotless-plugin` for the code automatic formatting during the maven build #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 74ac0adda..0c6c6ea99 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -26,6 +26,7 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import static com.hotels.transformer.base.Defaults.defaultValue; import static com.hotels.transformer.constant.ClassType.MIXED; import static com.hotels.transformer.constant.ClassType.MUTABLE; @@ -33,7 +34,6 @@ import static com.hotels.transformer.constant.Punctuation.DOT; import static com.hotels.transformer.constant.Punctuation.LPAREN; import static com.hotels.transformer.constant.Punctuation.RPAREN; -import static com.hotels.beans.populator.PopulatorFactory.getPopulator; import java.lang.reflect.Constructor; import java.lang.reflect.Field; diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java b/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java index 61e622c66..cc771f697 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java @@ -46,4 +46,3 @@ public final String getPrefix() { return name().toLowerCase(); } } - diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index b6343bf1d..2ca296f69 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -34,15 +34,15 @@ import static java.util.Set.of; import static java.util.stream.Collectors.toList; -import static com.hotels.transformer.validator.Validator.notNull; import static com.hotels.transformer.base.Defaults.defaultValue; import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; import static com.hotels.transformer.constant.ClassType.IMMUTABLE; import static com.hotels.transformer.constant.ClassType.MIXED; import static com.hotels.transformer.constant.ClassType.MUTABLE; -import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_FIELD; import static com.hotels.transformer.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; +import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_FIELD; +import static com.hotels.transformer.validator.Validator.notNull; import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java index 7388bcb8f..7a54e1403 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -73,5 +73,3 @@ public ImmutableToSubFooCustomAnnotation getNestedObject() { return nestedObject; } } - - diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java index e540e7080..e094bd951 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -42,5 +42,3 @@ public ImmutableToFooMissingCustomAnnotation(@ConstructorArg("name") final Strin this.id = id; } } - - diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java index 8a8a12ca6..51af1f845 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -53,5 +53,3 @@ public ImmutableToSubFooCustomAnnotation(@ConstructorArg("name") final String na this.veryComplexMap = veryComplexMap; } } - - diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 2c5c1c742..a6115a047 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -21,8 +21,11 @@ import static com.hotels.beans.conversion.processor.ConversionProcessorFactory.getConversionProcessor; import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.hotels.transformer.utils.ClassUtils.isBigDecimal; +import static com.hotels.transformer.utils.ClassUtils.isBigInteger; import static com.hotels.transformer.utils.ClassUtils.isBoolean; import static com.hotels.transformer.utils.ClassUtils.isByte; +import static com.hotels.transformer.utils.ClassUtils.isByteArray; import static com.hotels.transformer.utils.ClassUtils.isChar; import static com.hotels.transformer.utils.ClassUtils.isDouble; import static com.hotels.transformer.utils.ClassUtils.isFloat; @@ -30,9 +33,6 @@ import static com.hotels.transformer.utils.ClassUtils.isLong; import static com.hotels.transformer.utils.ClassUtils.isShort; import static com.hotels.transformer.utils.ClassUtils.isString; -import static com.hotels.transformer.utils.ClassUtils.isBigDecimal; -import static com.hotels.transformer.utils.ClassUtils.isBigInteger; -import static com.hotels.transformer.utils.ClassUtils.isByteArray; import java.util.Optional; import java.util.function.Function; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index ac78d5390..a665d37df 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -21,9 +21,9 @@ import static com.hotels.transformer.utils.ClassUtils.isBigDecimal; import static com.hotels.transformer.utils.ClassUtils.isBigInteger; -import static com.hotels.transformer.utils.ClassUtils.isByteArray; import static com.hotels.transformer.utils.ClassUtils.isBoolean; import static com.hotels.transformer.utils.ClassUtils.isByte; +import static com.hotels.transformer.utils.ClassUtils.isByteArray; import static com.hotels.transformer.utils.ClassUtils.isChar; import static com.hotels.transformer.utils.ClassUtils.isDouble; import static com.hotels.transformer.utils.ClassUtils.isFloat; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index 3bc438456..a893c1102 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -217,4 +217,3 @@ public void testConvertBigDecimalShouldReturnProperResult() { assertEquals(expectedValue, actual, DELTA); } } - diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 0974895db..b7aa816e2 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -217,4 +217,3 @@ public void testConvertBigDecimalShouldReturnProperResult() { assertEquals(expectedValue, actual, DELTA); } } - diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index 38af0c1d7..8b99f5974 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -216,4 +216,3 @@ public void testConvertBigDecimalShouldReturnProperResult() { assertEquals(expectedValue, actual); } } - diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java index b5fc453ab..63d4b5e84 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java @@ -216,4 +216,3 @@ public void testConvertBigDecimalShouldReturnProperResult() { assertEquals(expectedValue, actual); } } - diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java index 2b85449a0..95a85b18d 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java @@ -18,4 +18,3 @@ */ package com.hotels.map.transformer; - diff --git a/pom.xml b/pom.xml index 745f01833..d02765ac2 100644 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,7 @@ false true false + \#java,\#javax,\#org,\#,\#com,\#com.expedia,\#com.expediagroup,\#com.hotels,,\#lombok,java,javax,org,,com,com.expedia,com.expediagroup,com.hotels,,lombok @@ -539,13 +540,6 @@ - - com.diffplug.spotless - spotless-maven-plugin - - true - - org.apache.maven.plugins @@ -692,6 +686,29 @@ org.apache.maven.plugins maven-enforcer-plugin + + + com.diffplug.spotless + spotless-maven-plugin + ${spotless.maven.plugin.version} + + + process-sources + + apply + + + + + + + + + ${import.order} + + + + From 5aec0c0f57fb6788089afde858e41c74e6f5daad Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 8 Feb 2020 09:31:11 +0100 Subject: [PATCH 0996/1786] Modifies the import config --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d02765ac2..9704b1fce 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ false true false - \#java,\#javax,\#org,\#,\#com,\#com.expedia,\#com.expediagroup,\#com.hotels,,\#lombok,java,javax,org,,com,com.expedia,com.expediagroup,com.hotels,,lombok + \#java,\#javax,\#org,\#,\#com,,\#lombok,java,javax,org,,com,,lombok From 1dcc67b63cc4316cc18185cdef02c9a1a0adfb83 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 10 Feb 2020 08:38:20 +0100 Subject: [PATCH 0997/1786] Disables spotless maven plugin on the profiles: fast, site-release and release as not needed --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 9704b1fce..7c5eb0e9e 100644 --- a/pom.xml +++ b/pom.xml @@ -83,6 +83,7 @@ true false \#java,\#javax,\#org,\#,\#com,,\#lombok,java,javax,org,,com,,lombok + false @@ -255,6 +256,7 @@ false true true + true @@ -276,6 +278,7 @@ true false + true @@ -309,6 +312,7 @@ false true true + true @@ -700,6 +704,7 @@ + ${spotless.plugin.skip} From 73004fc5adc867c5c4933c38a4a655e4e334b4ff Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2020 02:18:15 +0000 Subject: [PATCH 0998/1786] Bump hotels-oss-parent from 4.3.0 to 5.0.0 Bumps [hotels-oss-parent](https://github.com/HotelsDotCom/hotels-oss-parent) from 4.3.0 to 5.0.0. - [Release notes](https://github.com/HotelsDotCom/hotels-oss-parent/releases) - [Changelog](https://github.com/HotelsDotCom/hotels-oss-parent/blob/master/CHANGELOG.md) - [Commits](https://github.com/HotelsDotCom/hotels-oss-parent/compare/hotels-oss-parent-4.3.0...hotels-oss-parent-5.0.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7c5eb0e9e..6817a12ed 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ com.hotels hotels-oss-parent - 4.3.0 + 5.0.0 From 8d0ffabecda9369d4aeb68b7ee366ae73b2a4884 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 13 Feb 2020 09:59:53 +0100 Subject: [PATCH 0999/1786] Updates the changelog --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index c437e5099..a156bbf3a 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. * Added `maven-spotless-plugin` for the code automatic formatting during the maven build #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). -* Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). +* Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). ### [1.6.4-jdk8] 2020.01.21 #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f5249b86..238d106b3 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. * Added `maven-spotless-plugin` for the code automatic formatting during the maven build #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). -* Updated `hotels-oss-parent` version to `4.3.0` (was `4.2.0`). +* Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). ### [1.6.5] 2020.01.21 #### Changed From 070507770a410fd13d1e889d940db8d931b36464 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 18 Feb 2020 17:43:46 +0100 Subject: [PATCH 1000/1786] Integrates the coverall plugin --- pom.xml | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 6817a12ed..258ef389b 100644 --- a/pom.xml +++ b/pom.xml @@ -71,6 +71,8 @@ 0.88 0.90 **/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* + + 2.3.1 3.3.4 0.12 @@ -483,11 +485,11 @@ **/Test*.* **/*Test.* **/*Application.* - com/hotels/transformer/AbstractTransformer.* - **/model/** - **/constant/** - **/error/** - **/annotation/** + **/AbstractTransformer.* + **/model/* + **/constant/* + **/error/* + **/annotation/* @@ -530,6 +532,21 @@ + + org.eluder.coveralls + coveralls-maven-plugin + ${coveralls.maven.plugin.version} + + + javax.xml.bind + jaxb-api + ${jaxb-api.version} + + + + Jdc0LQKSgQFSoBA4RiHyuFu6x0QdSxPeQ + + org.codehaus.mojo cobertura-maven-plugin From 8049625a9bff07d7b3fc21a431ab6ad7eb6e655d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 19 Feb 2020 07:19:17 +0100 Subject: [PATCH 1001/1786] Tests the coveralls report with through Travis --- .travis.yml | 4 ++-- pom.xml | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 83f28a1f9..5881750f3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -30,11 +30,11 @@ jobs: - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ + #if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: provider: pages local-dir: target/site diff --git a/pom.xml b/pom.xml index 258ef389b..550cd5ae3 100644 --- a/pom.xml +++ b/pom.xml @@ -543,9 +543,6 @@ ${jaxb-api.version} - - Jdc0LQKSgQFSoBA4RiHyuFu6x0QdSxPeQ - org.codehaus.mojo From 77df3ea9f0406d73ca0b42e373a0219b64e47747 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 19 Feb 2020 07:21:23 +0100 Subject: [PATCH 1002/1786] Tests the coveralls report with through Travis --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5881750f3..9ad1d7c1e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -27,10 +27,15 @@ jobs: if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - stage: "Coveralls report" + name: "Coveralls report" + jdk: openjdk11 + script: + - travis_retry mvn clean test jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 - #if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn From 3ef64bdeb885f061f98b8734489d56f1612fff33 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 19 Feb 2020 07:28:26 +0100 Subject: [PATCH 1003/1786] Updates the changelog and integrates coverall to the maven build --- .travis.yml | 7 +------ CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + README.md | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9ad1d7c1e..23b4a730b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -27,11 +27,6 @@ jobs: if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ script: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - stage: "Coveralls report" - name: "Coveralls report" - jdk: openjdk11 - script: - - travis_retry mvn clean test jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 @@ -39,7 +34,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} jacoco:report coveralls:report site:site javadoc:aggregate -P default,site-release jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: provider: pages local-dir: target/site diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index a156bbf3a..3ae4d1f85 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.5-jdk8] TBD ### Added * Added `maven-spotless-plugin` for the code automatic formatting during the maven build +* Added `coveralls-maven-plugin` for the test coverage analysis and report during the maven build: [Coverall report](https://coveralls.io/github/HotelsDotCom/bull) #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 238d106b3..2d284ee64 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.6.6] TBD ### Added * Added `maven-spotless-plugin` for the code automatic formatting during the maven build +* Added `coveralls-maven-plugin` for the test coverage analysis and report during the maven build: [Coverall report](https://coveralls.io/github/HotelsDotCom/bull) #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). diff --git a/README.md b/README.md index 860e0376f..96fb88e00 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) -[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=coverage)](https://sonarcloud.io/dashboard?id=BULL) +[![Coverage Status](https://coveralls.io/repos/github/HotelsDotCom/bull/badge.svg?branch=master)](https://coveralls.io/github/HotelsDotCom/bull?branch=master) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) ![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=HotelsDotCom/bull)](https://dependabot.com) From 280e363a03a4f19b050a35f159682491c9520386 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2020 02:17:34 +0000 Subject: [PATCH 1004/1786] Bump mockito-core from 3.2.4 to 3.3.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.2.4 to 3.3.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.2.4...v3.3.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 550cd5ae3..dfe460454 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 0.11 2.8.6 7.1.0 - 3.2.4 + 3.3.0 1.3.0 2.0.1.Final From aaa9870c5dcec1b4bb5dca3c676281440c1ec9ab Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Feb 2020 07:06:58 +0100 Subject: [PATCH 1005/1786] [travis skip] updates the changelog with the bumped library --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 3ae4d1f85..5ca8cd966 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). +* Updated `mockito-core` version to `3.3.0` (was `3.2.4`). ### [1.6.4-jdk8] 2020.01.21 #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d284ee64..a2d1152ca 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). +* Updated `mockito-core` version to `3.3.0` (was `3.2.4`). ### [1.6.5] 2020.01.21 #### Changed From 66140edd7c30af56764a3e34e10564a540859402 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 27 Feb 2020 16:27:14 +0100 Subject: [PATCH 1006/1786] Instruct jacoco to skip lombok generated sources and introduce the possibility to skip the coverall plugin execution --- .../hotels/transformer/utils/ClassUtilsTest.java | 2 +- lombok.config | 1 + pom.xml | 13 ++++++++----- 3 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 lombok.config diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index bb858df48..6be60bb6d 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -320,7 +320,7 @@ private Object[][] dataGetNotFinalFieldsTesting() { * Tests that the method {@code getTotalFields} works as expected. * @param testCaseDescription the test case description * @param testClass the class to test - * @param fieldPredicate the predicate to apply + * @param fieldPredicate the predicate to apply * @param expectedResult the expected result */ @Test(dataProvider = "dataGetTotalFieldsTesting") diff --git a/lombok.config b/lombok.config new file mode 100644 index 000000000..74da8257f --- /dev/null +++ b/lombok.config @@ -0,0 +1 @@ +lombok.addLombokGeneratedAnnotation=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index dfe460454..44ea1dd33 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ false true - false + false true false \#java,\#javax,\#org,\#,\#com,,\#lombok,java,javax,org,,com,,lombok @@ -248,7 +248,7 @@ true false - true + true @@ -256,7 +256,7 @@ true false - true + true true true @@ -312,7 +312,7 @@ true false - true + true true true @@ -475,7 +475,7 @@ check - ${jacoco.check.skip} + ${test.coverage..check.skip} com/hotels/transformer/** com/hotels/beans/** @@ -536,6 +536,9 @@ org.eluder.coveralls coveralls-maven-plugin ${coveralls.maven.plugin.version} + + ${test.coverage..check.skip} + javax.xml.bind From 78ba011ca03616447b093c7203a53a5a0cb2dc82 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2020 02:13:40 +0000 Subject: [PATCH 1007/1786] Bump spring-boot-starter-test from 2.2.4.RELEASE to 2.2.5.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.2.4.RELEASE to 2.2.5.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.2.4.RELEASE...v2.2.5.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 44ea1dd33..28886af34 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ 11 ${jdk.version} ${jdk.version} - 2.2.4.RELEASE + 2.2.5.RELEASE 1.18.12 3.9 0.11 From 9e38bec0e1bf00b0901b5355194656706cf9f094 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 28 Feb 2020 09:37:18 +0100 Subject: [PATCH 1008/1786] Updates changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 5ca8cd966..73975f94d 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). * Updated `mockito-core` version to `3.3.0` (was `3.2.4`). +* Updated `spring-boot-starter-test` version to `2.2.5.RELEASE` (was `2.2.4.RELEASE`). ### [1.6.4-jdk8] 2020.01.21 #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index a2d1152ca..ce8b3decf 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). * Updated `mockito-core` version to `3.3.0` (was `3.2.4`). +* Updated `spring-boot-starter-test` version to `2.2.5.RELEASE` (was `2.2.4.RELEASE`). ### [1.6.5] 2020.01.21 #### Changed From 09d5351e6b834ef10310d0e073070c24609debae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 1 Mar 2020 17:56:11 +0100 Subject: [PATCH 1009/1786] Fixes the plugin property name --- pom.xml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 28886af34..2e8e07b67 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ false true - false + false true false \#java,\#javax,\#org,\#,\#com,,\#lombok,java,javax,org,,com,,lombok @@ -248,7 +248,7 @@ true false - true + true @@ -256,7 +256,7 @@ true false - true + true true true @@ -312,7 +312,7 @@ true false - true + true true true @@ -452,6 +452,7 @@ false + org.jacoco jacoco-maven-plugin @@ -475,7 +476,7 @@ check - ${test.coverage..check.skip} + ${test.coverage.check.skip} com/hotels/transformer/** com/hotels/beans/** @@ -532,12 +533,13 @@ + org.eluder.coveralls coveralls-maven-plugin ${coveralls.maven.plugin.version} - ${test.coverage..check.skip} + ${test.coverage.check.skip} From 85e209815d538da1044674a7035b3995744495db Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 1 Mar 2020 18:04:26 +0100 Subject: [PATCH 1010/1786] Adds a link to coveralls in the documentation --- docs/site/site.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/site/site.xml b/docs/site/site.xml index 71537e1b9..017b989e7 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -55,7 +55,8 @@ - + + From 9ef8dd6627a228dba06fb2192b989da300b588de Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 2 Mar 2020 09:59:38 +0100 Subject: [PATCH 1011/1786] Improve lombok configuration to solve a library bug --- lombok.config | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lombok.config b/lombok.config index 74da8257f..b1c9a706f 100644 --- a/lombok.config +++ b/lombok.config @@ -1 +1,6 @@ -lombok.addLombokGeneratedAnnotation=true \ No newline at end of file +lombok.addLombokGeneratedAnnotation=true +lombok.anyConstructor.addConstructorProperties=true +config.stopBubbling=true +# Copy the Qualifier annotation from the instance variables to the constructor +# see https://github.com/rzwitserloot/lombok/issues/745 +lombok.copyableAnnotations+=org.springframework.beans.factory.annotation.Qualifier \ No newline at end of file From 7797f6cdcb1e65f924a796741170a9082c8957e3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 4 Mar 2020 15:23:25 +0100 Subject: [PATCH 1012/1786] - Enables the full build for each commit - Adds the bull-bean-transformer module to the "fast" profile --- .travis.yml | 4 ++-- pom.xml | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23b4a730b..a77702f05 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Pfast +script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install: skip jobs: include: @@ -34,7 +34,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} jacoco:report coveralls:report site:site javadoc:aggregate -P default,site-release jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} coveralls:report site:site javadoc:aggregate -P default,site-release jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: provider: pages local-dir: target/site diff --git a/pom.xml b/pom.xml index 2e8e07b67..1357318be 100644 --- a/pom.xml +++ b/pom.xml @@ -253,6 +253,9 @@ fast + + bull-map-transformer + true false From 7c47d70c2fd2a02783b18c73176ef92907866b84 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 4 Mar 2020 15:26:01 +0100 Subject: [PATCH 1013/1786] Enables the coveralls build on all branch --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a77702f05..8bcd13620 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn +script: travis_retry mvn clean install coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn install: skip jobs: include: @@ -34,7 +34,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} coveralls:report site:site javadoc:aggregate -P default,site-release jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: provider: pages local-dir: target/site From c8167ccecf6f176481024ad21526b36e9402ef8c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 4 Mar 2020 16:55:11 +0100 Subject: [PATCH 1014/1786] - Moves the coverall build to the common build, this allows to remove the specific build step for jdk8 - Updates the PR template adding the test coverage check --- .travis.yml | 11 ++--------- PULL_REQUEST_TEMPLATE.md | 1 + 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8bcd13620..1dafc7fed 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,17 +16,10 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn +script: travis_retry mvn clean install jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: include: - ### JDK8 build - - stage: "JDK8 Build" - name: "JDK8 Build and Test" - jdk: openjdk8 - if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ - script: - - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 @@ -34,7 +27,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: provider: pages local-dir: target/site diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 9870c7a5a..6dc039b1a 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -27,6 +27,7 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] My changes generate no new warnings - [ ] Any dependent changes have been merged and published in downstream modules - [ ] My changes have no bad impacts on performances +- [ ] My changes have been tested through Unit Tests and the overall coverage has not decreased. Check the coverall report for your branch: (here)[https://coveralls.io/github/HotelsDotCom/bull] - [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file - [ ] Any implemented change has been added in the [CHANGELOG-JDK8.md](./CHANGELOG-JDK8.md) file - [ ] My changes have been applied on a separate branch too with compatibility with Java 8. Follow this (instructions)[https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#3-prepare-the-jdk8-release] for help. From e82a4e3dd1d0fad022936cba474fca0e46d599a6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 4 Mar 2020 16:57:16 +0100 Subject: [PATCH 1015/1786] style fix --- PULL_REQUEST_TEMPLATE.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 6dc039b1a..19d669c52 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -27,8 +27,9 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] My changes generate no new warnings - [ ] Any dependent changes have been merged and published in downstream modules - [ ] My changes have no bad impacts on performances -- [ ] My changes have been tested through Unit Tests and the overall coverage has not decreased. Check the coverall report for your branch: (here)[https://coveralls.io/github/HotelsDotCom/bull] +- [ ] My changes have been tested through Unit Tests and the overall coverage has not decreased. Check the coverall report for your branch: [here](https://coveralls.io/github/HotelsDotCom/bull) - [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file - [ ] Any implemented change has been added in the [CHANGELOG-JDK8.md](./CHANGELOG-JDK8.md) file -- [ ] My changes have been applied on a separate branch too with compatibility with Java 8. Follow this (instructions)[https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#3-prepare-the-jdk8-release] for help. +- [ ] My changes have been applied on a separate branch too with compatibility with Java 8. Follow this [instructions](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#3-prepare-the-jdk8-release) for help. + - [ ] The maven version has been increased. From 251e2a3d58e91e9c692a9de4c3dc9c6a93d7bb76 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Tue, 10 Mar 2020 14:43:49 +0530 Subject: [PATCH 1016/1786] feature/testCoverage Adding a unit test case for ClassUtils which checks null object --- .../test/java/com/hotels/transformer/utils/ClassUtilsTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 6be60bb6d..a545cc235 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -215,7 +215,8 @@ private Object[][] dataPrimitiveOrSpecialTypeObjectTesting() { return new Object[][] { {"Tests that the method returns true if the class is a primitive or special type object", Locale.class, true}, {"Tests that the method returns false if the class is a primitive nor a special type object", BigDecimal.class, true}, - {"Tests that the method returns false if the class is not a primitive nor a special type object", FromFoo.class, false} + {"Tests that the method returns false if the class is not a primitive nor a special type object", FromFoo.class, false}, + {"Tests that the method returns false if the class is null", null, false} }; } From 3cef91a08a11f95b0fe7f5482cd575f1dd2b3c0b Mon Sep 17 00:00:00 2001 From: lbhandari Date: Tue, 10 Mar 2020 14:54:08 +0530 Subject: [PATCH 1017/1786] feature/testCoverage Adding unit test case for getGetterMethods method in ClassUtils to test that the parent class's getter methods are returned --- .../beans/sample/ExtendedFromFooSimple.java | 37 +++++++++++++++++++ .../transformer/utils/ClassUtilsTest.java | 5 ++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java diff --git a/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java new file mode 100644 index 000000000..8ef0c9137 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2019-2020 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +/** + * Sample immutable object. + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class ExtendedFromFooSimple extends FromFooSimple { + public String subName; +} diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index a545cc235..c5dd15019 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -53,6 +53,7 @@ import org.testng.annotations.Test; import com.hotels.beans.sample.AbstractClass; +import com.hotels.beans.sample.ExtendedFromFooSimple; import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooAdvFields; import com.hotels.beans.sample.FromFooSimple; @@ -105,6 +106,7 @@ public class ClassUtilsTest { private static final FromFoo[] NOT_PRIMITIVE_ARRAY = {}; private static final int FROM_FOO_ADV_FIELD_EXPECTED_GETTER_METHODS = 11; private static final int FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS = 3; + private static final int EXTENDED_FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS = 4; private static final LinkedList LINKED_LIST = new LinkedList<>(); private static final String LIST_FIELD_NAME = "list"; @@ -771,7 +773,8 @@ private Object[][] dataGetGetterMethodsTesting() { return new Object[][] { {"Tests that the method returns an empty list if the class has no getter methods", FromFooSimpleNoGetters.class, ZERO}, {"Tests that the method returns only the getter methods discarding the not valid one", FromFooAdvFields.class, FROM_FOO_ADV_FIELD_EXPECTED_GETTER_METHODS}, - {"Tests that the method returns the boolean getter method too", FromFooSimple.class, FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS} + {"Tests that the method returns the boolean getter method too", FromFooSimple.class, FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS}, + {"Tests that the method returns the getter methods from parent class too", ExtendedFromFooSimple.class, EXTENDED_FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS} }; } From e9624d25d261ffd7f1fb2e03803e06649b20dc93 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Tue, 10 Mar 2020 15:00:38 +0530 Subject: [PATCH 1018/1786] feature/testCoverage Removing unused import --- .../java/com/hotels/beans/sample/ExtendedFromFooSimple.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java index 8ef0c9137..8eb6b768b 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java @@ -16,8 +16,6 @@ package com.hotels.beans.sample; -import java.math.BigInteger; - import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; From 02e1fc883f8d5edb7bf7a7e1678680f06a920d42 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Tue, 10 Mar 2020 16:09:26 +0530 Subject: [PATCH 1019/1786] feature/testCoverage Using an existing child class instead of creating another one : review changes --- .../beans/sample/ExtendedFromFooSimple.java | 35 ------------------- .../transformer/utils/ClassUtilsTest.java | 6 ++-- 2 files changed, 3 insertions(+), 38 deletions(-) delete mode 100644 bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java diff --git a/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java deleted file mode 100644 index 8eb6b768b..000000000 --- a/bull-common/src/test/java/com/hotels/beans/sample/ExtendedFromFooSimple.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (C) 2019-2020 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hotels.beans.sample; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; - -/** - * Sample immutable object. - */ -@NoArgsConstructor -@AllArgsConstructor -@Getter -@Setter -@ToString -public class ExtendedFromFooSimple extends FromFooSimple { - public String subName; -} diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index c5dd15019..70d8fbde2 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -53,11 +53,11 @@ import org.testng.annotations.Test; import com.hotels.beans.sample.AbstractClass; -import com.hotels.beans.sample.ExtendedFromFooSimple; import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooAdvFields; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSimpleNoGetters; +import com.hotels.beans.sample.FromFooSubClass; import com.hotels.beans.sample.immutable.ImmutableToFoo; import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; @@ -106,7 +106,7 @@ public class ClassUtilsTest { private static final FromFoo[] NOT_PRIMITIVE_ARRAY = {}; private static final int FROM_FOO_ADV_FIELD_EXPECTED_GETTER_METHODS = 11; private static final int FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS = 3; - private static final int EXTENDED_FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS = 4; + private static final int FROM_FOO_SUB_CLASS_EXPECTED_GETTER_METHODS = 9; private static final LinkedList LINKED_LIST = new LinkedList<>(); private static final String LIST_FIELD_NAME = "list"; @@ -774,7 +774,7 @@ private Object[][] dataGetGetterMethodsTesting() { {"Tests that the method returns an empty list if the class has no getter methods", FromFooSimpleNoGetters.class, ZERO}, {"Tests that the method returns only the getter methods discarding the not valid one", FromFooAdvFields.class, FROM_FOO_ADV_FIELD_EXPECTED_GETTER_METHODS}, {"Tests that the method returns the boolean getter method too", FromFooSimple.class, FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS}, - {"Tests that the method returns the getter methods from parent class too", ExtendedFromFooSimple.class, EXTENDED_FROM_FOO_SIMPLE_EXPECTED_GETTER_METHODS} + {"Tests that the method returns the getter methods from parent class too", FromFooSubClass.class, FROM_FOO_SUB_CLASS_EXPECTED_GETTER_METHODS} }; } From 032f3daeafb75d51d15aacd676f9e566f94830b2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2020 02:20:02 +0000 Subject: [PATCH 1020/1786] Bump maven-site-plugin from 3.8.2 to 3.9.0 Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.8.2 to 3.9.0. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.8.2...maven-site-plugin-3.9.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1357318be..8d4f3c96c 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 3.3.4 0.12 github - 3.8.2 + 3.9.0 false true From fcd96abaa7041a4fdf3538a7730e79d26e2d5be5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 11 Mar 2020 07:20:12 +0100 Subject: [PATCH 1021/1786] [travis skip] updates changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 73975f94d..629d77dd7 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). * Updated `mockito-core` version to `3.3.0` (was `3.2.4`). * Updated `spring-boot-starter-test` version to `2.2.5.RELEASE` (was `2.2.4.RELEASE`). +* Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). ### [1.6.4-jdk8] 2020.01.21 #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index ce8b3decf..7bcf86de0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). * Updated `mockito-core` version to `3.3.0` (was `3.2.4`). * Updated `spring-boot-starter-test` version to `2.2.5.RELEASE` (was `2.2.4.RELEASE`). +* Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). ### [1.6.5] 2020.01.21 #### Changed From 6ebba9ff819cfc22be4bf7c4f62965712938f2be Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 12 Mar 2020 11:48:04 +0100 Subject: [PATCH 1022/1786] Adds a new module for report aggregation purpose. It combine also the jacoco coverage among all modules --- .travis.yml | 2 +- bull-report/pom.xml | 42 ++++++++++++++++++++++++++++++++++++++++++ pom.xml | 4 ++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 bull-report/pom.xml diff --git a/.travis.yml b/.travis.yml index 1dafc7fed..91c32a47c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode +script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: include: diff --git a/bull-report/pom.xml b/bull-report/pom.xml new file mode 100644 index 000000000..0de543b5d --- /dev/null +++ b/bull-report/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + BULL - Report + bull-report + Includes all project modules in order to combine their reports: e.g. Jacoco + + + bean-utils-library-parent + com.hotels.beans + 1.6.6-SNAPSHOT + + + + true + + + + + com.hotels.beans + bull-common + ${project.version} + + + com.hotels.beans + bull-converter + ${project.version} + + + com.hotels.beans + bull-bean-transformer + ${project.version} + + + com.hotels.beans + bull-map-transformer + ${project.version} + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1357318be..7cb8b5942 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,7 @@ bull-common bull-bean-transformer bull-converter + bull-report @@ -543,6 +544,9 @@ ${coveralls.maven.plugin.version} ${test.coverage.check.skip} + + ${project.basedir}/bull-report/target/site/jacoco-aggregate/jacoco.xml + From 24cbb1728e841f033afd7efb38d11cea9ffa1983 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 12 Mar 2020 12:05:02 +0100 Subject: [PATCH 1023/1786] Calls the InvalidBeanException always with both the message and the error --- .../transformer/error/InvalidBeanException.java | 16 ---------------- .../transformer/utils/ReflectionUtils.java | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java index 245eaf361..06af95436 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java @@ -20,22 +20,6 @@ * Invalid Bean exception class. */ public class InvalidBeanException extends RuntimeException { - /** - * Constructs a new invalid bean exception with the specified cause and a - * detail message of {@code (cause==null ? null : cause.toString())} - * (which typically contains the class and detail message of - * {@code cause}). This constructor is useful for invalid bean exceptions - * that are little more than wrappers for other throwable. - * - * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method). (A {@code null} value is - * permitted, and indicates that the cause is nonexistent or - * unknown.) - */ - public InvalidBeanException(final Throwable cause) { - super(cause); - } - /** * Constructs a new invalid bean exception with the specified detail message. * The cause is not initialized, and may subsequently be initialized by a diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index ecde81dc7..d7b59bd7e 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -221,7 +221,7 @@ private Function getGetterMethodFunction(final Class fieldClass, final String } catch (NoSuchMethodException e) { throw new MissingMethodException(); } catch (Throwable e) { - throw new InvalidBeanException(e); + throw new InvalidBeanException(e.getMessage(), e); } CACHE_MANAGER.cacheObject(cacheKey, function); return function; From 13c27956f9261b67a8f021c7c956fceef47148e6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 12 Mar 2020 11:48:04 +0100 Subject: [PATCH 1024/1786] Adds a new module for report aggregation purpose. It combine also the jacoco coverage among all modules --- .travis.yml | 2 +- .../error/InvalidBeanException.java | 16 ------- .../transformer/utils/ReflectionUtils.java | 2 +- bull-report/pom.xml | 42 +++++++++++++++++++ pom.xml | 4 ++ 5 files changed, 48 insertions(+), 18 deletions(-) create mode 100644 bull-report/pom.xml diff --git a/.travis.yml b/.travis.yml index 1dafc7fed..91c32a47c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install jacoco:report coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode +script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: include: diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java index 245eaf361..06af95436 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java @@ -20,22 +20,6 @@ * Invalid Bean exception class. */ public class InvalidBeanException extends RuntimeException { - /** - * Constructs a new invalid bean exception with the specified cause and a - * detail message of {@code (cause==null ? null : cause.toString())} - * (which typically contains the class and detail message of - * {@code cause}). This constructor is useful for invalid bean exceptions - * that are little more than wrappers for other throwable. - * - * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method). (A {@code null} value is - * permitted, and indicates that the cause is nonexistent or - * unknown.) - */ - public InvalidBeanException(final Throwable cause) { - super(cause); - } - /** * Constructs a new invalid bean exception with the specified detail message. * The cause is not initialized, and may subsequently be initialized by a diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index ecde81dc7..d7b59bd7e 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -221,7 +221,7 @@ private Function getGetterMethodFunction(final Class fieldClass, final String } catch (NoSuchMethodException e) { throw new MissingMethodException(); } catch (Throwable e) { - throw new InvalidBeanException(e); + throw new InvalidBeanException(e.getMessage(), e); } CACHE_MANAGER.cacheObject(cacheKey, function); return function; diff --git a/bull-report/pom.xml b/bull-report/pom.xml new file mode 100644 index 000000000..0de543b5d --- /dev/null +++ b/bull-report/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + BULL - Report + bull-report + Includes all project modules in order to combine their reports: e.g. Jacoco + + + bean-utils-library-parent + com.hotels.beans + 1.6.6-SNAPSHOT + + + + true + + + + + com.hotels.beans + bull-common + ${project.version} + + + com.hotels.beans + bull-converter + ${project.version} + + + com.hotels.beans + bull-bean-transformer + ${project.version} + + + com.hotels.beans + bull-map-transformer + ${project.version} + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1357318be..7cb8b5942 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,7 @@ bull-common bull-bean-transformer bull-converter + bull-report @@ -543,6 +544,9 @@ ${coveralls.maven.plugin.version} ${test.coverage.check.skip} + + ${project.basedir}/bull-report/target/site/jacoco-aggregate/jacoco.xml + From 3cfb874f2085042144155a8b9321572cd40965a7 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Thu, 12 Mar 2020 21:19:44 +0530 Subject: [PATCH 1025/1786] feature/issue-108-increase-test-coverage-child-branch Adding a unit test case for testing InvalidBeanException --- .../transformer/utils/ReflectionUtilsTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index af00ca4d4..55cc0b62e 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -44,6 +44,7 @@ import javax.validation.constraints.NotNull; import org.mockito.InjectMocks; +import org.mockito.Mockito; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -153,6 +154,21 @@ private Object[][] dataGetFieldValueTesting() { }; } + /** + * Tests that the method {@code getFieldValue} catches InvalidBeanException. + */ + @Test + public void testGetterMethodFunctionCatchesRuntimeExceptionAsInvalidBeanException() { + // GIVEN + MutableToFoo mutableToFoo = createMutableToFoo(null); + ReflectionUtils underTestMock = Mockito.spy(ReflectionUtils.class); + when(underTestMock.getDeclaredFieldType("id", MutableToFoo.class)).thenThrow(new RuntimeException()); + + // WHEN + Object actual = underTestMock.getFieldValue(mutableToFoo, ID_FIELD_NAME, FromFooSubClass.class); + assertNull(actual); + } + /** * Tests that the method {@code getFieldValue} throws Exception if the field does not exists. */ From 37bebb71277f0412c131219ac154f38f5c941416 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Fri, 13 Mar 2020 12:26:37 +0530 Subject: [PATCH 1026/1786] feature/issue-108-increase-test-coverage-child-branch modifying a test case --- .../com/hotels/transformer/utils/ReflectionUtilsTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 55cc0b62e..392ef6358 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -155,17 +155,17 @@ private Object[][] dataGetFieldValueTesting() { } /** - * Tests that the method {@code getFieldValue} catches InvalidBeanException. + * Tests that the method {@code getFieldValue} catches a runtime ezception as InvalidBeanException. */ @Test public void testGetterMethodFunctionCatchesRuntimeExceptionAsInvalidBeanException() { // GIVEN MutableToFoo mutableToFoo = createMutableToFoo(null); ReflectionUtils underTestMock = Mockito.spy(ReflectionUtils.class); - when(underTestMock.getDeclaredFieldType("id", MutableToFoo.class)).thenThrow(new RuntimeException()); + when(underTestMock.getDeclaredFieldType("list", MutableToFoo.class)).thenThrow(new RuntimeException()); // WHEN - Object actual = underTestMock.getFieldValue(mutableToFoo, ID_FIELD_NAME, FromFooSubClass.class); + Object actual = underTestMock.getFieldValue(mutableToFoo, LIST_FIELD_NAME, FromFooSubClass.class); assertNull(actual); } From 4d92be1515254ae7fd8992ae37ca1a5d6fdd5cf8 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Fri, 13 Mar 2020 12:38:01 +0530 Subject: [PATCH 1027/1786] feature/issue-108-increase-test-coverage-child-branch Review changes --- .../com/hotels/transformer/utils/ReflectionUtilsTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 392ef6358..413b436c2 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -155,17 +155,19 @@ private Object[][] dataGetFieldValueTesting() { } /** - * Tests that the method {@code getFieldValue} catches a runtime ezception as InvalidBeanException. + * Tests that the method {@link ReflectionUtils#getFieldValue(Object, String, Class) getFieldValue} catches a runtime exception as InvalidBeanException. */ @Test - public void testGetterMethodFunctionCatchesRuntimeExceptionAsInvalidBeanException() { + public void testGetFieldValueCatchesRuntimeExceptionAsInvalidBeanException() { // GIVEN MutableToFoo mutableToFoo = createMutableToFoo(null); ReflectionUtils underTestMock = Mockito.spy(ReflectionUtils.class); - when(underTestMock.getDeclaredFieldType("list", MutableToFoo.class)).thenThrow(new RuntimeException()); + when(underTestMock.getDeclaredFieldType(LIST_FIELD_NAME, MutableToFoo.class)).thenThrow(new RuntimeException()); // WHEN Object actual = underTestMock.getFieldValue(mutableToFoo, LIST_FIELD_NAME, FromFooSubClass.class); + + //THEN assertNull(actual); } From 7eba8de3856b8ed928cec5349ad36a041c13e69d Mon Sep 17 00:00:00 2001 From: lbhandari Date: Fri, 13 Mar 2020 13:09:48 +0530 Subject: [PATCH 1028/1786] feature/issue-108-increase-test-coverage-child-branch Asserting a method invocation --- .../com/hotels/transformer/utils/ReflectionUtilsTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 413b436c2..38f75da4c 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -24,6 +24,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -155,10 +157,10 @@ private Object[][] dataGetFieldValueTesting() { } /** - * Tests that the method {@link ReflectionUtils#getFieldValue(Object, String, Class) getFieldValue} catches a runtime exception as InvalidBeanException. + * Tests that the method {@link ReflectionUtils#getFieldValue(Object, String, Class) getFieldValue} catches a runtime exception. */ @Test - public void testGetFieldValueCatchesRuntimeExceptionAsInvalidBeanException() { + public void testGetFieldValueCatchesRuntimeException() { // GIVEN MutableToFoo mutableToFoo = createMutableToFoo(null); ReflectionUtils underTestMock = Mockito.spy(ReflectionUtils.class); @@ -169,6 +171,7 @@ public void testGetFieldValueCatchesRuntimeExceptionAsInvalidBeanException() { //THEN assertNull(actual); + verify(underTestMock, times(1)).getDeclaredField(LIST_FIELD_NAME, MutableToFoo.class); } /** From 2a39aced7c6048f6f216dfea75bc0ff0fbb20dc0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 13 Mar 2020 10:22:55 +0100 Subject: [PATCH 1029/1786] Adds the project codeowners --- .github/CODEOWNERS | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..95dcdc0ad --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,8 @@ +# CODEOWNERS file defines the users/teams that are able to approve pull requests. +# These owners will be the default owners for everything on this repo. +# https://github.com/HotelsDotCom/bull + +* @HotelsDotCom/bull-committers + +# Only some members of Customer Insights can alter the CODEOWNERS file +.github/CODEOWNERS @HotelsDotCom/bull-admin \ No newline at end of file From 5b4f36d0f82adfdb156e755de48fb5b31d61beb8 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Sun, 15 Mar 2020 01:45:29 +0530 Subject: [PATCH 1030/1786] feature/issue-108-increase-test-coverage-child-branch Adding another unit test in ReflectionUtilsTest --- .../com/hotels/beans/sample/FromFooMap.java | 1 + .../sample/immutable/ImmutableToFooMap.java | 1 + .../transformer/AbstractTransformerTest.java | 3 ++- .../utils/ReflectionUtilsTest.java | 26 +++++++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java index 2d272e2e0..658a2d36f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java @@ -34,4 +34,5 @@ public class FromFooMap { private final Map> complexMap; private final Map> veryComplexMap; private final Map> extremeComplexMap; + private final Map unparametrizedMap; } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java index 9d6e627a9..15a5b490f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java @@ -34,4 +34,5 @@ public class ImmutableToFooMap { private final Map> complexMap; private final Map> veryComplexMap; private final Map> extremeComplexMap; + private final Map unparametrizedMap; } diff --git a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java index 645618382..edf865be2 100644 --- a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java @@ -70,6 +70,7 @@ public abstract class AbstractTransformerTest { protected static final Map> COMPLEX_MAP = new HashMap<>(); protected static final Map> VERY_COMPLEX_MAP = new HashMap<>(); protected static final Map> EXTREME_COMPLEX_MAP = new HashMap<>(); + protected static final Map UNPARAMETRIZED_MAP = new HashMap<>(); protected static final String TRANSFORMER_SETTINGS_FIELD_NAME = "settings"; protected static final ReflectionUtils REFLECTION_UTILS = new ReflectionUtils(); protected static final String ITEM_1 = "donald"; @@ -104,7 +105,7 @@ protected void initObjects() { fromFooAdvFields = createFromFooAdvFields(); fromFooPrimitiveTypes = createFromFooPrimitiveTypes(); EXTREME_COMPLEX_MAP.put(fromFooSimple, SAMPLE_MAP); - fromFooMap = new FromFooMap(SAMPLE_MAP, COMPLEX_MAP, VERY_COMPLEX_MAP, EXTREME_COMPLEX_MAP); + fromFooMap = new FromFooMap(SAMPLE_MAP, COMPLEX_MAP, VERY_COMPLEX_MAP, EXTREME_COMPLEX_MAP, UNPARAMETRIZED_MAP); } /** diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 38f75da4c..f9f1d51aa 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -40,6 +40,7 @@ import java.lang.reflect.UndeclaredThrowableException; import java.math.BigInteger; import java.util.List; +import java.util.Map; import java.util.Optional; import javax.validation.constraints.NotBlank; @@ -51,6 +52,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.sample.FromFooMap; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSimpleNoGetters; import com.hotels.beans.sample.FromFooSubClass; @@ -83,6 +85,7 @@ public class ReflectionUtilsTest { private static final String DECLARING_CLASS_NAME = "declaringClassName"; private static final String INVOKE_METHOD_NAME = "invokeMethod"; private static final String VERY_COMPLEX_MAP_FIELD_NAME = "veryComplexMap"; + private static final String UNPARAMETRIZED_MAP = "unparametrizedMap"; private static final String GET_GETTER_METHOD_NAME = "getGetterMethod"; private static final String SET_NAME_METHOD_NAME = "setName"; private static final String SET_INDEX_METHOD_NAME = "setIndex"; @@ -599,6 +602,29 @@ public void testMapGenericFieldTypeWorksProperly() { assertEquals(expectedNestedMapElemType.getGenericClass(), actualNestedMapElemType.getGenericClass()); } + @Test + public void testMapGenericFieldTypeWorksProperlyForUnparametrizedMap() { + // GIVEN + MapElemType keyType = ItemType.builder() + .objectClass(Map.class) + .build(); + final MapType expectedMapType = new MapType(keyType, keyType); + Field field = underTest.getDeclaredField(UNPARAMETRIZED_MAP, FromFooMap.class); + + // WHEN + MapType actual = underTest.getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); + ItemType expectedMapKeyType = (ItemType) expectedMapType.getKeyType(); + ItemType actualMapKeyType = (ItemType) actual.getKeyType(); + ItemType expectedMapElemType = (ItemType) expectedMapType.getElemType(); + ItemType actualMapElemType = (ItemType) actual.getElemType(); + + // THEN + assertEquals(expectedMapKeyType.getObjectClass(), actualMapKeyType.getObjectClass()); + assertEquals(expectedMapKeyType.getGenericClass(), actualMapKeyType.getGenericClass()); + assertEquals(expectedMapElemType.getObjectClass(), actualMapElemType.getObjectClass()); + assertEquals(expectedMapElemType.getGenericClass(), actualMapElemType.getGenericClass()); + } + /** * Tests that the method {@code getGetterMethod} works properly. * @throws Exception in case an error occurs From 3e4f3f6ed46ff9b2c676844473f0b6d421599ff6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 15 Mar 2020 11:17:52 +0100 Subject: [PATCH 1031/1786] Modifies the handleReflectionException behaviour to return the exception to throw --- .../transformer/utils/ReflectionUtils.java | 31 +++++----- .../utils/ReflectionUtilsTest.java | 60 +++++++++++++++---- 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index ecde81dc7..5095a1bb5 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -101,8 +101,7 @@ protected Object invokeMethod(final Method method, final Object target, final Ob try { return method.invoke(target, args); } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); + throw handleReflectionException(e); } } @@ -285,8 +284,7 @@ private Object getFieldValueDirectAccess(final Object target, final String field } catch (MissingFieldException e) { throw e; } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); + throw handleReflectionException(e); } } @@ -311,8 +309,7 @@ private Field getClassDeclaredField(final String fieldName, final Class targe throw new MissingFieldException(targetClass.getName() + " does not contain field: " + fieldName); } } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); + throw handleReflectionException(e); } CACHE_MANAGER.cacheObject(cacheKey, field); return field; @@ -376,12 +373,11 @@ public void setFieldValue(final Object target, final Field field, final Object f * @param field the field to set * @param fieldValue the value to set */ - private void setFieldValueWithoutSetterMethod(final Object target, final Field field, final Object fieldValue) { + protected void setFieldValueWithoutSetterMethod(final Object target, final Field field, final Object fieldValue) { try { field.set(target, fieldValue); } catch (final Exception e) { - handleReflectionException(e); - throw new IllegalStateException(e); + throw handleReflectionException(e); } } @@ -611,18 +607,19 @@ public Class getArrayType(final Field arrayField) { /** * Throws the right exception. * @param ex the exception + * @return the exception to be thrown */ - void handleReflectionException(final Exception ex) { + protected RuntimeException handleReflectionException(final Exception ex) { + RuntimeException e; if (ex instanceof NoSuchMethodException) { - throw new MissingMethodException("Method not found: " + ex.getMessage()); + e = new MissingMethodException("Method not found: " + ex.getMessage()); } else if (ex instanceof IllegalAccessException) { - throw new IllegalStateException("Could not access method: " + ex.getMessage(), ex); + e = new IllegalStateException("Could not access method: " + ex.getMessage(), ex); + } else if (ex instanceof RuntimeException) { + e = (RuntimeException) ex; } else { - if (ex instanceof RuntimeException) { - throw (RuntimeException) ex; - } else { - throw new UndeclaredThrowableException(ex); - } + e = new UndeclaredThrowableException(ex); } + return e; } } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index af00ca4d4..067b29846 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -23,7 +23,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -217,49 +220,61 @@ private Object[][] dataGetFieldValueDirectAccessTesting() { /** * Tests that the method {@code handleReflectionException} raises the expected exception. */ - @Test(expectedExceptions = MissingMethodException.class) - public void testHandleReflectionExceptionThrowsIllegalStateExceptionWhenGivenExceptionIsNoSuchMethodException() { + @Test + public void testHandleReflectionExceptionThrowsMissingMethodExceptionWhenGivenExceptionIsNoSuchMethodException() { // GIVEN NoSuchMethodException noSuchMethodException = new NoSuchMethodException(); // WHEN - underTest.handleReflectionException(noSuchMethodException); + RuntimeException actual = underTest.handleReflectionException(noSuchMethodException); + + // THEN + assertSame(MissingMethodException.class, actual.getClass()); } /** - * Tests that the method {@code handleReflectionException} raises the expected exception. + * Tests that the method {@code handleReflectionException} returns the expected exception. */ - @Test(expectedExceptions = IllegalStateException.class) + @Test public void testHandleReflectionExceptionThrowsIllegalStateExceptionWhenGivenExceptionIsIllegalAccessException() { // GIVEN IllegalAccessException illegalAccessException = new IllegalAccessException(); // WHEN - underTest.handleReflectionException(illegalAccessException); + RuntimeException exception = underTest.handleReflectionException(illegalAccessException); + + // THEN + assertSame(IllegalStateException.class, exception.getClass()); } /** - * Tests that the method {@code handleReflectionException} raises the expected exception. + * Tests that the method {@code handleReflectionException} returns the expected exception. */ - @Test(expectedExceptions = RuntimeException.class) + @Test public void testHandleReflectionExceptionThrowsRuntimeExceptionWhenGivenExceptionIsRuntimeException() { // GIVEN RuntimeException runtimeException = new RuntimeException(); // WHEN - underTest.handleReflectionException(runtimeException); + RuntimeException exception = underTest.handleReflectionException(runtimeException); + + // THEN + assertSame(RuntimeException.class, exception.getClass()); } /** - * Tests that the method {@code handleReflectionException} raises the expected exception. + * Tests that the method {@code handleReflectionException} returns the expected exception. */ - @Test(expectedExceptions = UndeclaredThrowableException.class) + @Test public void testHandleReflectionExceptionThrowsUndeclaredThrowableExceptionWhenGivenExceptionIsInvalidBeanException() { // GIVEN - Exception exception = new Exception(); + Exception genericException = new Exception(); // WHEN - underTest.handleReflectionException(exception); + RuntimeException actual = underTest.handleReflectionException(genericException); + + // THEN + assertSame(UndeclaredThrowableException.class, actual.getClass()); } /** @@ -673,12 +688,30 @@ public void testSetFieldValueWorksProperly() { assertEquals(ONE, mutableToFoo.getId()); } + @Test + public void testSetFieldValueInvokesTheSetterMethodInCaseAnExceptionIsRaised() { + // GIVEN + ReflectionUtils underTestMock = spy(ReflectionUtils.class); + MutableToFooSimple mutableToFoo = new MutableToFooSimple(); + Field idField = underTest.getDeclaredField(ID_FIELD_NAME, mutableToFoo.getClass()); + doThrow(RuntimeException.class).when(underTestMock).setFieldValueWithoutSetterMethod(mutableToFoo, idField, ONE); + + // WHEN + underTestMock.setFieldValue(mutableToFoo, idField, ONE); + + // THEN + assertEquals(ONE, mutableToFoo.getId()); + } + /** * Tests that the method {@code invokeMethod} manages the exception properly. * @param testCaseDescription the test case description + * @param targetObject the object on which the method has to be invoked + * @param methodNameToInvoke the name of the method to invoke * @param methodArg the argument to pass to the invoke method * @param isAccessible the accessibility that the {@code invokeMethod} must have * @param expectedException the expected exception class + * @throws Exception if something goes wrong */ @Test(dataProvider = "dataInvokeMethodTesting") public void testInvokeMethodCorrectlyHandlesExceptions(final String testCaseDescription, final Object targetObject, final String methodNameToInvoke, @@ -715,6 +748,7 @@ private Object[][] dataInvokeMethodTesting() { /** * Test that the method: {@code getRealTarget} returns the object contained in the Optional. + * @throws Exception if something goes wrong */ @Test public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() throws Exception { From 8386e911014febd35845f7a51a41e3d3a24b5005 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Sun, 15 Mar 2020 16:06:53 +0530 Subject: [PATCH 1032/1786] feature/issue-108-increase-test-coverage-child-branch Review changes: --- .../transformer/utils/ReflectionUtilsTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 5f7cd91fb..114bf974e 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -26,9 +26,9 @@ import static org.junit.Assert.assertSame; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -597,15 +597,15 @@ public void testMapGenericFieldTypeWorksProperly() { .build(); final MapType expectedElemType = new MapType(keyType, keyType); final MapType expectedMapType = new MapType(keyType, expectedElemType); + ItemType expectedMapKeyType = (ItemType) expectedMapType.getKeyType(); + ItemType expectedNestedMapKeyType = (ItemType) ((MapType) expectedMapType.getElemType()).getKeyType(); + ItemType expectedNestedMapElemType = (ItemType) ((MapType) expectedMapType.getElemType()).getElemType(); Field field = underTest.getDeclaredField(VERY_COMPLEX_MAP_FIELD_NAME, ImmutableToSubFoo.class); // WHEN MapType actual = underTest.getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); - ItemType expectedMapKeyType = (ItemType) expectedMapType.getKeyType(); ItemType actualMapKeyType = (ItemType) actual.getKeyType(); - ItemType expectedNestedMapKeyType = (ItemType) ((MapType) expectedMapType.getElemType()).getKeyType(); ItemType actualNestedMapKeyType = (ItemType) ((MapType) actual.getElemType()).getKeyType(); - ItemType expectedNestedMapElemType = (ItemType) ((MapType) expectedMapType.getElemType()).getElemType(); ItemType actualNestedMapElemType = (ItemType) ((MapType) actual.getElemType()).getElemType(); // THEN @@ -624,13 +624,13 @@ public void testMapGenericFieldTypeWorksProperlyForUnparametrizedMap() { .objectClass(Map.class) .build(); final MapType expectedMapType = new MapType(keyType, keyType); + ItemType expectedMapKeyType = (ItemType) expectedMapType.getKeyType(); + ItemType expectedMapElemType = (ItemType) expectedMapType.getElemType(); Field field = underTest.getDeclaredField(UNPARAMETRIZED_MAP, FromFooMap.class); // WHEN MapType actual = underTest.getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); - ItemType expectedMapKeyType = (ItemType) expectedMapType.getKeyType(); ItemType actualMapKeyType = (ItemType) actual.getKeyType(); - ItemType expectedMapElemType = (ItemType) expectedMapType.getElemType(); ItemType actualMapElemType = (ItemType) actual.getElemType(); // THEN From b95b68ce9d9e5568565d640bbf8d43f91c8abd6a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2020 02:18:23 +0000 Subject: [PATCH 1033/1786] Bump mockito-core from 3.3.0 to 3.3.3 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.3.0 to 3.3.3. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.3.0...v3.3.3) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a83f7984d..1c6ac26a6 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 0.11 2.8.6 7.1.0 - 3.3.0 + 3.3.3 1.3.0 2.0.1.Final From 7b907d775385001566161b04eb81206e67b217de Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 08:14:02 +0100 Subject: [PATCH 1034/1786] Adds the bull-admins as default PR reviers and updates the changelog with the changes --- .github/CODEOWNERS | 2 +- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 95dcdc0ad..b4a085fa5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,7 +2,7 @@ # These owners will be the default owners for everything on this repo. # https://github.com/HotelsDotCom/bull -* @HotelsDotCom/bull-committers +* @HotelsDotCom/bull-committers @HotelsDotCom/bull-admin # Only some members of Customer Insights can alter the CODEOWNERS file .github/CODEOWNERS @HotelsDotCom/bull-admin \ No newline at end of file diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 629d77dd7..f4258f735 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). -* Updated `mockito-core` version to `3.3.0` (was `3.2.4`). +* Updated `mockito-core` version to `3.3.3` (was `3.2.4`). * Updated `spring-boot-starter-test` version to `2.2.5.RELEASE` (was `2.2.4.RELEASE`). * Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bcf86de0..83864b28b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). -* Updated `mockito-core` version to `3.3.0` (was `3.2.4`). +* Updated `mockito-core` version to `3.3.3` (was `3.2.4`). * Updated `spring-boot-starter-test` version to `2.2.5.RELEASE` (was `2.2.4.RELEASE`). * Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). From db27cd9889e9f2e11a088a0b744b6d74f31e8cda Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 09:18:40 +0100 Subject: [PATCH 1035/1786] Includes a test for the getDeclaredFieldMethod --- .../utils/ReflectionUtilsTest.java | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 114bf974e..1704efd25 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -55,6 +55,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooMap; import com.hotels.beans.sample.FromFooSimple; import com.hotels.beans.sample.FromFooSimpleNoGetters; @@ -88,12 +89,13 @@ public class ReflectionUtilsTest { private static final String DECLARING_CLASS_NAME = "declaringClassName"; private static final String INVOKE_METHOD_NAME = "invokeMethod"; private static final String VERY_COMPLEX_MAP_FIELD_NAME = "veryComplexMap"; - private static final String UNPARAMETRIZED_MAP = "unparametrizedMap"; + private static final String UNPARAMETRIZED_MAP_FIELD_NAME = "unparametrizedMap"; private static final String GET_GETTER_METHOD_NAME = "getGetterMethod"; private static final String SET_NAME_METHOD_NAME = "setName"; private static final String SET_INDEX_METHOD_NAME = "setIndex"; private static final String INDEX_NUMBER = "123"; private static final String GET_REAL_TARGET_METHOD_NAME = "getRealTarget"; + private static final String GET_CLASS_DECLARED_FIELD_METHOD_NAME = "getClassDeclaredField"; /** * The class to be tested. @@ -499,6 +501,29 @@ public void testGetDeclaredFieldWorksProperly(final String testCaseDescription, assertNotNull(actual); } + /** + * Test that the method: {@code getClassDeclaredField} throws the right exception. + * @throws Exception if the invoke method fails + */ + @Test + public void testGetClassDeclaredFieldThrowsTheRightException() throws Exception { + //GIVEN + + //WHEN + InvocationTargetException actualException = null; + try { + Method getClassDeclaredFieldMethod = underTest.getClass().getDeclaredMethod(GET_CLASS_DECLARED_FIELD_METHOD_NAME, String.class, Class.class); + getClassDeclaredFieldMethod.setAccessible(true); + getClassDeclaredFieldMethod.invoke(underTest, null, FromFoo.class); + } catch (final InvocationTargetException e) { + actualException = e; + } + + // THEN + assertNotNull(actualException); + assertEquals(NullPointerException.class, actualException.getTargetException().getClass()); + } + /** * Creates the parameters to be used for testing the method {@code getDeclaredField}. * @return parameters to be used for testing the the method {@code getDeclaredField}. @@ -626,7 +651,7 @@ public void testMapGenericFieldTypeWorksProperlyForUnparametrizedMap() { final MapType expectedMapType = new MapType(keyType, keyType); ItemType expectedMapKeyType = (ItemType) expectedMapType.getKeyType(); ItemType expectedMapElemType = (ItemType) expectedMapType.getElemType(); - Field field = underTest.getDeclaredField(UNPARAMETRIZED_MAP, FromFooMap.class); + Field field = underTest.getDeclaredField(UNPARAMETRIZED_MAP_FIELD_NAME, FromFooMap.class); // WHEN MapType actual = underTest.getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); From d138d9e19a9e41233a23875e54160343ef1ed9bb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 11:43:22 +0100 Subject: [PATCH 1036/1786] Modifies a test to increase the coverage --- .../hotels/beans/transformer/TransformerImpl.java | 2 +- .../ImmutableObjectTransformationTest.java | 15 +++++++++++---- .../MixedObjectTransformationTest.java | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 0c6c6ea99..d7dc83d1a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -170,7 +170,7 @@ private String getFormattedConstructorArgs(final Class targetClass, final * @param constructor the all args constructor * @return true if the parameter names are defined or the parameters are annotated with: {@link ConstructorArg} */ - private boolean canBeInjectedByConstructorParams(final Constructor constructor) { + protected boolean canBeInjectedByConstructorParams(final Constructor constructor) { final String cacheKey = "CanBeInjectedByConstructorParams-" + constructor.getDeclaringClass().getName(); return cacheManager.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { final boolean res = classUtils.areParameterNamesAvailable(constructor) || classUtils.allParameterAnnotatedWith(constructor, ConstructorArg.class); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 340d3b9ee..6c86cf47b 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -26,11 +26,13 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import static org.springframework.test.util.ReflectionTestUtils.setField; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.math.BigInteger; @@ -67,6 +69,7 @@ import com.hotels.transformer.error.InvalidFunctionException; import com.hotels.transformer.model.FieldMapping; import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.utils.ClassUtils; import com.hotels.transformer.utils.ReflectionUtils; /** @@ -100,7 +103,7 @@ public void afterMethod() { */ @Test(dataProvider = "dataDefaultTransformationTesting") public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, final BeanTransformer transformer, final Object sourceObject, - final Class targetObjectClass) { + final Class targetObjectClass) { //GIVEN //WHEN @@ -154,20 +157,23 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { * @param expectedId the expected id * @param expectedPhoneNumbers the expected phone number */ + @SuppressWarnings("unchecked") @Test(dataProvider = "dataCompositeFieldNameTesting") public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(final String testCaseDescription, final Object sourceObject, final String expectedName, final BigInteger expectedId, final int[] expectedPhoneNumbers) { //GIVEN - FieldMapping phoneNumbersMapping = new FieldMapping<>(PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME, PHONE_NUMBER_DEST_FIELD_NAME); + TransformerImpl underTestMock = spy(TransformerImpl.class); + Constructor beanAllArgsConstructor = new ClassUtils().getAllArgsConstructor(ImmutableFlatToFoo.class); + when(underTestMock.canBeInjectedByConstructorParams(beanAllArgsConstructor)).thenReturn(false); + FieldMapping phoneNumbersMapping = new FieldMapping<>(PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME, PHONE_NUMBER_DEST_FIELD_NAME); //WHEN - ImmutableFlatToFoo actual = underTest.withFieldMapping(phoneNumbersMapping).transform(sourceObject, ImmutableFlatToFoo.class); + ImmutableFlatToFoo actual = underTestMock.withFieldMapping(phoneNumbersMapping).transform(sourceObject, ImmutableFlatToFoo.class); //THEN assertEquals(expectedName, actual.getName()); assertEquals(expectedId, actual.getId()); assertEquals(expectedPhoneNumbers, actual.getPhoneNumbers()); - underTest.resetFieldsMapping(); } /** @@ -520,6 +526,7 @@ private void initGetDestFieldNameTestMock(final String declaringClassName, final /** * Restores the initial object status before testing method: {@code getDestFieldName}. + * @param getDestFieldNameMethod the destination field name method */ private void restoreObjects(final Method getDestFieldNameMethod) { getDestFieldNameMethod.setAccessible(false); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index de59a3ad7..b766f9c75 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -81,7 +81,7 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { //GIVEN //WHEN - final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); + BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); //THEN From 4421c55c81f92acee6310262b7201503935a6241 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 12:46:47 +0100 Subject: [PATCH 1037/1786] Adds a test case for the injectValues method --- .../beans/transformer/TransformerImpl.java | 2 +- .../ImmutableObjectTransformationTest.java | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index d7dc83d1a..791bc3995 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -191,7 +191,7 @@ protected boolean canBeInjectedByConstructorParams(final Constructor constructor * @return a list containing the values for the destination constructor. * @throws InvalidBeanException {@link InvalidBeanException} if there is an error while retrieving the constructor args parameter */ - private Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { + protected Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { final Parameter[] constructorParameters = classUtils.getConstructorParameters(constructor); final Object[] constructorArgsValues = new Object[constructorParameters.length]; range(0, constructorParameters.length) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 6c86cf47b..1bbc2d6d3 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -33,6 +33,7 @@ import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.math.BigInteger; @@ -62,6 +63,7 @@ import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; +import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.transformer.AbstractTransformerTest; import com.hotels.transformer.annotation.ConstructorArg; import com.hotels.transformer.cache.CacheManager; @@ -84,6 +86,8 @@ public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTe private static final String GROSS_PRICE_FIELD_NAME = "price.grossPrice"; private static final String WORK_FIELD_NAME = "work"; private static final boolean ACTIVE = true; + private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; + private static final String INJECT_VALUES_METHOD_NAME = "injectValues"; /** * After method actions. @@ -506,6 +510,37 @@ public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { } + /** + * Test that an {@link InvalidBeanException} is raised if the class instantiation fails when the method {@code injectValues()} is called. + * @throws Exception if something goes wrong + */ + @Test + @SuppressWarnings("unchecked") + public void testInjectValuesThrowsException() throws Exception { + //GIVEN + TransformerImpl underTestMock = spy(TransformerImpl.class); + ClassUtils classUtils = mock(ClassUtils.class); + Constructor constructor = classUtils.getAllArgsConstructor(MutableToFooSimple.class); + when(classUtils.getInstance(constructor)).thenThrow(InvalidBeanException.class); + when(classUtils.getConstructorParameters(constructor)).thenReturn(new Parameter[] {}); + setField(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); + Method injectValuesMethod = + TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); + injectValuesMethod.setAccessible(true); + + //WHEN + InvocationTargetException actualException = null; + try { + injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); + } catch (final InvocationTargetException e) { + actualException = e; + } + + // THEN + assertNotNull(actualException); + assertEquals(InvalidBeanException.class, actualException.getTargetException().getClass()); + } + /** * Initializes the mocks required for testing method: {@code getDestFieldName}. * @param declaringClassName the declaring class name From 5fab5858a8374486ff83ab06f9f32dadc6b86920 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 14:30:00 +0100 Subject: [PATCH 1038/1786] Modifies the test in order to make coveralls aware of it --- .../beans/transformer/TransformerImpl.java | 3 ++- .../ImmutableObjectTransformationTest.java | 21 +++---------------- .../hotels/transformer/utils/ClassUtils.java | 2 +- 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 791bc3995..a4aaffaab 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -102,7 +102,8 @@ protected final void transform(final T sourceObj, final K targetObject, f * @return a copy of the source object into the destination object * @throws InvalidBeanException {@link InvalidBeanException} if the target object is not compliant with the requirements */ - private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb, final boolean forceConstructorInjection) { + protected K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, + final String breadcrumb, final boolean forceConstructorInjection) { final Object[] constructorArgs; if (forceConstructorInjection || canBeInjectedByConstructorParams(constructor)) { constructorArgs = getConstructorArgsValues(sourceObj, targetClass, constructor, breadcrumb); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 1bbc2d6d3..33b16649f 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -33,7 +33,6 @@ import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.math.BigInteger; @@ -512,11 +511,9 @@ public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { /** * Test that an {@link InvalidBeanException} is raised if the class instantiation fails when the method {@code injectValues()} is called. - * @throws Exception if something goes wrong */ - @Test - @SuppressWarnings("unchecked") - public void testInjectValuesThrowsException() throws Exception { + @Test(expectedExceptions = InvalidBeanException.class) + public void testInjectValuesThrowsException() { //GIVEN TransformerImpl underTestMock = spy(TransformerImpl.class); ClassUtils classUtils = mock(ClassUtils.class); @@ -524,21 +521,9 @@ public void testInjectValuesThrowsException() throws Exception { when(classUtils.getInstance(constructor)).thenThrow(InvalidBeanException.class); when(classUtils.getConstructorParameters(constructor)).thenReturn(new Parameter[] {}); setField(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); - Method injectValuesMethod = - TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); - injectValuesMethod.setAccessible(true); //WHEN - InvocationTargetException actualException = null; - try { - injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); - } catch (final InvocationTargetException e) { - actualException = e; - } - - // THEN - assertNotNull(actualException); - assertEquals(InvalidBeanException.class, actualException.getTargetException().getClass()); + underTestMock.injectValues(fromFooSimple, MutableToFooSimple.class, constructor, null, true); } /** diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 2ca296f69..eeee55322 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -512,7 +512,7 @@ public Supplier getNoArgsConstructor(final Class clazz) { * @param the object type * @return the all args constructor */ - public Constructor getAllArgsConstructor(final Class clazz) { + public Constructor getAllArgsConstructor(final Class clazz) { final String cacheKey = "AllArgsConstructor-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); From 73ac85cb012aa2f9c98d2d723678344a28dd67d8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 14:55:11 +0100 Subject: [PATCH 1039/1786] Avoids the the handleException throws an exception --- .../beans/transformer/TransformerImpl.java | 3 +-- .../ImmutableObjectTransformationTest.java | 22 ++++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index a4aaffaab..791bc3995 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -102,8 +102,7 @@ protected final void transform(final T sourceObj, final K targetObject, f * @return a copy of the source object into the destination object * @throws InvalidBeanException {@link InvalidBeanException} if the target object is not compliant with the requirements */ - protected K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, - final String breadcrumb, final boolean forceConstructorInjection) { + private K injectValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb, final boolean forceConstructorInjection) { final Object[] constructorArgs; if (forceConstructorInjection || canBeInjectedByConstructorParams(constructor)) { constructorArgs = getConstructorArgsValues(sourceObj, targetClass, constructor, breadcrumb); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 33b16649f..49c9e1d23 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -33,6 +33,7 @@ import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.math.BigInteger; @@ -511,19 +512,34 @@ public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { /** * Test that an {@link InvalidBeanException} is raised if the class instantiation fails when the method {@code injectValues()} is called. + * @throws Exception if something goes wrong */ - @Test(expectedExceptions = InvalidBeanException.class) - public void testInjectValuesThrowsException() { + @Test + @SuppressWarnings("unchecked") + public void testInjectValuesThrowsException() throws Exception { //GIVEN TransformerImpl underTestMock = spy(TransformerImpl.class); ClassUtils classUtils = mock(ClassUtils.class); Constructor constructor = classUtils.getAllArgsConstructor(MutableToFooSimple.class); when(classUtils.getInstance(constructor)).thenThrow(InvalidBeanException.class); when(classUtils.getConstructorParameters(constructor)).thenReturn(new Parameter[] {}); + when(classUtils.areParameterNamesAvailable(constructor)).thenReturn(true); setField(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); + Method injectValuesMethod = + TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); + injectValuesMethod.setAccessible(true); //WHEN - underTestMock.injectValues(fromFooSimple, MutableToFooSimple.class, constructor, null, true); + InvocationTargetException actualException = null; + try { + injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); + } catch (final InvocationTargetException e) { + actualException = e; + } + + // THEN + assertNotNull(actualException); + assertEquals(InvalidBeanException.class, actualException.getTargetException().getClass()); } /** From 226fe776c11c8e0d1eef299cc09bcc5d3ae1461e Mon Sep 17 00:00:00 2001 From: lbhandari Date: Mon, 16 Mar 2020 19:46:55 +0530 Subject: [PATCH 1040/1786] feature/issue-108-increase-test-coverage-child Testing if the fix works --- .../java/com/hotels/beans/transformer/TransformerImpl.java | 2 +- .../beans/transformer/ImmutableObjectTransformationTest.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 791bc3995..6f219e6ab 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -131,7 +131,7 @@ private K injectValues(final T sourceObj, final Class targetClass, fin * @return a copy of the source object into the destination object * @throws InvalidBeanException {@link InvalidBeanException} if the target object is not compliant with the requirements */ - private K handleInjectionException(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb, + protected K handleInjectionException(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb, final Object[] constructorArgs, final boolean forceConstructorInjection, final Exception e) { String errorMsg; if (!classUtils.areParameterNamesAvailable(constructor)) { diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 49c9e1d23..e20f7c01d 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -25,6 +25,10 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -524,6 +528,7 @@ public void testInjectValuesThrowsException() throws Exception { when(classUtils.getInstance(constructor)).thenThrow(InvalidBeanException.class); when(classUtils.getConstructorParameters(constructor)).thenReturn(new Parameter[] {}); when(classUtils.areParameterNamesAvailable(constructor)).thenReturn(true); + doThrow(new InvalidBeanException("dummy exception")).when(underTestMock).handleInjectionException(any(), any(), any(), any(), any(), anyBoolean(), any()); setField(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); Method injectValuesMethod = TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); From 581c6c2c8b55ab3958ce2721e7399269b4c79fb3 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Mon, 16 Mar 2020 19:48:58 +0530 Subject: [PATCH 1041/1786] feature/issue-108-increase-test-coverage-child'. Removing unused import --- .../beans/transformer/ImmutableObjectTransformationTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index e20f7c01d..8d722e3a1 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -27,7 +27,6 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; From 5e2768f68e690e8424435133f528a2486fa7f928 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Mon, 16 Mar 2020 20:13:56 +0530 Subject: [PATCH 1042/1786] feature/issue-108-increase-test-coverage-child Returning object instead of throwing exception --- .../ImmutableObjectTransformationTest.java | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 8d722e3a1..5e6e09d58 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -27,7 +27,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -36,7 +36,6 @@ import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.math.BigInteger; @@ -527,23 +526,17 @@ public void testInjectValuesThrowsException() throws Exception { when(classUtils.getInstance(constructor)).thenThrow(InvalidBeanException.class); when(classUtils.getConstructorParameters(constructor)).thenReturn(new Parameter[] {}); when(classUtils.areParameterNamesAvailable(constructor)).thenReturn(true); - doThrow(new InvalidBeanException("dummy exception")).when(underTestMock).handleInjectionException(any(), any(), any(), any(), any(), anyBoolean(), any()); + doReturn(new InvalidBeanException("dummy exception")).when(underTestMock).handleInjectionException(any(), any(), any(), any(), any(), anyBoolean(), any()); setField(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); Method injectValuesMethod = TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); injectValuesMethod.setAccessible(true); //WHEN - InvocationTargetException actualException = null; - try { - injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); - } catch (final InvocationTargetException e) { - actualException = e; - } + Object e = injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); // THEN - assertNotNull(actualException); - assertEquals(InvalidBeanException.class, actualException.getTargetException().getClass()); + assertNotNull(e); } /** From 6630c4528947b567d7884a44a12db8a967e0ae02 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Mon, 16 Mar 2020 20:22:11 +0530 Subject: [PATCH 1043/1786] feature/issue-108-increase-test-coverage-child' Adding some more asserts --- .../transformer/ImmutableObjectTransformationTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 5e6e09d58..30a07a87b 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -533,10 +533,13 @@ public void testInjectValuesThrowsException() throws Exception { injectValuesMethod.setAccessible(true); //WHEN - Object e = injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); + Object actual = injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); // THEN - assertNotNull(e); + assertNotNull(actual); + assertTrue(actual instanceof InvalidBeanException); + InvalidBeanException actualException = (InvalidBeanException) actual; + assertEquals(actualException.getMessage(), "dummy exception"); } /** From a7ec8ab68b1aa5682cbd95bda9cd17bf1f3cefc0 Mon Sep 17 00:00:00 2001 From: lbhandari Date: Mon, 16 Mar 2020 21:17:55 +0530 Subject: [PATCH 1044/1786] feature/issue-108-increase-test-coverage-child Review changes : simplifying the code --- .../ImmutableObjectTransformationTest.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 30a07a87b..d33f5bd38 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -25,6 +25,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doReturn; @@ -520,26 +521,23 @@ public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { @SuppressWarnings("unchecked") public void testInjectValuesThrowsException() throws Exception { //GIVEN + InvalidBeanException expectedException = new InvalidBeanException("Dummy exception"); TransformerImpl underTestMock = spy(TransformerImpl.class); ClassUtils classUtils = mock(ClassUtils.class); Constructor constructor = classUtils.getAllArgsConstructor(MutableToFooSimple.class); when(classUtils.getInstance(constructor)).thenThrow(InvalidBeanException.class); when(classUtils.getConstructorParameters(constructor)).thenReturn(new Parameter[] {}); when(classUtils.areParameterNamesAvailable(constructor)).thenReturn(true); - doReturn(new InvalidBeanException("dummy exception")).when(underTestMock).handleInjectionException(any(), any(), any(), any(), any(), anyBoolean(), any()); + doReturn(expectedException).when(underTestMock).handleInjectionException(any(), any(), any(), any(), any(), anyBoolean(), any()); setField(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); Method injectValuesMethod = - TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); + TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); injectValuesMethod.setAccessible(true); - //WHEN Object actual = injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); - // THEN assertNotNull(actual); - assertTrue(actual instanceof InvalidBeanException); - InvalidBeanException actualException = (InvalidBeanException) actual; - assertEquals(actualException.getMessage(), "dummy exception"); + assertSame(expectedException, actual); } /** From f0f3ce37ed4a2182a8eff1974708c26300ff92cf Mon Sep 17 00:00:00 2001 From: lbhandari Date: Mon, 16 Mar 2020 21:55:50 +0530 Subject: [PATCH 1045/1786] feature/issue-108-increase-test-coverage-child Review changes --- .../ImmutableObjectTransformationTest.java | 34 --------------- .../MutableObjectTransformationTest.java | 43 +++++++++++++++++++ 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index d33f5bd38..6c86cf47b 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -25,10 +25,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -66,7 +62,6 @@ import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.beans.sample.mutable.MutableToFooSimple; import com.hotels.transformer.AbstractTransformerTest; import com.hotels.transformer.annotation.ConstructorArg; import com.hotels.transformer.cache.CacheManager; @@ -89,8 +84,6 @@ public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTe private static final String GROSS_PRICE_FIELD_NAME = "price.grossPrice"; private static final String WORK_FIELD_NAME = "work"; private static final boolean ACTIVE = true; - private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; - private static final String INJECT_VALUES_METHOD_NAME = "injectValues"; /** * After method actions. @@ -513,33 +506,6 @@ public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { } - /** - * Test that an {@link InvalidBeanException} is raised if the class instantiation fails when the method {@code injectValues()} is called. - * @throws Exception if something goes wrong - */ - @Test - @SuppressWarnings("unchecked") - public void testInjectValuesThrowsException() throws Exception { - //GIVEN - InvalidBeanException expectedException = new InvalidBeanException("Dummy exception"); - TransformerImpl underTestMock = spy(TransformerImpl.class); - ClassUtils classUtils = mock(ClassUtils.class); - Constructor constructor = classUtils.getAllArgsConstructor(MutableToFooSimple.class); - when(classUtils.getInstance(constructor)).thenThrow(InvalidBeanException.class); - when(classUtils.getConstructorParameters(constructor)).thenReturn(new Parameter[] {}); - when(classUtils.areParameterNamesAvailable(constructor)).thenReturn(true); - doReturn(expectedException).when(underTestMock).handleInjectionException(any(), any(), any(), any(), any(), anyBoolean(), any()); - setField(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); - Method injectValuesMethod = - TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); - injectValuesMethod.setAccessible(true); - //WHEN - Object actual = injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); - // THEN - assertNotNull(actual); - assertSame(expectedException, actual); - } - /** * Initializes the mocks required for testing method: {@code getDestFieldName}. * @param declaringClassName the declaring class name diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 62f99e608..14233e245 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -24,9 +24,21 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import static org.springframework.test.util.ReflectionTestUtils.setField; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; + import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -43,6 +55,7 @@ import com.hotels.transformer.error.InvalidBeanException; import com.hotels.transformer.error.MissingFieldException; import com.hotels.transformer.model.FieldTransformer; +import com.hotels.transformer.utils.ClassUtils; /** * Unit test for all {@link BeanTransformer} functions related to Mutable type Java Beans. @@ -50,6 +63,8 @@ public class MutableObjectTransformationTest extends AbstractBeanTransformerTest { private static final boolean ACTIVE = true; private static final String PRICE_FIELD_NAME = "price"; + private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; + private static final String INJECT_VALUES_METHOD_NAME = "injectValues"; /** * Test that an exception is thrown if there is no default constructor defined for the mutable bean object. @@ -355,4 +370,32 @@ public void testThatBothPrimitiveTypeTransformationAndCustomTransformationAreExe underTest.setPrimitiveTypeConversionEnabled(false); underTest.removeFieldTransformer(PRICE_FIELD_NAME); } + + /** + * Test that an {@link InvalidBeanException} is raised if the class instantiation fails when the method {@code injectValues()} is called. + * @throws Exception if something goes wrong + */ + @Test + public void testInjectValuesThrowsException() throws Exception { + //GIVEN + InvalidBeanException expectedException = new InvalidBeanException("Dummy exception"); + TransformerImpl underTestMock = spy(TransformerImpl.class); + ClassUtils classUtils = mock(ClassUtils.class); + Constructor constructor = classUtils.getAllArgsConstructor(MutableToFooSimple.class); + when(classUtils.getInstance(constructor)).thenThrow(InvalidBeanException.class); + when(classUtils.getConstructorParameters(constructor)).thenReturn(new Parameter[] {}); + when(classUtils.areParameterNamesAvailable(constructor)).thenReturn(true); + doReturn(expectedException).when(underTestMock).handleInjectionException(any(), any(), any(), any(), any(), anyBoolean(), any()); + setField(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); + Method injectValuesMethod = + TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); + injectValuesMethod.setAccessible(true); + + //WHEN + Object actual = injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); + + // THEN + assertNotNull(actual); + assertSame(expectedException, actual); + } } From 96506db8296aa0206d0a3b113e654611ec324be8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 17:36:29 +0100 Subject: [PATCH 1046/1786] Changed code owners --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b4a085fa5..95dcdc0ad 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,7 +2,7 @@ # These owners will be the default owners for everything on this repo. # https://github.com/HotelsDotCom/bull -* @HotelsDotCom/bull-committers @HotelsDotCom/bull-admin +* @HotelsDotCom/bull-committers # Only some members of Customer Insights can alter the CODEOWNERS file .github/CODEOWNERS @HotelsDotCom/bull-admin \ No newline at end of file From ae9bbb1af9e24ff5cb2fd9293ba305e43600e3b2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 17:59:00 +0100 Subject: [PATCH 1047/1786] Prepares the release and updates the changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83864b28b..257a4ace7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.6.6] TBD +### [1.6.6] 2020.03.16 ### Added * Added `maven-spotless-plugin` for the code automatic formatting during the maven build * Added `coveralls-maven-plugin` for the test coverage analysis and report during the maven build: [Coverall report](https://coveralls.io/github/HotelsDotCom/bull) From 12c4f77916838b0e23e725d45dc357dc6ee16c77 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 18:01:04 +0100 Subject: [PATCH 1048/1786] [maven-release-plugin] prepare release 1.6.6 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 6 ++---- pom.xml | 6 +++--- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 3bfd72547..b09133f48 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.6-SNAPSHOT + 1.6.6 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e4f641114..bbd5db480 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.6-SNAPSHOT + 1.6.6 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index ce92c61e6..39c141820 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.6-SNAPSHOT + 1.6.6 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0d93e2fd9..37a7b7cb1 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.6-SNAPSHOT + 1.6.6 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 0de543b5d..f4b5084b6 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 BULL - Report bull-report @@ -10,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.6-SNAPSHOT + 1.6.6 diff --git a/pom.xml b/pom.xml index 1c6ac26a6..67fc0e255 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.6-SNAPSHOT + 1.6.6 pom 2019 @@ -94,7 +94,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.6.6 @@ -733,7 +733,7 @@ ${spotless.plugin.skip} - + ${import.order} From c19e6a4162b5a047bc34c7beaf5096e8f94525da Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 16 Mar 2020 18:01:17 +0100 Subject: [PATCH 1049/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index b09133f48..9ea394df6 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.6 + 1.6.7-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index bbd5db480..36574e312 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.6 + 1.6.7-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 39c141820..6824c0fce 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.6 + 1.6.7-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 37a7b7cb1..810e8469c 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.6 + 1.6.7-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index f4b5084b6..aa7a1307f 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.6 + 1.6.7-SNAPSHOT diff --git a/pom.xml b/pom.xml index 67fc0e255..7e89a7150 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.6 + 1.6.7-SNAPSHOT pom 2019 @@ -94,7 +94,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.6.6 + HEAD From 08d06d96a7e08b61ff62c6765ce0aaf8fa3bc3a1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 23 Mar 2020 09:02:15 +0100 Subject: [PATCH 1050/1786] Increase the jacoco threshold --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7e89a7150..af2ce4dad 100644 --- a/pom.xml +++ b/pom.xml @@ -68,8 +68,8 @@ 1.0 0.90 1.0 - 0.85 - 0.88 + 0.87 + 0.90 0.90 **/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* From 4bd110ad55afda4a0b036405ba63509da4deca55 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Mar 2020 14:35:36 +0100 Subject: [PATCH 1051/1786] Adds the instruction to add the bull badge --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 96fb88e00..ab634bff6 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) +[![Documentation](https://img.shields.io/badge/Documentation-blue.svg)](https://go/paved-road) [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) [![Coverage Status](https://coveralls.io/repos/github/HotelsDotCom/bull/badge.svg?branch=master)](https://coveralls.io/github/HotelsDotCom/bull?branch=master) @@ -819,6 +820,17 @@ The application's logo has been designed by: Rob Light. All the instructions for releasing a new version are available at: [RELEASES.md](RELEASE.md) +## Badge your project + +![Bull enabled](https://img.shields.io/badge/bull-enabled-critical) + +Add the following row in your Markdown file. + +``` +![Bull enabled](https://img.shields.io/badge/bull-enabled-critical) +``` + + ## Legal This project is available under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html). From fd4edefb4baa41310b72e4c54f82402be66dfd4a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Mar 2020 14:40:41 +0100 Subject: [PATCH 1052/1786] Chages the bull badge color --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ab634bff6..3c401ef19 100644 --- a/README.md +++ b/README.md @@ -822,12 +822,12 @@ All the instructions for releasing a new version are available at: [RELEASES.md] ## Badge your project -![Bull enabled](https://img.shields.io/badge/bull-enabled-critical) +![Bull enabled](https://img.shields.io/badge/bull-enabled-red) Add the following row in your Markdown file. ``` -![Bull enabled](https://img.shields.io/badge/bull-enabled-critical) +![Bull enabled](https://img.shields.io/badge/bull-enabled-red) ``` From 4b32ea2a4946f0789ab952cf63a3a21c0fd2b5b2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Mar 2020 14:55:59 +0100 Subject: [PATCH 1053/1786] Chages the bull badge color --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3c401ef19..ae38c626a 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) -[![Documentation](https://img.shields.io/badge/Documentation-blue.svg)](https://go/paved-road) [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) [![Coverage Status](https://coveralls.io/repos/github/HotelsDotCom/bull/badge.svg?branch=master)](https://coveralls.io/github/HotelsDotCom/bull?branch=master) @@ -822,12 +821,12 @@ All the instructions for releasing a new version are available at: [RELEASES.md] ## Badge your project -![Bull enabled](https://img.shields.io/badge/bull-enabled-red) +[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) Add the following row in your Markdown file. ``` -![Bull enabled](https://img.shields.io/badge/bull-enabled-red) +[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) ``` From 9a6083c8d1744231c9a69eeb2f3a5a18b4e61356 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Mar 2020 17:23:02 +0100 Subject: [PATCH 1054/1786] Adds the bull badge next to the title --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ae38c626a..230f99f44 100644 --- a/README.md +++ b/README.md @@ -819,11 +819,9 @@ The application's logo has been designed by: Rob Light. All the instructions for releasing a new version are available at: [RELEASES.md](RELEASE.md) -## Badge your project +## Badge your project [![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) -[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) - -Add the following row in your Markdown file. +Add the following snippet in your Markdown file. ``` [![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) From 023915235551b2c71d2a05e58289026a7c99f62b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Mar 2020 17:24:14 +0100 Subject: [PATCH 1055/1786] Adds the bull badge next to the title --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 230f99f44..fd8cbe772 100644 --- a/README.md +++ b/README.md @@ -819,9 +819,11 @@ The application's logo has been designed by: Rob Light. All the instructions for releasing a new version are available at: [RELEASES.md](RELEASE.md) -## Badge your project [![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) +## Badge your project -Add the following snippet in your Markdown file. +[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) + +Add the following snippet in your Markdown file: ``` [![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) From 757f58cd438eead00842da622d519622d10d4117 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2020 02:32:21 +0000 Subject: [PATCH 1056/1786] Bump spring-boot-starter-test from 2.2.5.RELEASE to 2.2.6.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.2.5.RELEASE to 2.2.6.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.2.5.RELEASE...v2.2.6.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index af2ce4dad..cda2953d1 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 11 ${jdk.version} ${jdk.version} - 2.2.5.RELEASE + 2.2.6.RELEASE 1.18.12 3.9 0.11 From 84d859ab6da04de74a5e5b0b1f26c7777a1a2e17 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 27 Mar 2020 10:13:55 +0100 Subject: [PATCH 1057/1786] Updates the changelog --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index f4258f735..e6df5f3ab 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -10,7 +10,7 @@ All notable changes to this project will be documented in this file. * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). * Updated `mockito-core` version to `3.3.3` (was `3.2.4`). -* Updated `spring-boot-starter-test` version to `2.2.5.RELEASE` (was `2.2.4.RELEASE`). +* Updated `spring-boot-starter-test` version to `2.2.6.RELEASE` (was `2.2.4.RELEASE`). * Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). ### [1.6.4-jdk8] 2020.01.21 diff --git a/CHANGELOG.md b/CHANGELOG.md index 257a4ace7..cb7e73e2e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to this project will be documented in this file. * Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). * Updated `mockito-core` version to `3.3.3` (was `3.2.4`). -* Updated `spring-boot-starter-test` version to `2.2.5.RELEASE` (was `2.2.4.RELEASE`). +* Updated `spring-boot-starter-test` version to `2.2.6.RELEASE` (was `2.2.4.RELEASE`). * Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). ### [1.6.5] 2020.01.21 From 2f0bda197836eb3479337865a95b3a6c1c7860be Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 02:25:16 +0000 Subject: [PATCH 1058/1786] Bump commons-lang3 from 3.9 to 3.10 Bumps commons-lang3 from 3.9 to 3.10. Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cda2953d1..1838237ef 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ ${jdk.version} 2.2.6.RELEASE 1.18.12 - 3.9 + 3.10 0.11 2.8.6 7.1.0 From 768ce833ce466d10e06c840f7e53ed37c0d4ac58 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 30 Mar 2020 07:10:59 +0200 Subject: [PATCH 1059/1786] [travis skip] updates changelog --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index e6df5f3ab..11aecbfd0 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. * Updated `mockito-core` version to `3.3.3` (was `3.2.4`). * Updated `spring-boot-starter-test` version to `2.2.6.RELEASE` (was `2.2.4.RELEASE`). * Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). +* Updated `commons-lang3` version to `3.10` (was `3.9`). ### [1.6.4-jdk8] 2020.01.21 #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index cb7e73e2e..2e58f3bc9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. * Updated `mockito-core` version to `3.3.3` (was `3.2.4`). * Updated `spring-boot-starter-test` version to `2.2.6.RELEASE` (was `2.2.4.RELEASE`). * Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). +* Updated `commons-lang3` version to `3.10` (was `3.9`). ### [1.6.5] 2020.01.21 #### Changed From 776924890f096f37b016d46b0233c2693672447a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 3 Apr 2020 19:17:10 +0200 Subject: [PATCH 1060/1786] Squashed commit of the following: commit ea5614eea44cfa81515eae672348948d42db7c5e Author: Fabio Borriello Date: Fri Apr 3 19:15:39 2020 +0200 Changes the color for the javadoc and maven-centran badge --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fd8cbe772..2c9677109 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou ## Start using -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) -[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central&color=blue)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) +[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg?color=blue)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) [![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) From e490afc18cc47d8b3f115ffe13f6d3549b5223f8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 9 Apr 2020 11:48:22 +0200 Subject: [PATCH 1061/1786] Adds the support for all builders pattern --- .../beans/transformer/TransformerImpl.java | 15 ++++-- .../hotels/transformer/utils/ClassUtils.java | 46 +++++++++++++++++++ .../transformer/utils/ReflectionUtils.java | 2 +- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 6f219e6ab..f965f5658 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -57,22 +57,27 @@ public class TransformerImpl extends AbstractBeanTransformer { * {@inheritDoc} */ @Override + @SuppressWarnings("unchecked") protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final ClassType classType = classUtils.getClassType(targetClass); + final Object transformedClass; + final Optional> builderClass = classUtils.getBuilderClass(targetClass); + final Class realTargetClass = builderClass.orElse(targetClass); + final ClassType classType = classUtils.getClassType(realTargetClass); if (classType.is(MUTABLE)) { try { - k = classUtils.getNoArgsConstructor(targetClass).get(); - injectAllFields(sourceObj, k, breadcrumb); + transformedClass = classUtils.getNoArgsConstructor(realTargetClass).get(); + injectAllFields(sourceObj, transformedClass, breadcrumb); } catch (Exception e) { throw new InvalidBeanException(e.getMessage(), e); } } else { - k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb, false); + transformedClass = injectValues(sourceObj, realTargetClass, classUtils.getAllArgsConstructor(realTargetClass), breadcrumb, false); if (classType.is(MIXED)) { - injectNotFinalFields(sourceObj, k, breadcrumb); + injectNotFinalFields(sourceObj, transformedClass, breadcrumb); } } + k = builderClass.map(bc -> (K) reflectionUtils.invokeMethod(classUtils.getBuildMethod(bc), transformedClass)).orElseGet(() -> (K) transformedClass); if (settings.isValidationEnabled()) { validator.validate(k); } diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index eeee55322..18fb143d6 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -16,6 +16,7 @@ package com.hotels.transformer.utils; +import static java.lang.String.format; import static java.lang.invoke.LambdaMetafactory.metafactory; import static java.lang.invoke.MethodHandles.lookup; import static java.lang.invoke.MethodHandles.privateLookupIn; @@ -61,6 +62,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.function.Predicate; @@ -70,6 +72,7 @@ import com.hotels.transformer.constant.ClassType; import com.hotels.transformer.error.InstanceCreationException; import com.hotels.transformer.error.InvalidBeanException; +import com.hotels.transformer.error.MissingMethodException; /** * Reflection utils for Class objects. @@ -96,6 +99,11 @@ public final class ClassUtils { */ private static final MethodHandles.Lookup METHOD_HANDLES_LOOKUP = lookup(); + /** + * Default method name used by a Builder for creating an object. + */ + private static final String BUILD_METHOD_NAME = "build"; + /** * Reflection utils instance {@link ReflectionUtils}. */ @@ -464,6 +472,44 @@ public Class[] getDeclaredClasses(final Class clazz) { }); } + /** + * Returns the builder class. + * @param targetClass the class where the builder should be searched + * @return the Builder class if available. + */ + @SuppressWarnings("unchecked") + public Optional> getBuilderClass(final Class targetClass) { + String cacheKey = "BuilderClass-" + targetClass.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { + Optional res = stream(getDeclaredClasses(targetClass)) + .filter(nestedClass -> + stream(getDeclaredMethods(nestedClass)) + .anyMatch(method -> method.getName().equals(BUILD_METHOD_NAME) && method.getReturnType().equals(targetClass))) + .findAny(); + CACHE_MANAGER.cacheObject(cacheKey, res); + return res; + }); + } + + /** + * Get build method inside the class. + * @param builderClass Class whit a build method (see Builder Pattern) + * @return Build method if present + */ + public Method getBuildMethod(final Class builderClass) { + final String cacheKey = "BuildMethod-" + builderClass.getName(); + return CACHE_MANAGER.getFromCache(cacheKey, Method.class).orElseGet(() -> { + try { + Method method = builderClass.getMethod(BUILD_METHOD_NAME); + method.setAccessible(true); + CACHE_MANAGER.cacheObject(cacheKey, method); + return method; + } catch (NoSuchMethodException e) { + throw new MissingMethodException(format("Error while getting method %s in class %s.", BUILD_METHOD_NAME, builderClass.getName()) + e.getMessage()); + } + }); + } + /** * Creates an instance of the given class invoking the given constructor. * @param constructor the constructor to invoke. diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index 84ed8f4f3..15db1a4ea 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -97,7 +97,7 @@ public final class ReflectionUtils { * @param args the method parameters * @return the method result */ - protected Object invokeMethod(final Method method, final Object target, final Object... args) { + public Object invokeMethod(final Method method, final Object target, final Object... args) { try { return method.invoke(target, args); } catch (final Exception e) { From fd0159add2960dd0676e83dfeffa9956268513fa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 11 Apr 2020 19:17:40 +0200 Subject: [PATCH 1062/1786] Adds the UtilityClass annotation on the final classes with all static methods --- .../src/main/java/com/hotels/transformer/base/Defaults.java | 6 ++---- .../main/java/com/hotels/transformer/constant/Filters.java | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java index 6b50e4e86..ab237080c 100644 --- a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java +++ b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java @@ -27,14 +27,12 @@ import static com.hotels.transformer.utils.ClassUtils.isLong; import static com.hotels.transformer.utils.ClassUtils.isShort; -import static lombok.AccessLevel.PRIVATE; - -import lombok.NoArgsConstructor; +import lombok.experimental.UtilityClass; /** * Default values for primitive types. */ -@NoArgsConstructor(access = PRIVATE) +@UtilityClass public final class Defaults { /** * Gets the default value of a primitive type. diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java index 19bb3de4b..01c237ab9 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java @@ -19,17 +19,15 @@ import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isStatic; -import static lombok.AccessLevel.PRIVATE; - import java.lang.reflect.Field; import java.util.function.Predicate; -import lombok.NoArgsConstructor; +import lombok.experimental.UtilityClass; /** * Filters conditions. */ -@NoArgsConstructor(access = PRIVATE) +@UtilityClass public final class Filters { /** * Returns only the final not static field. From 1c08c95dbafacccbeb91d70fb3310d9a458e6c3a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 02:19:56 +0000 Subject: [PATCH 1063/1786] Bump hibernate-validator from 6.1.2.Final to 6.1.3.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.1.2.Final to 6.1.3.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.1.3.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.1.2.Final...6.1.3.Final) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1838237ef..9e936056e 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 1.3.0 2.0.1.Final - 6.1.2.Final + 6.1.3.Final 1.7.30 3.0.0 2.2.6 From c52d8bdca105c7bd515c6fa264d20d1022c3cd8b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 13 Apr 2020 07:41:36 +0200 Subject: [PATCH 1064/1786] Updates the changelog with the applied changes --- CHANGELOG-JDK8.md | 6 +++++- CHANGELOG.md | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 11aecbfd0..95cd8c48f 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,11 @@ All notable changes to this project will be documented in this file. -### [1.6.5-jdk8] TBD +### [1.6.6-jdk8] TBD +#### Changed +* Updated `hibernate-validator` version to `6.1.3.Final` (was `6.1.2.Final`). + +### [1.6.5-jdk8] 2020.03.16 ### Added * Added `maven-spotless-plugin` for the code automatic formatting during the maven build * Added `coveralls-maven-plugin` for the test coverage analysis and report during the maven build: [Coverall report](https://coveralls.io/github/HotelsDotCom/bull) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e58f3bc9..222e2772e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.6.7] TBD +#### Changed +* Updated `hibernate-validator` version to `6.1.3.Final` (was `6.1.2.Final`). + ### [1.6.6] 2020.03.16 ### Added * Added `maven-spotless-plugin` for the code automatic formatting during the maven build From 16fbc4eb8de35d4771836e66ab162258562b5f0b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 13 Apr 2020 15:10:42 +0200 Subject: [PATCH 1065/1786] Adds a support section in the readme file --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 2c9677109..3a78d3725 100644 --- a/README.md +++ b/README.md @@ -829,6 +829,11 @@ Add the following snippet in your Markdown file: [![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) ``` +## Support + +[![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) + +For any question, proposal or help, please refer to the slack channel: [#bull](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk). ## Legal From fb9c2bb441a9a3066e5261c331f0bb7a0e01a4f8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 13 Apr 2020 16:08:10 +0200 Subject: [PATCH 1066/1786] Introduces a BiPredicate for the Builder finding. --- .../hotels/transformer/constant/Filters.java | 10 +++ .../hotels/transformer/utils/ClassUtils.java | 24 ++++---- .../mutable/MutableToFooWithBuilder.java | 19 +++--- .../transformer/utils/ClassUtilsTest.java | 61 +++++++++++++++++++ 4 files changed, 94 insertions(+), 20 deletions(-) diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java index 19bb3de4b..b1efc087c 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java @@ -19,9 +19,13 @@ import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isStatic; +import static com.hotels.transformer.utils.ClassUtils.BUILD_METHOD_NAME; + import static lombok.AccessLevel.PRIVATE; import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.function.BiPredicate; import java.util.function.Predicate; import lombok.NoArgsConstructor; @@ -47,6 +51,12 @@ public final class Filters { return !isFinal(modifiers) && !isStatic(modifiers); }; + /** + * Returns true if the method is the Builder "build" one and it returns the given class. + */ + public static final BiPredicate IS_BUILDER_CLASS = + (method, targetClass) -> method.getName().equals(BUILD_METHOD_NAME) && method.getReturnType().equals(targetClass); + /** * Returns only the final field. */ diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 18fb143d6..2bbfe110a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -16,7 +16,6 @@ package com.hotels.transformer.utils; -import static java.lang.String.format; import static java.lang.invoke.LambdaMetafactory.metafactory; import static java.lang.invoke.MethodHandles.lookup; import static java.lang.invoke.MethodHandles.privateLookupIn; @@ -40,6 +39,7 @@ import static com.hotels.transformer.constant.ClassType.IMMUTABLE; import static com.hotels.transformer.constant.ClassType.MIXED; import static com.hotels.transformer.constant.ClassType.MUTABLE; +import static com.hotels.transformer.constant.Filters.IS_BUILDER_CLASS; import static com.hotels.transformer.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_FIELD; @@ -78,6 +78,11 @@ * Reflection utils for Class objects. */ public final class ClassUtils { + /** + * Default method name used by a Builder for creating an object. + */ + public static final String BUILD_METHOD_NAME = "build"; + /** * Class nullability error message constant. */ @@ -99,11 +104,6 @@ public final class ClassUtils { */ private static final MethodHandles.Lookup METHOD_HANDLES_LOOKUP = lookup(); - /** - * Default method name used by a Builder for creating an object. - */ - private static final String BUILD_METHOD_NAME = "build"; - /** * Reflection utils instance {@link ReflectionUtils}. */ @@ -484,7 +484,7 @@ public Optional> getBuilderClass(final Class targetClass) { Optional res = stream(getDeclaredClasses(targetClass)) .filter(nestedClass -> stream(getDeclaredMethods(nestedClass)) - .anyMatch(method -> method.getName().equals(BUILD_METHOD_NAME) && method.getReturnType().equals(targetClass))) + .anyMatch(method -> IS_BUILDER_CLASS.test(method, targetClass))) .findAny(); CACHE_MANAGER.cacheObject(cacheKey, res); return res; @@ -492,20 +492,20 @@ public Optional> getBuilderClass(final Class targetClass) { } /** - * Get build method inside the class. - * @param builderClass Class whit a build method (see Builder Pattern) - * @return Build method if present + * Get build method inside the Builder class. + * @param builderClass the builder class (see Builder Pattern) + * @return Builder build method if present */ public Method getBuildMethod(final Class builderClass) { final String cacheKey = "BuildMethod-" + builderClass.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { - Method method = builderClass.getMethod(BUILD_METHOD_NAME); + Method method = builderClass.getDeclaredMethod(BUILD_METHOD_NAME); method.setAccessible(true); CACHE_MANAGER.cacheObject(cacheKey, method); return method; } catch (NoSuchMethodException e) { - throw new MissingMethodException(format("Error while getting method %s in class %s.", BUILD_METHOD_NAME, builderClass.getName()) + e.getMessage()); + throw new MissingMethodException("Error while getting Builder method: " + BUILD_METHOD_NAME + " for class: " + builderClass.getName() + "."); } }); } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java index f0a68d42b..e553729d0 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java @@ -34,7 +34,16 @@ public final class MutableToFooWithBuilder { private List nestedObjectList; private MutableToSubFoo nestedObject; - private MutableToFooWithBuilder() { + /** + * Private constructor. + * @param builder the builder class + */ + private MutableToFooWithBuilder(final Builder builder) { + this.id = builder.id; + this.name = builder.name; + this.list = builder.list; + this.nestedObjectList = builder.nestedObjectList; + this.nestedObject = builder.nestedObject; } /** @@ -58,13 +67,7 @@ public Builder withId(final BigInteger id) { } public MutableToFooWithBuilder build() { - MutableToFooWithBuilder mutableToFooWithBuilder = new MutableToFooWithBuilder(); - mutableToFooWithBuilder.id = this.id; - mutableToFooWithBuilder.name = this.name; - mutableToFooWithBuilder.list = this.list; - mutableToFooWithBuilder.nestedObjectList = this.nestedObjectList; - mutableToFooWithBuilder.nestedObject = this.nestedObject; - return mutableToFooWithBuilder; + return new MutableToFooWithBuilder(this); } } } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 70d8fbde2..01f70df14 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -27,6 +27,8 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; +import static com.hotels.transformer.utils.ClassUtils.BUILD_METHOD_NAME; + import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -40,6 +42,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.Properties; import java.util.function.Predicate; import java.util.function.Supplier; @@ -72,6 +75,7 @@ import com.hotels.transformer.constant.ClassType; import com.hotels.transformer.error.InstanceCreationException; import com.hotels.transformer.error.InvalidBeanException; +import com.hotels.transformer.error.MissingMethodException; /** * Unit test for {@link ClassUtils}. @@ -987,6 +991,7 @@ public void testGetConcreteClassWorksAsExpected(final String testCaseDescription /** * Creates the parameters to be used for testing the method {@code getConcreteClass}. * @return parameters to be used for testing the the method {@code getConcreteClass}. + * @throws Exception if something goes wrong */ @DataProvider private Object[][] dataGetConcreteClassTesting() throws Exception { @@ -997,6 +1002,62 @@ private Object[][] dataGetConcreteClassTesting() throws Exception { }; } + /** + * Test that the a {@link MissingMethodException} is raised if the Builder class has no {@code build()} method. + */ + @Test(expectedExceptions = MissingMethodException.class) + public void testGetBuildMethodThrowsExceptionIfMethodIsMissing() { + // GIVEN + + // WHEN + underTest.getBuildMethod(ImmutableToFoo.class); + } + + /** + * Test that the {@link ClassUtils#getBuildMethod(Class) getBuildMethod} returns the Builder build method. + */ + @Test + public void testGetBuildMethodReturnsTheBuildMethod() { + // GIVEN + + // WHEN + Method actual = underTest.getBuildMethod(MutableToFooWithBuilder.Builder.class); + + // THEN + assertNotNull(actual); + assertEquals(BUILD_METHOD_NAME, actual.getName()); + } + + /** + * Tests that the method {@link ClassUtils#getBuilderClass(Class) getBuilderClass} returns the expected value. + * @param testCaseDescription the test case description + * @param testClass the class for which the builder class has to be retrieved + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataGetBuilderClassTesting") + public void testGetConcreteClassWorksAsExpected(final String testCaseDescription, final Class testClass, final Optional> expectedResult) { + // GIVEN + + // WHEN + Optional> actual = underTest.getBuilderClass(testClass); + + // THEN + assertEquals(expectedResult.isPresent(), actual.isPresent()); + expectedResult.ifPresent(clazz -> assertEquals(clazz, actual.get())); + } + + /** + * Creates the parameters to be used for testing the method {@code getBuilderClass}. + * @return parameters to be used for testing the the method {@code getBuilderClass}. + */ + @DataProvider + private Object[][] dataGetBuilderClassTesting() { + return new Object[][] { + {"Tests that the method returns the builder class", MutableToFooWithBuilder.class, Optional.of(MutableToFooWithBuilder.Builder.class)}, + {"Tests that the method returns an empty optional if the class has no builder", ImmutableToFoo.class, Optional.empty()} + }; + } + private Field getField(final T objectInstance, final String fieldName) throws NoSuchFieldException { Field field = objectInstance.getClass().getDeclaredField(fieldName); field.setAccessible(true); From 91bd2593892a1c43d94a888691312e6276a8a99a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 14 Apr 2020 08:36:05 +0200 Subject: [PATCH 1067/1786] Simplifies the Builder build method retrieval --- .../beans/transformer/TransformerImpl.java | 7 ++++--- .../hotels/transformer/constant/Filters.java | 10 --------- .../hotels/transformer/utils/ClassUtils.java | 21 +++++++++++++------ .../transformer/utils/ClassUtilsTest.java | 18 +++++++++++++--- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index f965f5658..a2ef63539 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -61,8 +61,8 @@ public class TransformerImpl extends AbstractBeanTransformer { protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; final Object transformedClass; - final Optional> builderClass = classUtils.getBuilderClass(targetClass); - final Class realTargetClass = builderClass.orElse(targetClass); + final Optional> builderClassOpt = classUtils.getBuilderClass(targetClass); + final Class realTargetClass = builderClassOpt.orElse(targetClass); final ClassType classType = classUtils.getClassType(realTargetClass); if (classType.is(MUTABLE)) { try { @@ -77,7 +77,8 @@ protected final K transform(final T sourceObj, final Class t injectNotFinalFields(sourceObj, transformedClass, breadcrumb); } } - k = builderClass.map(bc -> (K) reflectionUtils.invokeMethod(classUtils.getBuildMethod(bc), transformedClass)).orElseGet(() -> (K) transformedClass); + k = builderClassOpt.map(builderClass -> + (K) reflectionUtils.invokeMethod(classUtils.getBuildMethod(targetClass, builderClass), transformedClass)).orElseGet(() -> (K) transformedClass); if (settings.isValidationEnabled()) { validator.validate(k); } diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java index b1efc087c..19bb3de4b 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java @@ -19,13 +19,9 @@ import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isStatic; -import static com.hotels.transformer.utils.ClassUtils.BUILD_METHOD_NAME; - import static lombok.AccessLevel.PRIVATE; import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.function.BiPredicate; import java.util.function.Predicate; import lombok.NoArgsConstructor; @@ -51,12 +47,6 @@ public final class Filters { return !isFinal(modifiers) && !isStatic(modifiers); }; - /** - * Returns true if the method is the Builder "build" one and it returns the given class. - */ - public static final BiPredicate IS_BUILDER_CLASS = - (method, targetClass) -> method.getName().equals(BUILD_METHOD_NAME) && method.getReturnType().equals(targetClass); - /** * Returns only the final field. */ diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 2bbfe110a..8766efc17 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -39,7 +39,6 @@ import static com.hotels.transformer.constant.ClassType.IMMUTABLE; import static com.hotels.transformer.constant.ClassType.MIXED; import static com.hotels.transformer.constant.ClassType.MUTABLE; -import static com.hotels.transformer.constant.Filters.IS_BUILDER_CLASS; import static com.hotels.transformer.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_FIELD; @@ -482,9 +481,15 @@ public Optional> getBuilderClass(final Class targetClass) { String cacheKey = "BuilderClass-" + targetClass.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional res = stream(getDeclaredClasses(targetClass)) - .filter(nestedClass -> - stream(getDeclaredMethods(nestedClass)) - .anyMatch(method -> IS_BUILDER_CLASS.test(method, targetClass))) + .filter(nestedClass -> { + boolean hasBuildMethod = true; + try { + getBuildMethod(targetClass, nestedClass); + } catch (MissingMethodException e) { + hasBuildMethod = false; + } + return hasBuildMethod; + }) .findAny(); CACHE_MANAGER.cacheObject(cacheKey, res); return res; @@ -493,19 +498,23 @@ public Optional> getBuilderClass(final Class targetClass) { /** * Get build method inside the Builder class. + * @param parentClass the class containing the builder * @param builderClass the builder class (see Builder Pattern) * @return Builder build method if present */ - public Method getBuildMethod(final Class builderClass) { + public Method getBuildMethod(final Class parentClass, final Class builderClass) { final String cacheKey = "BuildMethod-" + builderClass.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { Method method = builderClass.getDeclaredMethod(BUILD_METHOD_NAME); + if (!method.getReturnType().equals(parentClass)) { + throw new MissingMethodException("Invalid " + BUILD_METHOD_NAME + " method definition. It must returns a: " + parentClass.getCanonicalName()); + } method.setAccessible(true); CACHE_MANAGER.cacheObject(cacheKey, method); return method; } catch (NoSuchMethodException e) { - throw new MissingMethodException("Error while getting Builder method: " + BUILD_METHOD_NAME + " for class: " + builderClass.getName() + "."); + throw new MissingMethodException("No Builder " + BUILD_METHOD_NAME + " method defined for class: " + builderClass.getName() + "."); } }); } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 01f70df14..c07dfdcb8 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -1010,18 +1010,18 @@ public void testGetBuildMethodThrowsExceptionIfMethodIsMissing() { // GIVEN // WHEN - underTest.getBuildMethod(ImmutableToFoo.class); + underTest.getBuildMethod(ImmutableToFoo.class, ImmutableToFoo.class); } /** - * Test that the {@link ClassUtils#getBuildMethod(Class) getBuildMethod} returns the Builder build method. + * Test that the {@link ClassUtils#getBuildMethod(Class, Class) getBuildMethod} returns the Builder build method. */ @Test public void testGetBuildMethodReturnsTheBuildMethod() { // GIVEN // WHEN - Method actual = underTest.getBuildMethod(MutableToFooWithBuilder.Builder.class); + Method actual = underTest.getBuildMethod(MutableToFooWithBuilder.class, MutableToFooWithBuilder.Builder.class); // THEN assertNotNull(actual); @@ -1058,12 +1058,24 @@ private Object[][] dataGetBuilderClassTesting() { }; } + /** + * Returns the class field with the given name. + * @param objectInstance the class containing the field + * @param fieldName the name of the field to retrieve + * @param the object instance type + * @return the class field with the given name + * @throws NoSuchFieldException if the field is missing + */ private Field getField(final T objectInstance, final String fieldName) throws NoSuchFieldException { Field field = objectInstance.getClass().getDeclaredField(fieldName); field.setAccessible(true); return field; } + /** + * Creates a {@link FromFoo}. + * @return a {@link FromFoo} instance + */ private FromFoo createFromFoo() { return new FromFoo(NAME, null, null, LINKED_LIST, null); } From 8fc1c60fb612b903044302fb4a0ba6e766c746a1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 14 Apr 2020 08:40:46 +0200 Subject: [PATCH 1068/1786] Updates changelog and increase the major version --- CHANGELOG-JDK8.md | 4 +++- CHANGELOG.md | 5 ++++- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 95cd8c48f..59dec2f13 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,9 @@ All notable changes to this project will be documented in this file. -### [1.6.6-jdk8] TBD +### [1.7.0-jdk8] TBD +#### Added +* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). #### Changed * Updated `hibernate-validator` version to `6.1.3.Final` (was `6.1.2.Final`). diff --git a/CHANGELOG.md b/CHANGELOG.md index 222e2772e..22e537e00 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,10 @@ All notable changes to this project will be documented in this file. -### [1.6.7] TBD +### [1.7.0] TBD +#### Added +* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). + #### Changed * Updated `hibernate-validator` version to `6.1.3.Final` (was `6.1.2.Final`). diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 9ea394df6..784f18a23 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.7-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 36574e312..c952e08f3 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.7-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 6824c0fce..237ffec83 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.6.7-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 810e8469c..9c820716c 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.7-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index aa7a1307f..0a85250f8 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.6.7-SNAPSHOT + 1.7.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 9e936056e..5c6309ff0 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.6.7-SNAPSHOT + 1.7.0-SNAPSHOT pom 2019 From b3fa5978c25af4379cc998c03f05f53beb47c367 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 14 Apr 2020 10:17:52 +0200 Subject: [PATCH 1069/1786] Adds test cases that verify that everything works as expected in case the builder is not valid --- .../mutable/MutableToFooWithWrongBuilder.java | 73 +++++++++++++++++++ .../transformer/utils/ClassUtilsTest.java | 26 ++++++- 2 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java new file mode 100644 index 000000000..8a9697b86 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2019-2020 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hotels.beans.sample.mutable; + +import java.math.BigInteger; +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +/** + * Mutable object instantiable only through a wrong Builder. + */ +@Getter +@Setter +public final class MutableToFooWithWrongBuilder { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + /** + * Private constructor. + * @param builder the builder class + */ + private MutableToFooWithWrongBuilder(final Builder builder) { + this.id = builder.id; + this.name = builder.name; + this.list = builder.list; + this.nestedObjectList = builder.nestedObjectList; + this.nestedObject = builder.nestedObject; + } + + /** + * Builder class. + */ + public static class Builder { + private String name; + private BigInteger id; + private List list; + private List nestedObjectList; + private MutableToSubFoo nestedObject; + + public Builder withName(final String name) { + this.name = name; + return this; + } + + public Builder withId(final BigInteger id) { + this.id = id; + return this; + } + + public Builder build() { + return this; + } + } +} diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index c07dfdcb8..cc9282a92 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -71,6 +71,7 @@ import com.hotels.beans.sample.mutable.MutableToFoo; import com.hotels.beans.sample.mutable.MutableToFooSubClass; import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; +import com.hotels.beans.sample.mutable.MutableToFooWithWrongBuilder; import com.hotels.transformer.annotation.ConstructorArg; import com.hotels.transformer.constant.ClassType; import com.hotels.transformer.error.InstanceCreationException; @@ -1004,13 +1005,29 @@ private Object[][] dataGetConcreteClassTesting() throws Exception { /** * Test that the a {@link MissingMethodException} is raised if the Builder class has no {@code build()} method. + * @param testCaseDescription the test case description + * @param containerTestClass the test class containing the Builder + * @param builderClass the Builder nested class */ - @Test(expectedExceptions = MissingMethodException.class) - public void testGetBuildMethodThrowsExceptionIfMethodIsMissing() { + @Test(dataProvider = "dataGetBuilderMethodExceptionTesting", expectedExceptions = MissingMethodException.class) + public void testGetBuildMethodThrowsExceptionIfMethodIsMissing(final String testCaseDescription, final Class containerTestClass, final Class builderClass) { // GIVEN // WHEN - underTest.getBuildMethod(ImmutableToFoo.class, ImmutableToFoo.class); + underTest.getBuildMethod(containerTestClass, builderClass); + } + + /** + * Creates the parameters to be used for testing the method {@code getBuildMethod}. + * @return parameters to be used for testing the the method {@code getBuildMethod}. + */ + @DataProvider + private Object[][] dataGetBuilderMethodExceptionTesting() { + return new Object[][] { + {"Tests that the method raises a MissingMethodException if the class has no builder build method", ImmutableToFoo.class, ImmutableToFoo.class}, + {"Tests that the method raises a MissingMethodException if the class has a builder build method that does not return the parent class", + MutableToFooWithWrongBuilder.class, MutableToFooWithWrongBuilder.Builder.class} + }; } /** @@ -1054,7 +1071,8 @@ public void testGetConcreteClassWorksAsExpected(final String testCaseDescription private Object[][] dataGetBuilderClassTesting() { return new Object[][] { {"Tests that the method returns the builder class", MutableToFooWithBuilder.class, Optional.of(MutableToFooWithBuilder.Builder.class)}, - {"Tests that the method returns an empty optional if the class has no builder", ImmutableToFoo.class, Optional.empty()} + {"Tests that the method returns an empty optional if the class has no builder", ImmutableToFoo.class, Optional.empty()}, + {"Tests that the method returns an empty optional if the class has a wrong builder", MutableToFooWithWrongBuilder.class, Optional.empty()} }; } From 79c7277f7944e2679cf4af87148d5250c7bd04fb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 14 Apr 2020 18:21:42 +0200 Subject: [PATCH 1070/1786] Minor: adds unchecked suppression --- .../src/main/java/com/hotels/transformer/utils/ClassUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 8766efc17..51e601321 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -567,6 +567,7 @@ public Supplier getNoArgsConstructor(final Class clazz) { * @param the object type * @return the all args constructor */ + @SuppressWarnings("unchecked") public Constructor getAllArgsConstructor(final Class clazz) { final String cacheKey = "AllArgsConstructor-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { From 33fb8ba59db706f27182333746368e63b0dc9094 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 15 Apr 2020 09:46:45 +0200 Subject: [PATCH 1071/1786] Minor: variable name refactoring --- .../beans/transformer/TransformerImpl.java | 18 +++++++++--------- bull-common/pom.xml | 8 ++++++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index a2ef63539..6ea670581 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -60,25 +60,25 @@ public class TransformerImpl extends AbstractBeanTransformer { @SuppressWarnings("unchecked") protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final Object transformedClass; - final Optional> builderClassOpt = classUtils.getBuilderClass(targetClass); - final Class realTargetClass = builderClassOpt.orElse(targetClass); + final Object transformedBean; + final Optional> nestedBuilderClass = classUtils.getBuilderClass(targetClass); + final Class realTargetClass = nestedBuilderClass.orElse(targetClass); final ClassType classType = classUtils.getClassType(realTargetClass); if (classType.is(MUTABLE)) { try { - transformedClass = classUtils.getNoArgsConstructor(realTargetClass).get(); - injectAllFields(sourceObj, transformedClass, breadcrumb); + transformedBean = classUtils.getNoArgsConstructor(realTargetClass).get(); + injectAllFields(sourceObj, transformedBean, breadcrumb); } catch (Exception e) { throw new InvalidBeanException(e.getMessage(), e); } } else { - transformedClass = injectValues(sourceObj, realTargetClass, classUtils.getAllArgsConstructor(realTargetClass), breadcrumb, false); + transformedBean = injectValues(sourceObj, realTargetClass, classUtils.getAllArgsConstructor(realTargetClass), breadcrumb, false); if (classType.is(MIXED)) { - injectNotFinalFields(sourceObj, transformedClass, breadcrumb); + injectNotFinalFields(sourceObj, transformedBean, breadcrumb); } } - k = builderClassOpt.map(builderClass -> - (K) reflectionUtils.invokeMethod(classUtils.getBuildMethod(targetClass, builderClass), transformedClass)).orElseGet(() -> (K) transformedClass); + k = nestedBuilderClass.map(builderClass -> + (K) reflectionUtils.invokeMethod(classUtils.getBuildMethod(targetClass, builderClass), transformedBean)).orElseGet(() -> (K) transformedBean); if (settings.isValidationEnabled()) { validator.validate(k); } diff --git a/bull-common/pom.xml b/bull-common/pom.xml index c952e08f3..a77fc42a4 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -48,6 +48,14 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + \ No newline at end of file From a66fd0ea4ba9b8e0648e5a2cea25500d7eb3ee8f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 15 Apr 2020 09:47:57 +0200 Subject: [PATCH 1072/1786] Removes useless plugin --- bull-common/pom.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/bull-common/pom.xml b/bull-common/pom.xml index a77fc42a4..c952e08f3 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -48,14 +48,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - 9 - 9 - - \ No newline at end of file From 1428452c7374cdf08341617a15dd365c172ea13b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 15 Apr 2020 18:21:18 +0200 Subject: [PATCH 1073/1786] Refactors the transformer method to improve the readibility --- .../beans/transformer/TransformerImpl.java | 65 ++++++++++++++----- .../hotels/transformer/utils/ClassUtils.java | 10 ++- .../transformer/utils/ClassUtilsTest.java | 14 ++-- 3 files changed, 57 insertions(+), 32 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 6ea670581..914cbeb2a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -57,34 +57,35 @@ public class TransformerImpl extends AbstractBeanTransformer { * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final Object transformedBean; - final Optional> nestedBuilderClass = classUtils.getBuilderClass(targetClass); - final Class realTargetClass = nestedBuilderClass.orElse(targetClass); - final ClassType classType = classUtils.getClassType(realTargetClass); - if (classType.is(MUTABLE)) { - try { - transformedBean = classUtils.getNoArgsConstructor(realTargetClass).get(); - injectAllFields(sourceObj, transformedBean, breadcrumb); - } catch (Exception e) { - throw new InvalidBeanException(e.getMessage(), e); - } + final Class builderClass = classUtils.getBuilderClass(targetClass); + if (nonNull(builderClass)) { + k = injectThroughBuilder(sourceObj, targetClass, builderClass, breadcrumb); } else { - transformedBean = injectValues(sourceObj, realTargetClass, classUtils.getAllArgsConstructor(realTargetClass), breadcrumb, false); - if (classType.is(MIXED)) { - injectNotFinalFields(sourceObj, transformedBean, breadcrumb); - } + k = injectValues(sourceObj, targetClass, breadcrumb); } - k = nestedBuilderClass.map(builderClass -> - (K) reflectionUtils.invokeMethod(classUtils.getBuildMethod(targetClass, builderClass), transformedBean)).orElseGet(() -> (K) transformedBean); if (settings.isValidationEnabled()) { validator.validate(k); } return k; } + /** + * Inject all properties value from an object to a new one using the class builder. + * @param sourceObj the source object + * @param targetClass the destination object class + * @param builderClass the builder class inside the Bean + * @param breadcrumb the full path of the current field starting from his ancestor + * @param the Source object type + * @param the target object type + * @return a copy of the source object into the destination object + */ + @SuppressWarnings("unchecked") + private K injectThroughBuilder(final T sourceObj, final Class targetClass, final Class builderClass, final String breadcrumb) { + return (K) reflectionUtils.invokeMethod(classUtils.getBuildMethod(targetClass, builderClass), injectValues(sourceObj, builderClass, breadcrumb)); + } + /** * {@inheritDoc} */ @@ -96,6 +97,34 @@ protected final void transform(final T sourceObj, final K targetObject, f } } + /** + * Inject all properties value from an object to a new one. + * @param sourceObj the source object + * @param targetClass the destination object class + * @param breadcrumb the full path of the current field starting from his ancestor + * @param the Source object type + * @param the target object type + * @return a copy of the source object into the destination object + */ + private K injectValues(final T sourceObj, final Class targetClass, final String breadcrumb) { + final K k; + final ClassType classType = classUtils.getClassType(targetClass); + if (classType.is(MUTABLE)) { + try { + k = classUtils.getNoArgsConstructor(targetClass).get(); + injectAllFields(sourceObj, k, breadcrumb); + } catch (Exception e) { + throw new InvalidBeanException(e.getMessage(), e); + } + } else { + k = injectValues(sourceObj, targetClass, classUtils.getAllArgsConstructor(targetClass), breadcrumb, false); + if (classType.is(MIXED)) { + injectNotFinalFields(sourceObj, k, breadcrumb); + } + } + return k; + } + /** * Inject the values through the all args constructor. * @param sourceObj sourceObj the source object diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 51e601321..c610067f4 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -61,7 +61,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.function.Predicate; @@ -476,11 +475,10 @@ public Class[] getDeclaredClasses(final Class clazz) { * @param targetClass the class where the builder should be searched * @return the Builder class if available. */ - @SuppressWarnings("unchecked") - public Optional> getBuilderClass(final Class targetClass) { + public Class getBuilderClass(final Class targetClass) { String cacheKey = "BuilderClass-" + targetClass.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { - Optional res = stream(getDeclaredClasses(targetClass)) + return CACHE_MANAGER.getFromCache(cacheKey, Class.class).orElseGet(() -> { + Class res = stream(getDeclaredClasses(targetClass)) .filter(nestedClass -> { boolean hasBuildMethod = true; try { @@ -490,7 +488,7 @@ public Optional> getBuilderClass(final Class targetClass) { } return hasBuildMethod; }) - .findAny(); + .findAny().orElse(null); CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index cc9282a92..1090baf08 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -42,7 +42,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Optional; import java.util.Properties; import java.util.function.Predicate; import java.util.function.Supplier; @@ -1052,15 +1051,14 @@ public void testGetBuildMethodReturnsTheBuildMethod() { * @param expectedResult the expected result */ @Test(dataProvider = "dataGetBuilderClassTesting") - public void testGetConcreteClassWorksAsExpected(final String testCaseDescription, final Class testClass, final Optional> expectedResult) { + public void testGetConcreteClassWorksAsExpected(final String testCaseDescription, final Class testClass, final Class expectedResult) { // GIVEN // WHEN - Optional> actual = underTest.getBuilderClass(testClass); + Class actual = underTest.getBuilderClass(testClass); // THEN - assertEquals(expectedResult.isPresent(), actual.isPresent()); - expectedResult.ifPresent(clazz -> assertEquals(clazz, actual.get())); + assertEquals(expectedResult, actual); } /** @@ -1070,9 +1068,9 @@ public void testGetConcreteClassWorksAsExpected(final String testCaseDescription @DataProvider private Object[][] dataGetBuilderClassTesting() { return new Object[][] { - {"Tests that the method returns the builder class", MutableToFooWithBuilder.class, Optional.of(MutableToFooWithBuilder.Builder.class)}, - {"Tests that the method returns an empty optional if the class has no builder", ImmutableToFoo.class, Optional.empty()}, - {"Tests that the method returns an empty optional if the class has a wrong builder", MutableToFooWithWrongBuilder.class, Optional.empty()} + {"Tests that the method returns the builder class", MutableToFooWithBuilder.class, MutableToFooWithBuilder.Builder.class}, + {"Tests that the method returns an empty optional if the class has no builder", ImmutableToFoo.class, null}, + {"Tests that the method returns an empty optional if the class has a wrong builder", MutableToFooWithWrongBuilder.class, null} }; } From 2be167b8ae204683a5cc382c0ed59227dc889a7e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 19 Apr 2020 08:02:27 +0200 Subject: [PATCH 1074/1786] Modifies the getBuilderClass method to return an optional --- .../hotels/beans/transformer/TransformerImpl.java | 6 +++--- .../com/hotels/transformer/utils/ClassUtils.java | 9 +++++---- .../hotels/transformer/utils/ClassUtilsTest.java | 14 ++++++++------ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 914cbeb2a..af90718da 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -59,9 +59,9 @@ public class TransformerImpl extends AbstractBeanTransformer { @Override protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final Class builderClass = classUtils.getBuilderClass(targetClass); - if (nonNull(builderClass)) { - k = injectThroughBuilder(sourceObj, targetClass, builderClass, breadcrumb); + final Optional> builderClass = classUtils.getBuilderClass(targetClass); + if (builderClass.isPresent()) { + k = injectThroughBuilder(sourceObj, targetClass, builderClass.get(), breadcrumb); } else { k = injectValues(sourceObj, targetClass, breadcrumb); } diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index c610067f4..26f8d8262 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -61,6 +61,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.function.Predicate; @@ -475,10 +476,10 @@ public Class[] getDeclaredClasses(final Class clazz) { * @param targetClass the class where the builder should be searched * @return the Builder class if available. */ - public Class getBuilderClass(final Class targetClass) { + public Optional> getBuilderClass(final Class targetClass) { String cacheKey = "BuilderClass-" + targetClass.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, Class.class).orElseGet(() -> { - Class res = stream(getDeclaredClasses(targetClass)) + return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { + Optional res = stream(getDeclaredClasses(targetClass)) .filter(nestedClass -> { boolean hasBuildMethod = true; try { @@ -488,7 +489,7 @@ public Class getBuilderClass(final Class targetClass) { } return hasBuildMethod; }) - .findAny().orElse(null); + .findAny(); CACHE_MANAGER.cacheObject(cacheKey, res); return res; }); diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 1090baf08..1c70335f0 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -42,6 +42,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.Properties; import java.util.function.Predicate; import java.util.function.Supplier; @@ -1051,14 +1052,15 @@ public void testGetBuildMethodReturnsTheBuildMethod() { * @param expectedResult the expected result */ @Test(dataProvider = "dataGetBuilderClassTesting") - public void testGetConcreteClassWorksAsExpected(final String testCaseDescription, final Class testClass, final Class expectedResult) { + public void testGetConcreteClassWorksAsExpected(final String testCaseDescription, final Class testClass, final Optional> expectedResult) { // GIVEN // WHEN - Class actual = underTest.getBuilderClass(testClass); + Optional> actual = underTest.getBuilderClass(testClass); // THEN - assertEquals(expectedResult, actual); + assertEquals(expectedResult.isPresent(), actual.isPresent()); + expectedResult.ifPresent(clazz -> assertEquals(clazz, actual.get())); } /** @@ -1068,9 +1070,9 @@ public void testGetConcreteClassWorksAsExpected(final String testCaseDescription @DataProvider private Object[][] dataGetBuilderClassTesting() { return new Object[][] { - {"Tests that the method returns the builder class", MutableToFooWithBuilder.class, MutableToFooWithBuilder.Builder.class}, - {"Tests that the method returns an empty optional if the class has no builder", ImmutableToFoo.class, null}, - {"Tests that the method returns an empty optional if the class has a wrong builder", MutableToFooWithWrongBuilder.class, null} + {"Tests that the method returns the builder class", MutableToFooWithBuilder.class, Optional.of(MutableToFooWithBuilder.Builder.class)}, + {"Tests that the method returns an empty optional if the class has no builder", ImmutableToFoo.class, Optional.empty()}, + {"Tests that the method returns an empty optional if the class has a wrong builder", MutableToFooWithWrongBuilder.class, Optional.empty()} }; } From 96af47eda5de5188e95b3acec03053cbb1aa69f4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 19 Apr 2020 08:19:07 +0200 Subject: [PATCH 1075/1786] Provides documentation for the supported builder patterns --- README.md | 3 +- .../site/markdown/transformer/bean/builder.md | 91 +++++++++++++++++++ docs/site/markdown/transformer/map/samples.md | 14 +-- 3 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 docs/site/markdown/transformer/bean/builder.md diff --git a/README.md b/README.md index 3a78d3725..ce90299a8 100644 --- a/README.md +++ b/README.md @@ -118,10 +118,11 @@ mvnw.cmd clean install -P relaxed # Feature samples -* [Bean Transformation](https://github.com/HotelsDotCom/bull#transformation-samples) +* [Bean Transformation](https://github.com/HotelsDotCom/bull#bean-transformation-samples) * [Bean Validation](https://github.com/HotelsDotCom/bull#validation-samples) * [Primitive Type conversion](https://github.com/HotelsDotCom/bull#primitive-type-object-converter) * [Map Transformation](https://hotelsdotcom.github.io/bull/transformer/map/samples.html) +* [Supported Builder Pattern](https://hotelsdotcom.github.io/bull/transformer/bean/builder.html) ## Bean transformation samples diff --git a/docs/site/markdown/transformer/bean/builder.md b/docs/site/markdown/transformer/bean/builder.md new file mode 100644 index 000000000..8cde679dd --- /dev/null +++ b/docs/site/markdown/transformer/bean/builder.md @@ -0,0 +1,91 @@ + + Builder + + +# Builder supported patterns + +The library support the transformation of Java Bean using the following Builder patterns: + +### Standard pattern: + +~~~Java +public class ItemType { + private final Class objectClass; + private final Class genericClass; + + ItemType(final Class objectClass, final Class genericClass) { + this.objectClass = objectClass; + this.genericClass = genericClass; + } + + public static ItemTypeBuilder builder() { + return new ItemType.ItemTypeBuilder(); + } + + // getter methods + + public static class ItemTypeBuilder { + private Class objectClass; + private Class genericClass; + + ItemTypeBuilder() { + } + + public ItemTypeBuilder objectClass(final Class objectClass) { + this.objectClass = objectClass; + return this; + } + + public ItemTypeBuilder genericClass(final Class genericClass) { + this.genericClass = genericClass; + return this; + } + + public com.hotels.transformer.model.ItemType build() { + return new ItemType(this.objectClass, this.genericClass); + } + } +} +~~~ + +### Custom Builder pattern: + +~~~Java +public class ItemType { + private final Class objectClass; + private final Class genericClass; + + ItemType(final ItemTypeBuilder builder) { + this.objectClass = builder.objectClass; + this.genericClass = builder.genericClass; + } + + public static ItemTypeBuilder builder() { + return new ItemType.ItemTypeBuilder(); + } + + // getter methods + + public static class ItemTypeBuilder { + private Class objectClass; + private Class genericClass; + + ItemTypeBuilder() { + } + + public ItemTypeBuilder objectClass(final Class objectClass) { + this.objectClass = objectClass; + return this; + } + + public ItemTypeBuilder genericClass(final Class genericClass) { + this.genericClass = genericClass; + return this; + } + + public com.hotels.transformer.model.ItemType build() { + return new ItemType(this); + } + } +} +~~~ \ No newline at end of file diff --git a/docs/site/markdown/transformer/map/samples.md b/docs/site/markdown/transformer/map/samples.md index 6726211c2..62b89e6a5 100644 --- a/docs/site/markdown/transformer/map/samples.md +++ b/docs/site/markdown/transformer/map/samples.md @@ -2,9 +2,9 @@ Samples -# `Map` Transformation samples +# Map Transformation samples -### `Map` clone: +### Map clone: Given a simple `Map` defined as follow: @@ -19,7 +19,7 @@ it can be cloned using the following command: Map> newMap = new MapUtils().getTransformer().transform(map); ~~~ -### Map a `Key` value into a different `Key` in the destination `Map`: +### Map a Key value into a different Key in the destination Map: Given a simple `Map` defined as follow: @@ -51,7 +51,7 @@ the output will be: Hello ~~~ -### Apply a transformation function on a `Map` key: +### Apply a transformation function on a Map key: Given a simple `Map` defined as follow: @@ -73,7 +73,7 @@ Map> newMap = new MapUtils().getTransformer() Then the key: "name" in the `newMap`will be: `NAME` -### Apply a transformation function on a `Map` value: +### Apply a transformation function on a Map value: Given a simple `Map` defined as follow: @@ -105,7 +105,7 @@ the output will be: 900 ~~~ -### Transform `Map` `key` or `value` object into a different object +### Transform Map key or value object into a different object Assuming that we have a map defined as follow: @@ -155,7 +155,7 @@ Map map = new MapUtils().getTransformer() .transform(sourceMap, ToBean.class, ToSubBean.class); ~~~ -### Configure a `BeanTransformer` and use it fo the `Map` transformation +### Configure a BeanTransformer and use it fo the Map transformation Assuming that we have two classes with different field names defined as follow: From 28b6137bcfce09c0635eb7573427fcdfd82f2aa1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 02:24:07 +0000 Subject: [PATCH 1076/1786] Bump hibernate-validator from 6.1.3.Final to 6.1.4.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.1.3.Final to 6.1.4.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.1.4.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.1.3.Final...6.1.4.Final) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9e936056e..07fc2f6f0 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 1.3.0 2.0.1.Final - 6.1.3.Final + 6.1.4.Final 1.7.30 3.0.0 2.2.6 From c91f4558f3730de8ec2dfff6893429e04b326801 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 Apr 2020 08:18:26 +0200 Subject: [PATCH 1077/1786] Adds a new setting that allows to enable/disable the custom builder pattern transformation --- README.md | 98 +++++++++++++++++++ .../transformer/AbstractBeanTransformer.java | 9 ++ .../beans/transformer/BeanTransformer.java | 7 ++ .../beans/transformer/TransformerImpl.java | 13 ++- .../BuilderObjectTransformationTest.java | 2 + .../model/TransformerSettings.java | 7 ++ .../site/markdown/transformer/bean/builder.md | 10 ++ 7 files changed, 145 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ce90299a8..46e79c36a 100644 --- a/README.md +++ b/README.md @@ -604,6 +604,104 @@ ToBean toBean = transformer.transform(fromBean, ToBean.class); **IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function defined on a specific field. This means that the once the `FieldTransformer` function will be executed the field value has already been transformed. +## Builder supported patterns + +The library support the transformation of Java Bean using the following Builder patterns: + +### Standard pattern: + +~~~Java +public class ItemType { + private final Class objectClass; + private final Class genericClass; + + ItemType(final Class objectClass, final Class genericClass) { + this.objectClass = objectClass; + this.genericClass = genericClass; + } + + public static ItemTypeBuilder builder() { + return new ItemType.ItemTypeBuilder(); + } + + // getter methods + + public static class ItemTypeBuilder { + private Class objectClass; + private Class genericClass; + + ItemTypeBuilder() { + } + + public ItemTypeBuilder objectClass(final Class objectClass) { + this.objectClass = objectClass; + return this; + } + + public ItemTypeBuilder genericClass(final Class genericClass) { + this.genericClass = genericClass; + return this; + } + + public com.hotels.transformer.model.ItemType build() { + return new ItemType(this.objectClass, this.genericClass); + } + } +} +~~~ + +### Custom Builder pattern: + +To enable the transformation of Java Beans using the following Builder pattern: + +~~~Java +public class ItemType { + private final Class objectClass; + private final Class genericClass; + + ItemType(final ItemTypeBuilder builder) { + this.objectClass = builder.objectClass; + this.genericClass = builder.genericClass; + } + + public static ItemTypeBuilder builder() { + return new ItemType.ItemTypeBuilder(); + } + + // getter methods + + public static class ItemTypeBuilder { + private Class objectClass; + private Class genericClass; + + ItemTypeBuilder() { + } + + public ItemTypeBuilder objectClass(final Class objectClass) { + this.objectClass = objectClass; + return this; + } + + public ItemTypeBuilder genericClass(final Class genericClass) { + this.genericClass = genericClass; + return this; + } + + public com.hotels.transformer.model.ItemType build() { + return new ItemType(this); + } + } +} +~~~ + +It's needed to enable the custom Builder Transformation as following: + +~~~Java +ToBean toBean = new BeanTransformer() + .setCustomBuilderTransformationEnabled(true) + .transform(sourceObject, ToBean.class); +~~~ + ## Constraints: * the class's fields that have to be copied must not be static diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java index 9d2a90304..027fa4d78 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java @@ -106,6 +106,15 @@ public BeanTransformer setPrimitiveTypeConversionEnabled(final boolean primitive return this; } + /** + * {@inheritDoc} + */ + @Override + public BeanTransformer setCustomBuilderTransformationEnabled(final boolean customBuilderTransformationEnabled) { + settings.setCustomBuilderTransformationEnabled(customBuilderTransformationEnabled); + return this; + } + /** * {@inheritDoc} */ diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index cee7999fa..0926ef835 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -94,4 +94,11 @@ public interface BeanTransformer extends Transformer { * @return the {@link BeanTransformer} instance */ BeanTransformer setPrimitiveTypeConversionEnabled(boolean primitiveTypeConversionEnabled); + + /** + * It allows to enable/disable the transformation of Java Bean with a custom Builder pattern. + * @param customBuilderEnabled if true Java Beans with a custom Builder pattern are transformed automatically. By default it's false. + * @return the {@link BeanTransformer} instance + */ + BeanTransformer setCustomBuilderTransformationEnabled(boolean customBuilderEnabled); } diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index af90718da..c9a2e39da 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -19,6 +19,7 @@ import static java.util.Arrays.stream; import static java.util.Objects.isNull; import static java.util.Objects.nonNull; +import static java.util.Optional.empty; import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; @@ -59,7 +60,7 @@ public class TransformerImpl extends AbstractBeanTransformer { @Override protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final Optional> builderClass = classUtils.getBuilderClass(targetClass); + final Optional> builderClass = getBuilderClass(targetClass); if (builderClass.isPresent()) { k = injectThroughBuilder(sourceObj, targetClass, builderClass.get(), breadcrumb); } else { @@ -71,6 +72,16 @@ protected final K transform(final T sourceObj, final Class t return k; } + /** + * Gets the Java Bean Builder class (if any). + * @param targetClass the destination object class + * @param the target object type + * @return the Builder class + */ + private Optional> getBuilderClass(final Class targetClass) { + return !settings.isCustomBuilderTransformationEnabled() ? empty() : classUtils.getBuilderClass(targetClass); + } + /** * Inject all properties value from an object to a new one using the class builder. * @param sourceObj the source object diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 896de1004..1a1c605f9 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -41,12 +41,14 @@ public class BuilderObjectTransformationTest extends AbstractBeanTransformerTest @Test(dataProvider = "transformationThroughBuilderTesting") public void testTransformationThroughBuilder(final String testDescription, final Object sourceObject, final Class targetObjectClass) { //GIVEN + underTest.setCustomBuilderTransformationEnabled(true); //WHEN Object actual = underTest.transform(sourceObject, targetObjectClass); //THEN assertThat(actual, sameBeanAs(sourceObject)); + underTest.setCustomBuilderTransformationEnabled(false); } /** diff --git a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java index ef80d3f24..b27a9de2b 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java @@ -88,4 +88,11 @@ public class TransformerSettings { */ @Setter private boolean primitiveTypeConversionEnabled; + + /** + * It allows to enable/disable the transformation of Java Bean with a custom Builder pattern. + * if true Java Beans with a custom Builder pattern are transformed automatically. + */ + @Setter + private boolean customBuilderTransformationEnabled; } diff --git a/docs/site/markdown/transformer/bean/builder.md b/docs/site/markdown/transformer/bean/builder.md index 8cde679dd..e97ad47bc 100644 --- a/docs/site/markdown/transformer/bean/builder.md +++ b/docs/site/markdown/transformer/bean/builder.md @@ -50,6 +50,8 @@ public class ItemType { ### Custom Builder pattern: +To enable the transformation of Java Beans using the following Builder pattern: + ~~~Java public class ItemType { private final Class objectClass; @@ -88,4 +90,12 @@ public class ItemType { } } } +~~~ + +It's needed to enable the custom Builder Transformation as following: + +~~~Java +ToBean toBean = new BeanTransformer() + .setCustomBuilderTransformationEnabled(true) + .transform(sourceObject, ToBean.class); ~~~ \ No newline at end of file From 8765c02a9c29d822574683e64eec12f61a195510 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 Apr 2020 10:58:12 +0200 Subject: [PATCH 1078/1786] Updates the changelog and the build version --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 5 ++--- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 59dec2f13..230843382 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.7.0-jdk8] TBD +### [1.7.0-jdk8] 2020.03.20 #### Added * Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index 22e537e00..f11ad12cb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,11 @@ All notable changes to this project will be documented in this file. -### [1.7.0] TBD +### [1.7.0.0] 2020.03.20 #### Added * Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). - #### Changed -* Updated `hibernate-validator` version to `6.1.3.Final` (was `6.1.2.Final`). +* Updated `hibernate-validator` version to `6.1.4.Final` (was `6.1.2.Final`). ### [1.6.6] 2020.03.16 ### Added diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 784f18a23..cd52a7b09 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0-SNAPSHOT + 1.7.0.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index c952e08f3..322bdd173 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0-SNAPSHOT + 1.7.0.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 237ffec83..707a8b3af 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0-SNAPSHOT + 1.7.0.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 9c820716c..d1d1339bd 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.0-SNAPSHOT + 1.7.0.0 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 0a85250f8..d33ea370b 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.0-SNAPSHOT + 1.7.0.0 diff --git a/pom.xml b/pom.xml index 6f3ac431f..6d0626fda 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.0-SNAPSHOT + 1.7.0.0 pom 2019 From c173c10e60d593d6235ab5cccea167ab380b06b3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 Apr 2020 11:00:13 +0200 Subject: [PATCH 1079/1786] Updates the changelog and the build version --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index cd52a7b09..42f515998 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0.0 + 1.7.0.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 322bdd173..ac595e6b4 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0.0 + 1.7.0.0-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 707a8b3af..06e4c13b3 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0.0 + 1.7.0.0-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index d1d1339bd..75034d748 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.0.0 + 1.7.0.0-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index d33ea370b..37bbfcd4c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.0.0 + 1.7.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 6d0626fda..863030875 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.0.0 + 1.7.0.0-SNAPSHOT pom 2019 From a6012e5340e8b54994d637cdf0b402f0c62054e0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 Apr 2020 11:11:03 +0200 Subject: [PATCH 1080/1786] [maven-release-plugin] prepare release 1.7.0.0 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 42f515998..cd52a7b09 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0.0-SNAPSHOT + 1.7.0.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index ac595e6b4..322bdd173 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0.0-SNAPSHOT + 1.7.0.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 06e4c13b3..707a8b3af 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0.0-SNAPSHOT + 1.7.0.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 75034d748..d1d1339bd 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.0.0-SNAPSHOT + 1.7.0.0 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 37bbfcd4c..d33ea370b 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.0.0-SNAPSHOT + 1.7.0.0 diff --git a/pom.xml b/pom.xml index 863030875..c18071a14 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.0.0-SNAPSHOT + 1.7.0.0 pom 2019 @@ -94,7 +94,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.7.0.0 From adb68be5638cbc264bd6a8c19dafab7bb46250b3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 Apr 2020 11:11:13 +0200 Subject: [PATCH 1081/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index cd52a7b09..aaa9c4468 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0.0 + 1.7.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 322bdd173..67e5358f9 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0.0 + 1.7.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 707a8b3af..69b1cf639 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.0.0 + 1.7.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index d1d1339bd..188dd5a33 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.0.0 + 1.7.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index d33ea370b..f485a4ca9 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.0.0 + 1.7.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index c18071a14..1d8f1192a 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.0.0 + 1.7.1-SNAPSHOT pom 2019 @@ -94,7 +94,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.0.0 + HEAD From 97b59fb38f1118055e4b0487566066feda2bbeed Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 Apr 2020 15:03:38 +0200 Subject: [PATCH 1082/1786] Minor improvements --- bull-bean-transformer/pom.xml | 5 ----- .../src/main/java/com/hotels/transformer/base/Defaults.java | 2 +- .../main/java/com/hotels/transformer/constant/Filters.java | 2 +- .../main/java/com/hotels/transformer/utils/ClassUtils.java | 6 +++--- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index aaa9c4468..90d1c8374 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -12,11 +12,6 @@ - - com.hotels.beans - bull-common - ${project.version} - com.hotels.beans bull-converter diff --git a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java index ab237080c..6cf3da3f4 100644 --- a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java +++ b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java @@ -33,7 +33,7 @@ * Default values for primitive types. */ @UtilityClass -public final class Defaults { +public class Defaults { /** * Gets the default value of a primitive type. * @param type the class type diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java index 01c237ab9..3b9a3bb94 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java @@ -28,7 +28,7 @@ * Filters conditions. */ @UtilityClass -public final class Filters { +public class Filters { /** * Returns only the final not static field. */ diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 26f8d8262..75e2b3cfd 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -601,11 +601,11 @@ public Parameter[] getConstructorParameters(final Constructor constructor) { public boolean hasField(final Object target, final String fieldName) { final String cacheKey = "ClassHasField-" + target.getClass().getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - boolean hasField; + boolean hasField = false; try { - hasField = nonNull(target.getClass().getDeclaredField(fieldName)); + target.getClass().getDeclaredField(fieldName); + hasField = true; } catch (final NoSuchFieldException e) { - hasField = false; final Class superclass = target.getClass().getSuperclass(); if (hasSuperclass(superclass)) { hasField = hasField(superclass, fieldName); From 211257942531c6a5caaa7ff662ab62a6f8ef2f33 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 20 Apr 2020 15:10:41 +0200 Subject: [PATCH 1083/1786] Minor: adds suppression --- .../src/main/java/com/hotels/transformer/utils/ClassUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 75e2b3cfd..b66d3eb57 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -476,6 +476,7 @@ public Class[] getDeclaredClasses(final Class clazz) { * @param targetClass the class where the builder should be searched * @return the Builder class if available. */ + @SuppressWarnings("unchecked") public Optional> getBuilderClass(final Class targetClass) { String cacheKey = "BuilderClass-" + targetClass.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { From c4233c50447a7d904b20dc59fab2c218f354a80b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 Apr 2020 06:46:18 +0200 Subject: [PATCH 1084/1786] Updates changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f11ad12cb..6903f19d4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.7.0.0] 2020.03.20 +### [1.7.1] 2020.03.21 #### Added * Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). #### Changed From a445fbedd00ba71aa229849b6803900b87c3c28b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 Apr 2020 06:47:27 +0200 Subject: [PATCH 1085/1786] [maven-release-plugin] prepare release 1.7.1 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 90d1c8374..e99e44375 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.1-SNAPSHOT + 1.7.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 67e5358f9..6f68a091f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.1-SNAPSHOT + 1.7.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 69b1cf639..8a627a782 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.1-SNAPSHOT + 1.7.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 188dd5a33..a1434df37 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.1-SNAPSHOT + 1.7.1 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index f485a4ca9..ce47bced2 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.1-SNAPSHOT + 1.7.1 diff --git a/pom.xml b/pom.xml index 1d8f1192a..f850a1505 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.1-SNAPSHOT + 1.7.1 pom 2019 @@ -94,7 +94,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.7.1 From 34a10ba02a849a39909dcee4462dd7d3cf4bceb7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 Apr 2020 06:47:36 +0200 Subject: [PATCH 1086/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index e99e44375..3db367f2f 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.1 + 1.7.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 6f68a091f..fb982ae71 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.1 + 1.7.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 8a627a782..f6b228da6 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.1 + 1.7.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index a1434df37..01b434be4 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.1 + 1.7.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index ce47bced2..053914ad7 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.1 + 1.7.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index f850a1505..7a61d9e75 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.1 + 1.7.2-SNAPSHOT pom 2019 @@ -94,7 +94,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.1 + HEAD From 9f8393442861d657c78231a83cd4ab65a2ecb1fb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 21 Apr 2020 09:14:03 +0200 Subject: [PATCH 1087/1786] Configures the checkstyle plugin to be executed after spotless --- pom.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 7a61d9e75..bf8ec325b 100644 --- a/pom.xml +++ b/pom.xml @@ -431,8 +431,10 @@ ${maven.checkstyle.plugin.version} - validate - validate + process-sources + + check + config/checkstyle/rules.xml config/checkstyle/suppression.xml @@ -442,9 +444,6 @@ ${checkstyle.check.skip} ${checkstyle.includeTestSourceDirectory} - - check - From 6afbfeea32024e087f8301dc7ba9df75aeb5de2f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 24 Apr 2020 16:55:32 +0200 Subject: [PATCH 1088/1786] Upgrades maven-wrapper to 0.5.6 (was 0.5.5) --- .mvn/wrapper/maven-wrapper.properties | 2 +- mvnw | 4 ++-- mvnw.cmd | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 76655c7c1..2feaca7f9 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,5 +1,5 @@ distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip -wrapper.url=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar +wrapper.url=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar # Path where the maven-wrapper.jar will be saved to. maven.wrapper.jar.path=.mvn/wrapper/maven-wrapper.jar diff --git a/mvnw b/mvnw index d1ca01734..c0a2d08c1 100755 --- a/mvnw +++ b/mvnw @@ -212,9 +212,9 @@ else echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." fi if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" fi while IFS="=" read key value; do case "$key" in (wrapperUrl) jarUrl="$value"; break ;; diff --git a/mvnw.cmd b/mvnw.cmd index b26ab24f0..665e101ba 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -120,7 +120,7 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B @@ -134,7 +134,7 @@ if exist %WRAPPER_JAR% ( ) ) else ( if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... From 4532169eb7db935da5267ee71f5ce46580029379 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2020 02:21:08 +0000 Subject: [PATCH 1089/1786] Bump wagon-ssh from 3.3.4 to 3.4.0 Bumps wagon-ssh from 3.3.4 to 3.4.0. Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bf8ec325b..8cfd02681 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ 2.3.1 - 3.3.4 + 3.4.0 0.12 github 3.9.0 From fe2881b6b21a15b1ef730b4aa9db737e187dd2fd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 27 Apr 2020 07:33:29 +0200 Subject: [PATCH 1090/1786] Updates changelog --- CHANGELOG-JDK8.md | 4 ++++ CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 230843382..c1c550699 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.7.1-jdk8] TBD +#### Changed +* Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). + ### [1.7.0-jdk8] 2020.03.20 #### Added * Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). diff --git a/CHANGELOG.md b/CHANGELOG.md index 6903f19d4..874ed3bae 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.7.2] TBD +#### Changed +* Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). + ### [1.7.1] 2020.03.21 #### Added * Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). From fc2291ba2908852e082501800bc2a05400975819 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 30 Apr 2020 09:53:34 +0200 Subject: [PATCH 1091/1786] Makes the checkstyle rules compliant with the latest plugin version --- config/checkstyle/rules.xml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/config/checkstyle/rules.xml b/config/checkstyle/rules.xml index 04498920d..27de1383e 100644 --- a/config/checkstyle/rules.xml +++ b/config/checkstyle/rules.xml @@ -2,7 +2,6 @@ - - + + + + + + @@ -133,13 +138,6 @@ - - - - - - - From 22389cd00df164e8831d0de9a24f8cff64f95455 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 30 Apr 2020 09:57:30 +0200 Subject: [PATCH 1092/1786] Updates the checkstyle plugin version --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 8cfd02681..e70876d0c 100644 --- a/pom.xml +++ b/pom.xml @@ -80,6 +80,7 @@ github 3.9.0 + 3.1.1 false true false From 0aa483d43f69aa8f4c444dd3c759a3c5c231ea51 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 7 May 2020 02:24:48 +0000 Subject: [PATCH 1093/1786] Bump hibernate-validator from 6.1.4.Final to 6.1.5.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.1.4.Final to 6.1.5.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.1.5.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.1.4.Final...6.1.5.Final) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e70876d0c..ac20b159d 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 1.3.0 2.0.1.Final - 6.1.4.Final + 6.1.5.Final 1.7.30 3.0.0 2.2.6 From b27240dab1ba34b6974eaddd18d01f638f851678 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 7 May 2020 07:27:23 +0200 Subject: [PATCH 1094/1786] [travis skip] Updates changelog files with the new dependency version --- CHANGELOG-JDK8.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index c1c550699..a3a17e2f9 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.7.1-jdk8] TBD #### Changed * Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). +* Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). ### [1.7.0-jdk8] 2020.03.20 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 874ed3bae..ad9937207 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### [1.7.2] TBD #### Changed * Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). +* Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). ### [1.7.1] 2020.03.21 #### Added From a558a9d1a3ac36b2bb426e7ffa395509be691362 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 7 May 2020 09:21:40 +0200 Subject: [PATCH 1095/1786] Adds the coveralls token to the Travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 91c32a47c..24444877c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ jdk: - openjdk11 - openjdk12 - openjdk13 -script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode +script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: include: From 6bbfc37d32cf11786a142ae8adf8bbcecf673492 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 8 May 2020 02:35:00 +0000 Subject: [PATCH 1096/1786] Bump spring-boot-starter-test from 2.2.6.RELEASE to 2.2.7.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.2.6.RELEASE to 2.2.7.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.2.6.RELEASE...v2.2.7.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ac20b159d..d0b7ff145 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 11 ${jdk.version} ${jdk.version} - 2.2.6.RELEASE + 2.2.7.RELEASE 1.18.12 3.10 0.11 From c65a06fd0e07e27440da807fe95de9d6dec73a0f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 8 May 2020 06:49:28 +0200 Subject: [PATCH 1097/1786] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad9937207..7e8c657de 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). * Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). +* Updated spring-boot-starter-test version to 2.2.7.RELEASE (was 2.2.6.RELEASE). ### [1.7.1] 2020.03.21 #### Added From 899c4be3696e7553ee0e9597a3aa2faeeea7569a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 8 May 2020 06:51:45 +0200 Subject: [PATCH 1098/1786] Update CHANGELOG-JDK8.md --- CHANGELOG-JDK8.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index a3a17e2f9..4b5874ad4 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). * Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). +* Updated `spring-boot-starter-test` version to `2.2.7.RELEASE` (was `2.2.6.RELEASE`). ### [1.7.0-jdk8] 2020.03.20 #### Added From a86eed3a5486bb0ce02a9353c520660ba4f3a2b4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 8 May 2020 06:52:55 +0200 Subject: [PATCH 1099/1786] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e8c657de..1519092ba 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). * Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). -* Updated spring-boot-starter-test version to 2.2.7.RELEASE (was 2.2.6.RELEASE). +* Updated `spring-boot-starter-test` version to `2.2.7.RELEASE` (was `2.2.6.RELEASE`). ### [1.7.1] 2020.03.21 #### Added From 18eaf470e69ffabb31d989b5937d338902e2c7bc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 15 May 2020 17:54:24 +0200 Subject: [PATCH 1100/1786] Improves the .md file syntax specifying the code snipped type --- CHANGELOG-JDK8.md | 4 +- CHANGELOG.md | 4 +- README.md | 244 +++++++++--------- RELEASE.md | 48 ++-- docs/site/markdown/converter/samples.md | 16 +- .../site/markdown/transformer/bean/builder.md | 12 +- .../site/markdown/transformer/bean/samples.md | 160 ++++++------ .../site/markdown/transformer/bean/testing.md | 28 +- docs/site/markdown/transformer/map/samples.md | 88 +++---- .../markdown/transformer/mapTransformer.md | 4 +- docs/site/markdown/validator/samples.md | 28 +- 11 files changed, 318 insertions(+), 318 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 4b5874ad4..d4766a6f2 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -94,13 +94,13 @@ All notable changes to this project will be documented in this file. ### [1.1.24] 2019.09.02 #### Changed * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.1.25`, use `bull-bean-transformer` instead.** - ~~~ + ```xml com.hotels.beans bull-bean-transformer x.y.z - ~~~ + ``` * Module `bean-utils-library` has been relocated into `bull-bean-transformer`. * The following classes has been deprecated, please find below the complete list and the new one to be used: diff --git a/CHANGELOG.md b/CHANGELOG.md index 1519092ba..86d941423 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,13 +91,13 @@ All notable changes to this project will be documented in this file. ### [1.5.1] 2019.09.02 #### Changed * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** - ~~~ + ```xml com.hotels.beans bull-bean-transformer x.y.z - ~~~ + ``` * Module `bean-utils-library` has been relocated into `bull-bean-transformer`. * The following classes has been deprecated, please find below the complete list and the new one to be used: diff --git a/README.md b/README.md index 46e79c36a..5e56be73b 100644 --- a/README.md +++ b/README.md @@ -24,23 +24,23 @@ All BULL modules are available on Maven Central: * ### Bean Transformer -~~~ +``` com.hotels.beans bull-bean-transformer x.y.z -~~~ +``` * ### `Map` Transformer -~~~ +``` com.hotels.beans bull-map-transformer x.y.z -~~~ +``` **The project provides two different builds**, one compatible with `jdk 8` (or above) and one with `jdk 11` or above. @@ -51,7 +51,7 @@ In case you need to integrate it in a `jdk 8` (or above project) please refer to Some jdk versions removes the Java Bean constructor's argument names from the compiled code and this may cause problems to the library. On top of that, it's suggested to configure the `maven-compiler-plugin`, inside your project, as follow: -~~~ +```xml ... @@ -72,27 +72,27 @@ On top of that, it's suggested to configure the `maven-compiler-plugin`, inside ... -~~~ +``` ## Maven build Full build -~~~ +```shell script ./mvnw clean install -~~~ +``` or on Windows -~~~ +```shell script mvnw.cmd clean install -~~~ +``` Skip test coverage and checkstyle check -~~~ +```shell script ./mvnw clean install -P relaxed -~~~ +``` or on Windows -~~~ +```shell script mvnw.cmd clean install -P relaxed -~~~ +``` ## Features: * support copy of immutable beans. @@ -128,7 +128,7 @@ mvnw.cmd clean install -P relaxed ### Simple case: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -140,16 +140,16 @@ public class FromBean { public class ToBean // all constructors // all args constructor // getters and setters... // getters and setters... } -~~~ +``` And one line code as: -~~~Java +```java ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); -~~~ +``` ### Different field names copy: From class and To class with different field names: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String differentName; @@ -174,17 +174,17 @@ public class FromBean { public class ToBean // getters... } -~~~ +``` And one line code as: -~~~Java +```java beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class); -~~~ +``` ### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: Assuming that the object `FromSubBean` is declared as follow: -~~~Java +```java public class FromSubBean { private String serialNumber; @@ -193,9 +193,9 @@ public class FromSubBean { // getters and setters... } -~~~ +``` and our source object and destination object are described as follow: -~~~Java +```java public class FromBean { public class ToBean { private final int id; private final int id; @@ -207,20 +207,20 @@ public class FromBean { public class ToBean // getters... // getters... } } -~~~ +``` the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: -~~~Java +```java FieldMapping serialNumberMapping = new FieldMapping<>("subObject.serialNumber", "serialNumber"); FieldMapping creationDateMapping = new FieldMapping<>("subObject.creationDate", "creationDate"); beanUtils.getTransformer() .withFieldMapping(serialNumberMapping, creationDateMapping) .transform(fromBean, ToBean.class); -~~~ +``` ### Different field names defining constructor args: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String differentName; private final int id; private final int id; @@ -245,15 +245,15 @@ public class FromBean { public class ToBean // getters... } -~~~ +``` And one line code as: -~~~Java +```java ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); -~~~ +``` ### Different field names and types applying transformation through lambda function: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger identifier; @@ -267,22 +267,22 @@ public class FromBean { public class ToBean // getters and setters... // getters and setters... } } -~~~ +``` -~~~Java +```java FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); FieldTransformer localeTransformer = new FieldTransformer<>("locale", Locale::forLanguageTag); beanUtils.getTransformer() .withFieldMapping(new FieldMapping<>("id", "identifier")) .withFieldTransformer(fieldTransformer).transform(fromBean, ToBean.class) .withFieldTransformer(localeTransformer); -~~~ +``` ### Assign a default value in case of missing field in the source object: Assign a default value in case of missing field in the source object: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -293,19 +293,19 @@ public class FromBean { public class ToBean // getters... // getters and setters... } } -~~~ +``` And one line code as: -~~~Java +```java ToBean toBean = beanUtils.getTransformer() .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); -~~~ +``` ### Disable the default value set for primitive types in case they are null: BULL by default sets the default value for all primitive types fields in case their value in the source object. Given the following Java Bean: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -315,15 +315,15 @@ public class FromBean { public class ToBean // getters... // getters and setters... } } -~~~ +``` in case the field `id` in the `FromBean` object is `null`, the value assigned the correspondent field in the `ToBean` object will be `0`. To disable this you can simply do: -~~~Java +```java ToBean toBean = beanUtils.getTransformer() .setDefaultValueSetEnabled(false).transform(fromBean, ToBean.class); -~~~ +``` in this case the field `id` after the transformation will be `null` @@ -331,7 +331,7 @@ in this case the field `id` after the transformation will be `null` Assign a default value in case of missing field in the source object: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -341,14 +341,14 @@ public class FromBean { public class ToBean // all args constructor // constructors... // getters... // getters and setters... } } -~~~ +``` And one line code as: -~~~Java +```java FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", () -> "sampleVal"); ToBean toBean = beanUtils.getTransformer() .withFieldTransformer(notExistingFieldTransformer) .transform(fromBean, ToBean.class); -~~~ +``` ### Apply a transformation function on a field contained in a nested object: @@ -356,7 +356,7 @@ This example shows of a lambda transformation function can be applied on a neste Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; @@ -364,22 +364,22 @@ public class FromBean { public class ToBean // all args constructor // all args constructor // getters... // getters... } } -~~~ +``` and -~~~Java +```java public class ToSubBean { private final String name; private final long index; } -~~~ +``` Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as follow: -~~~Java +```java FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); ToBean toBean = beanUtils.getTransformer() .withFieldTransformer(nameTransformer) .transform(fromBean, ToBean.class); -~~~ +``` ### Map a primitive type field in the source object into a nested object: @@ -387,7 +387,7 @@ This example shows how to map a primitive field into a nested object into the de Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; @@ -395,21 +395,21 @@ public class FromBean { public class ToBean // all args constructor // all args constructor // getters... // getters... } } -~~~ +``` and -~~~Java +```java public class ToSubBean { private final int x; // all args constructor } // getters... -~~~ +``` Assuming that the value `x` should be mapped into field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as follow: -~~~Java +```java ToBean toBean = beanUtils.getTransformer() .withFieldMapping(new FieldMapping<>("x", "nestedObject.x")); -~~~ +``` ### Apply a transformation function on all fields matching with the given one: @@ -417,7 +417,7 @@ This example shows how a lambda transformation function can be applied on all fi Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; @@ -425,9 +425,9 @@ public class FromBean { public class ToBean // all args constructor // all args constructor // getters... // getters... } } -~~~ +``` and -~~~Java +```java public class FromSubBean { public class ToSubBean { private final String name; private final String name; private final long index; private final long index; @@ -435,42 +435,42 @@ public class FromSubBean { public class ToSubBe // all args constructor // all args constructor // getters... // getters... } } -~~~ +``` Assuming that the lambda transformation function should be applied only to the field: `name` contained in the `ToSubBean` object, the transformation function has to be defined as follow: -~~~Java +```java FieldTransformer nameTransformer = new FieldTransformer<>("name", StringUtils::capitalize); ToBean toBean = beanUtils.getTransformer() .setFlatFieldNameTransformation(true) .withFieldTransformer(nameTransformer) .transform(fromBean, ToBean.class); -~~~ +``` ### Static transformer function: -~~~Java +```java List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimple); -~~~ +``` can be transformed as follow: -~~~Java +```java Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); -~~~ +``` or if you have a pre-configured transformer: -~~~Java +```java Function transformerFunction = BeanUtils.getTransformer(, ImmutableToFooSimple.class); List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); -~~~ +``` ### Enable Java Beans validation: Assuming that the field: `id` in the fromBean instance is null. -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -479,19 +479,19 @@ public class FromBean { public class ToBean // all args constructor // all args constructor // getters... // getters and setters... } } -~~~ +``` adding the following configuration an exception will be thrown: -~~~Java +```java ToBean toBean = beanUtils.getTransformer() .setValidationEnabled(true) .transform(fromBean, ToBean.class); -~~~ +``` ### Copy on an existing instance: Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private String name; private final FromSubBean nestedObject; private ToSubBean nestedObject; @@ -499,18 +499,18 @@ public class FromBean { public class ToBean // all args constructor // constructor // getters... // getters and setters... } } -~~~ +``` if you need to perform the copy on an already existing object, just do: -~~~Java +```java ToBean toBean = new ToBean(); beanUtils.getTransformer().transform(fromBean, toBean); -~~~ +``` ### Skip transformation on a given set of fields: Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private String name; private final FromSubBean nestedObject; private ToSubBean nestedObject; @@ -526,14 +526,14 @@ public class FromBean2 { // all args constructor // getters... } -~~~ +``` if you need to skip the transformation for a given field, just do: -~~~Java +```java ToBean toBean = new ToBean(); beanUtils.getTransformer() .skipTransformationForField("nestedObject") .transform(fromBean, toBean); -~~~ +``` where `nestedObject` is the name of the field in the destination object. @@ -544,7 +544,7 @@ To better explain this function let's assume that the `ToBean` (defined above) s - `nestedObject` field value has been taken from the `FromBean2` object the objective can be reached by doing: -~~~Java +```java // create the destination object ToBean toBean = new ToBean(); @@ -557,11 +557,11 @@ beanUtils.getTransformer() beanUtils.getTransformer() .skipTransformationForField("name") .transform(fromBean2, toBean); -~~~ +``` ### Not existing field in the source object: In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should gets the field value from that method. -~~~Java +```java public class FromBean { public class ToBean { private final BigInteger id; public BigInteger getId() { @@ -569,17 +569,17 @@ public class FromBean { public class ToBean } // getters... } } -~~~ +``` And one line code as: -~~~Java +```java ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); -~~~ +``` ### Transform primitive types automatically Given the following Java Bean: -~~~Java +```java public class FromBean { public class ToBean { private final String indexNumber; private final int indexNumber; private final BigInteger id; public Long id; @@ -588,18 +588,18 @@ public class FromBean { public class ToBean // getters... // getters and setters... } } -~~~ +``` as, by default the primitive type conversion is disabled, to get the above object converted we should have implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically from enabling the functionality described above. -~~~Java +```java Transformer transformer = beanUtils.getTransformer() .setPrimitiveTypeConversionEnabled(true); ToBean toBean = transformer.transform(fromBean, ToBean.class); -~~~ +``` **IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function defined on a specific field. This means that the once the `FieldTransformer` function will be executed the field value has already been transformed. @@ -610,7 +610,7 @@ The library support the transformation of Java Bean using the following Builder ### Standard pattern: -~~~Java +```java public class ItemType { private final Class objectClass; private final Class genericClass; @@ -648,13 +648,13 @@ public class ItemType { } } } -~~~ +``` ### Custom Builder pattern: To enable the transformation of Java Beans using the following Builder pattern: -~~~Java +```java public class ItemType { private final Class objectClass; private final Class genericClass; @@ -692,15 +692,15 @@ public class ItemType { } } } -~~~ +``` It's needed to enable the custom Builder Transformation as following: -~~~Java +```java ToBean toBean = new BeanTransformer() .setCustomBuilderTransformationEnabled(true) .transform(sourceObject, ToBean.class); -~~~ +``` ## Constraints: @@ -781,7 +781,7 @@ Validate a java bean has never been so simple. The library offers different API Given the following bean: -~~~Java +```java public class SampleBean { @NotNull private BigInteger id; @@ -790,19 +790,19 @@ public class SampleBean { // constructor // getters and setters... } -~~~ +``` an instance of the above object: -~~~Java +```java SampleBean sampleBean = new SampleBean(); -~~~ +``` And one line code as: -~~~Java +```java beanUtils.getValidator().validate(sampleBean); -~~~ +``` this will throw an `InvalidBeanException` as the `id` field is null. @@ -810,7 +810,7 @@ this will throw an `InvalidBeanException` as the `id` field is null. Given the following bean: -~~~Java +```java public class SampleBean { @NotNull private BigInteger id; @@ -819,26 +819,26 @@ public class SampleBean { // constructor // getters and setters... } -~~~ +``` an instance of the above object: -~~~Java +```java SampleBean sampleBean = new SampleBean(); -~~~ +``` And one line code as: -~~~Java +```java List violatedConstraints = beanUtils.getValidator().getConstraintViolationsMessages(sampleBean); -~~~ +``` this will returns a list containing a constraint validation message for the `id` field as it's null and the constraint: `@NotNull` is not met. in case it's needed to have the `ConstraintViolation` object: -~~~Java +```java Set> violatedConstraints = beanUtils.getValidator().getConstraintViolations(sampleBean); -~~~ +``` ## Primitive type object converter @@ -861,33 +861,33 @@ The supported types, in which an object can be converted (from / to), are: Given the following variable: -~~~Java +```java String indexNumber = "26062019"; -~~~ +``` to convert it in an `int`: -~~~Java +```java Converter converter = new BeanUtils().getPrimitiveTypeConverter(); int indexNumber = converter.convertValue(indexNumber, int.class); -~~~ +``` ### Obtain a conversion function that convert from char to byte: It's possible to obtain a type conversion function, reusable several time in different places. Assuming that the required conversion is from `char` to `byte -~~~Java +```java char c = '1'; -~~~ +``` the conversion function is retrieved through: -~~~Java +```java Converter converter = new BeanUtils().getPrimitiveTypeConverter(); Optional> conversionFunction = converter.getConversionFunction(char.class, byte.class); byte converted = conversionFunction.map(processor -> processor.apply(c)).orElse(0); -~~~ +``` * in case the conversion is not needed as the primitive type and the destination type are the same it will return an empty `Optional` * in case the conversion function is unavailable or no not possible the method throws a : `TypeConversionException` diff --git a/RELEASE.md b/RELEASE.md index db8837dd5..306cdb158 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -52,16 +52,16 @@ from it's latest release tag. The first thing to do is to create a branch (that would have the same name as the `jdk11` one plus the suffix: `-jd8`) starting from the latest `jdk8` release tag: -~~~ +```shell script $ git checkout -b [branch name]-jdk8 [latest jdk8 release tag] -~~~ +``` e.g. if the latest `jdk8` release tag is: `1.7.0-jdk8` and the new feature branch is: `feature/my-new-feature` the command to perform is: -~~~ +```shell script $ git checkout -b feature/my-new-feature-jdk8 1.7.0-jdk8 -~~~ +``` **IMPORTANT:** In the new branch, apply only the changes introduced comparing the code with the `jdk11` branch. When completed, commit your code and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. @@ -85,12 +85,12 @@ The guide explains how to do a release both the `jdk11` and `jdk8` compatible: The following steps will do a release "`X.Y.Z-jdk8`" -~~~ +```shell script $ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean -~~~ +``` #### 1. Create a branch from the latest JDK8 release tag @@ -102,10 +102,10 @@ Assuming that: the release branch would be: `release/my-new-feature-jdk8` -~~~ +```shell script $ git checkout -b release/my-new-feature-jdk8 A.B.C-jdk8 $ git push --set-upstream origin release/my-new-feature-jdk8 -~~~ +``` #### 2. Apply the changes to the new branch @@ -115,9 +115,9 @@ Apply all the changes you implemented to this branch. The maven version is now set with the latest released, but you need to change it with the new one you are going to release: -~~~ +```shell script $ mvn versions:set -D newVersion=X.Y.Z-jdk8 -~~~ +``` Commit all the changes and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. @@ -125,30 +125,30 @@ Commit all the changes and verify that the [Travis build](https://travis-ci.org/ Once you will have created the tag, and pushed it to the remote repo, an automatic release will be performed by Travis. -~~~ +```shell script $ git tag -a X.Y.Z-jdk8 -m "my version X.Y.Z-jdk8" $ git push origin --tags -~~~ +``` #### 5. Remove the no longer needed branch If the release went successfully, you can now delete the branch: -~~~ +```shell script $ git branch -D release/my-new-feature-jdk8 $ git push --delete release/my-new-feature-jdk8 -~~~ +``` ### JDK11 Release The following steps will do a release "`X.Y.Z`" -~~~ +```shell script $ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean -~~~ +``` #### 1. Create a branch from the master branch @@ -160,17 +160,17 @@ Assuming that: the release branch would be: `release/my-new-feature` -~~~ +```shell script $ git checkout -b release/my-new-feature -~~~ +``` #### 2. Change the maven version The maven version is now set with the latest released, but you need to change it with the new one you are going to release: -~~~ +```shell script $ mvn versions:set -D newVersion=X.Y.Z -~~~ +``` Commit all the changes and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. @@ -178,16 +178,16 @@ Commit all the changes and verify that the [Travis build](https://travis-ci.org/ Once you will have created the tag, and pushed it to the remote repo, an automatic release will be performed by Travis. -~~~ +```shell script $ git tag -a X.Y.Z -m "my version X.Y.Z" $ git push origin --tags -~~~ +``` #### 4. Remove the no longer needed branch If the release went successfully, you can now delete the branch: -~~~ +```shell script $ git branch -D release/my-new-feature $ git push --delete release/my-new-feature-jdk8 -~~~ \ No newline at end of file +``` \ No newline at end of file diff --git a/docs/site/markdown/converter/samples.md b/docs/site/markdown/converter/samples.md index 5c5bfdff1..a30503298 100644 --- a/docs/site/markdown/converter/samples.md +++ b/docs/site/markdown/converter/samples.md @@ -8,33 +8,33 @@ Given the following variable: -~~~Java +```java String indexNumber = "26062019"; -~~~ +``` to convert it in an `int`: -~~~Java +```java Converter converter = new BeanUtils().getPrimitiveTypeConverter(); int indexNumber = converter.convertValue(indexNumber, int.class); -~~~ +``` ### Obtain a conversion function that convert from char to byte: It's possible to obtain a type conversion function, reusable several time in different places. Assuming that the required conversion is from `char` to `byte -~~~Java +```java char c = '1'; -~~~ +``` the conversion function is retrieved through: -~~~Java +```java Converter converter = new BeanUtils().getPrimitiveTypeConverter(); Optional> conversionFunction = converter.getConversionFunction(char.class, byte.class); byte converted = conversionFunction.map(processor -> processor.apply(c)).orElse(0); -~~~ +``` * in case the conversion is not needed as the primitive type and the destination type are the same it will return an empty `Optional` * in case the conversion function is unavailable or no not possible the method throws a : `TypeConversionException` diff --git a/docs/site/markdown/transformer/bean/builder.md b/docs/site/markdown/transformer/bean/builder.md index e97ad47bc..286e175f1 100644 --- a/docs/site/markdown/transformer/bean/builder.md +++ b/docs/site/markdown/transformer/bean/builder.md @@ -8,7 +8,7 @@ The library support the transformation of Java Bean using the following Builder ### Standard pattern: -~~~Java +```java public class ItemType { private final Class objectClass; private final Class genericClass; @@ -46,13 +46,13 @@ public class ItemType { } } } -~~~ +``` ### Custom Builder pattern: To enable the transformation of Java Beans using the following Builder pattern: -~~~Java +```java public class ItemType { private final Class objectClass; private final Class genericClass; @@ -90,12 +90,12 @@ public class ItemType { } } } -~~~ +``` It's needed to enable the custom Builder Transformation as following: -~~~Java +```java ToBean toBean = new BeanTransformer() .setCustomBuilderTransformationEnabled(true) .transform(sourceObject, ToBean.class); -~~~ \ No newline at end of file +``` \ No newline at end of file diff --git a/docs/site/markdown/transformer/bean/samples.md b/docs/site/markdown/transformer/bean/samples.md index a836d0997..b52f153d6 100644 --- a/docs/site/markdown/transformer/bean/samples.md +++ b/docs/site/markdown/transformer/bean/samples.md @@ -6,7 +6,7 @@ ### Simple case: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -19,16 +19,16 @@ public class FromBean { public class ToBean // getters and setters... // getters and setters... } } -~~~ +``` And one line code as: -~~~Java +```java ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); -~~~ +``` ### Different field names copy: From class and To class with different field names: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String differentName; @@ -53,17 +53,17 @@ public class FromBean { public class ToBean // getters... } -~~~ +``` And one line code as: -~~~Java +```java beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class);` -~~~ +``` ### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: Assuming that the object `FromSubBean` is declared as follow: -~~~Java +```java public class FromSubBean { private String serialNumber; @@ -72,9 +72,9 @@ public class FromSubBean { // getters and setters... } -~~~ +``` and our source object and destination object are described as follow: -~~~Java +```java public class FromBean { public class ToBean { private final int id; private final int id; @@ -86,20 +86,20 @@ public class FromBean { public class ToBean // getters... // getters... } } -~~~ +``` the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: -~~~Java +```java FieldMapping serialNumberMapping = new FieldMapping<>("subObject.serialNumber", "serialNumber"); FieldMapping creationDateMapping = new FieldMapping<>("subObject.creationDate", "creationDate"); beanUtils.getTransformer() .withFieldMapping(serialNumberMapping, creationDateMapping) .transform(fromBean, ToBean.class); -~~~ +``` ### Different field names defining constructor args: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String differentName; private final int id; private final int id; @@ -124,15 +124,15 @@ public class FromBean { public class ToBean // getters... } -~~~ +``` And one line code as: -~~~Java +```java ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); -~~~ +``` ### Different field names and types applying transformation through lambda function: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger identifier; @@ -146,22 +146,22 @@ public class FromBean { public class ToBean // getters and setters... // getters and setters... } } -~~~ +``` -~~~Java +```java FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); FieldTransformer localeTransformer = new FieldTransformer<>("locale", Locale::forLanguageTag); beanUtils.getTransformer() .withFieldMapping(new FieldMapping<>("id", "identifier")) .withFieldTransformer(fieldTransformer).transform(fromBean, ToBean.class) .withFieldTransformer(localeTransformer); -~~~ +``` ### Assign a default value in case of missing field in the source object: Assign a default value in case of missing field in the source object: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -172,19 +172,19 @@ public class FromBean { public class ToBean // getters... // getters and setters... } } -~~~ +``` And one line code as: -~~~Java +```java ToBean toBean = beanUtils.getTransformer() .setDefaultValueForMissingField(true).transform(fromBean, ToBean.class); -~~~ +``` ### Disable the default value set for primitive types in case they are null: BULL by default sets the default value for all primitive types fields in case their value in the source object. Given the following Java Bean: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -194,15 +194,15 @@ public class FromBean { public class ToBean // getters... // getters and setters... } } -~~~ +``` in case the field `id` in the `FromBean` object is `null`, the value assigned the correspondent field in the `ToBean` object will be `0`. To disable this you can simply do: -~~~Java +```java ToBean toBean = beanUtils.getTransformer() .setDefaultValueSetEnabled(false).transform(fromBean, ToBean.class); -~~~ +``` in this case the field `id` after the transformation will be `null` @@ -210,7 +210,7 @@ in this case the field `id` after the transformation will be `null` Assign a default value in case of missing field in the source object: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -220,14 +220,14 @@ public class FromBean { public class ToBean // all args constructor // constructors... // getters... // getters and setters... } } -~~~ +``` And one line code as: -~~~Java +```java FieldTransformer notExistingFieldTransformer = new FieldTransformer<>("notExistingField", () -> "sampleVal"); ToBean toBean = beanUtils.getTransformer() .withFieldTransformer(notExistingFieldTransformer) .transform(fromBean, ToBean.class); -~~~ +``` ### Apply a transformation function on a field contained in a nested object: @@ -235,7 +235,7 @@ This example shows of a lambda transformation function can be applied on a neste Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; @@ -243,22 +243,22 @@ public class FromBean { public class ToBean // all args constructor // all args constructor // getters... // getters... } } -~~~ +``` and -~~~Java +```java public class ToSubBean { private final String name; private final long index; } -~~~ +``` Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as follow: -~~~Java +```java FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); ToBean toBean = beanUtils.getTransformer() .withFieldTransformer(nameTransformer) .transform(fromBean, ToBean.class); -~~~ +``` ### Map a primitive type field in the source object into a nested object: @@ -266,7 +266,7 @@ This example shows how to map a primitive field into a nested object into the de Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; @@ -274,21 +274,21 @@ public class FromBean { public class ToBean // all args constructor // all args constructor // getters... // getters... } } -~~~ +``` and -~~~Java +```java public class ToSubBean { private final int x; // all args constructor } // getters... -~~~ +``` Assuming that the value `x` should be mapped into field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as follow: -~~~Java +```java ToBean toBean = beanUtils.getTransformer() .withFieldMapping(new FieldMapping<>("x", "nestedObject.x")); -~~~ +``` ### Apply a transformation function on all fields matching with the given one: @@ -296,7 +296,7 @@ This example shows how a lambda transformation function can be applied on all fi Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String name; private final FromSubBean nestedObject; private final ToSubBean nestedObject; @@ -304,9 +304,9 @@ public class FromBean { public class ToBean // all args constructor // all args constructor // getters... // getters... } } -~~~ +``` and -~~~Java +```java public class FromSubBean { public class ToSubBean { private final String name; private final String name; private final long index; private final long index; @@ -314,41 +314,41 @@ public class FromSubBean { public class ToSubBe // all args constructor // all args constructor // getters... // getters... } } -~~~ +``` Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as follow: -~~~Java +```java FieldTransformer nameTransformer = new FieldTransformer<>("name", StringUtils::capitalize); ToBean toBean = beanUtils.getTransformer() .setFlatFieldNameTransformation(true) .withFieldTransformer(nameTransformer) .transform(fromBean, ToBean.class); -~~~ +``` ### Static transformer function: -~~~Java +```java List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimple); -~~~ +``` can be transformed as follow: -~~~Java +```java Function transformerFunction = BeanUtils.getTransformer(ImmutableToFooSimple.class); List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); -~~~ +``` or if you have a pre-configured transformer: -~~~Java +```java Function transformerFunction = BeanUtils.getTransformer(, ImmutableToFooSimple.class); List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); -~~~ +``` ### Disable Java Beans validation: Assuming that the field: `id` in the fromBean instance is null. -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -357,19 +357,19 @@ public class FromBean { public class ToBean // all args constructor // all args constructor // getters... // getters and setters... } } -~~~ +``` adding the following configuration no exception will be thrown: -~~~Java +```java ToBean toBean = beanUtils.getTransformer() .setValidationDisabled(true) .transform(fromBean, ToBean.class); -~~~ +``` ### Copy on an existing instance: Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private String name; private final FromSubBean nestedObject; private ToSubBean nestedObject; @@ -377,18 +377,18 @@ public class FromBean { public class ToBean // all args constructor // constructor // getters... // getters and setters... } } -~~~ +``` if you need to perform the copy on an already existing object, just do: -~~~Java +```java ToBean toBean = new ToBean(); beanUtils.getTransformer().transform(fromBean, toBean); -~~~ +``` ### Skip transformation on a given set of fields: Given: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private String name; private final FromSubBean nestedObject; private ToSubBean nestedObject; @@ -404,14 +404,14 @@ public class FromBean2 { // all args constructor // getters... } -~~~ +``` if you need to skip the transformation for a given field, just do: -~~~Java +```java ToBean toBean = new ToBean(); beanUtils.getTransformer() .skipTransformationForField("nestedObject") .transform(fromBean, toBean); -~~~ +``` where `nestedObject` is the name of the field in the destination object. @@ -422,7 +422,7 @@ To better explain this function let's assume that the `ToBean` (defined above) s - `nestedObject` field value has be taken from the `FromBean2` object the objective can be reached by doing: -~~~Java +```java // create the destination object ToBean toBean = new ToBean(); @@ -435,12 +435,12 @@ beanUtils.getTransformer() beanUtils.getTransformer() .skipTransformationForField("name") .transform(fromBean2, toBean); -~~~ +``` ### Not existing field in the source object: In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library gets the field value from that method. -~~~Java +```java public class FromBean { public class ToBean { private final BigInteger id; public BigInteger getId() { @@ -448,17 +448,17 @@ public class FromBean { public class ToBean } // getters... } } -~~~ +``` And one line code as: -~~~Java +```java ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); -~~~ +``` ### Transform primitive types automatically Given the following Java Bean: -~~~Java +```java public class FromBean { public class ToBean { private final String indexNumber; private final int indexNumber; private final BigInteger id; public Long id; @@ -467,17 +467,17 @@ public class FromBean { public class ToBean // getters... // getters and setters... } } -~~~ +``` as, by default the primitive type conversion is disabled, to get the above object converted we should have implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically from enabling the functionality described above. -~~~Java +```java Transformer transformer = beanUtils.getTransformer() .setPrimitiveTypeConversionEnabled(true); ToBean toBean = transformer.transform(fromBean, ToBean.class); -~~~ +``` More sample beans can be found in the test package: `com.hotels.beans.sample` or on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) \ No newline at end of file diff --git a/docs/site/markdown/transformer/bean/testing.md b/docs/site/markdown/transformer/bean/testing.md index a07ebf44d..b7307724d 100644 --- a/docs/site/markdown/transformer/bean/testing.md +++ b/docs/site/markdown/transformer/bean/testing.md @@ -31,7 +31,7 @@ to be added to the test resource folder. This file is available [here](https://g All the examples will be based on the following source object and destination object: -~~~Java +```java public class SampleRequest { public class DestObject { private final BigInteger x; @NotNull private final BigInteger y; private BigInteger x; @@ -39,14 +39,14 @@ public class SampleRequest { public class DestObj // constructors // constructors // getters and setters // getters and setters } } -~~~ +``` ### First scenario #####The destination object does not require a special configuration to get transformed Given the following service class that contains the `BeanUtils` library: -~~~Java +```java import ... public class SampleClass { @@ -67,9 +67,9 @@ public class SampleClass { return x.multiply(y); } } -~~~ +``` The test class will be: -~~~Java +```java import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; import static org.mockito.Mockito.when; @@ -152,14 +152,14 @@ public class SampleClassTest { return new DestObject(x, y); } } -~~~ +``` ### Second scenario: #####The destination object requires a special configuration, but you are confident that the configuration is working fine as it doesn't includes any particular instruction. Given the following service class: -~~~Java +```java import ... public class SampleClass { @@ -183,9 +183,9 @@ public class SampleClass { return x.multiply(y); } } -~~~ +``` The test class will be: -~~~Java +```java import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; import static org.mockito.Mockito.when; @@ -272,14 +272,14 @@ public class SampleClassTest { return new DestObject(x, y); } } -~~~ +``` ### Third scenario: #####The destination object requires a special configuration that needs to be tested as you are not confident that it would work Given the following service class: -~~~Java +```java import ... public class SampleClass { @@ -303,9 +303,9 @@ public class SampleClass { return x.multiply(y); } } -~~~ +``` The test class will be: -~~~Java +```java import static org.junit.Assert.assertEquals; import static org.mockito.MockitoAnnotations.initMocks; @@ -395,4 +395,4 @@ public class SampleClassTest { } } } -~~~ +``` diff --git a/docs/site/markdown/transformer/map/samples.md b/docs/site/markdown/transformer/map/samples.md index 62b89e6a5..26431fde7 100644 --- a/docs/site/markdown/transformer/map/samples.md +++ b/docs/site/markdown/transformer/map/samples.md @@ -8,68 +8,68 @@ Given a simple `Map` defined as follow: -~~~Java +```java Map> map = new HashMap<>(); map.put("key", List.of("value1", "value2")); -~~~ +``` it can be cloned using the following command: -~~~Java +```java Map> newMap = new MapUtils().getTransformer().transform(map); -~~~ +``` ### Map a Key value into a different Key in the destination Map: Given a simple `Map` defined as follow: -~~~Java +```java Map map = new HashMap<>(); map.put("key1", "Hello"); map.put("key2", "Dude"); -~~~ +``` And assuming that we want that the `key2` value, in the destination map, has to be the `key1` one, the only thing we need to do is to define the field mapping: -~~~Java +```java FieldMapping keyMapping = new FieldMapping<>("key1", "key2"); Map> newMap = new MapUtils().getTransformer() .withFieldMapping(keyMapping) .transform(map); -~~~ +``` Then if we run the following command: -~~~Java +```java System.out.println(newMap.get("key2")); -~~~ +``` the output will be: -~~~Java +```java Hello -~~~ +``` ### Apply a transformation function on a Map key: Given a simple `Map` defined as follow: -~~~Java +```java Map map = new HashMap<>(); map.put("name", "John"); map.put("surname", "Smith"); -~~~ +``` And assuming that we want that the `name` correspondent key is made upper case, the only thing we need to do is to apply a `FieldTransformer` to the `key` defined as following: -~~~Java +```java FieldTransformer keyTransformer = new FieldTransformer<>("name", String::toUpperCase); Map> newMap = new MapUtils().getTransformer() .withKeyTransformer(keyTransformer) .transform(map); -~~~ +``` Then the key: "name" in the `newMap`will be: `NAME` @@ -77,51 +77,51 @@ Then the key: "name" in the `newMap`will be: `NAME` Given a simple `Map` defined as follow: -~~~Java +```java Map map = new HashMap<>(); map.put("key1", 30); map.put("key2", 200); -~~~ +``` And assuming that we want that the `key1` correspondent value is raised to the power of 2, the only thing we need to do is to define a `FieldTransformer` as following: -~~~Java +```java FieldTransformer keyPow = new FieldTransformer<>("key1", val -> Math.pow(val, 2)); Map> newMap = new MapUtils().getTransformer() .withFieldTransformer(keyPow) .transform(map); -~~~ +``` Then if we run the following command: -~~~Java +```java System.out.println(newMap.get("key1")); -~~~ +``` the output will be: -~~~Java +```java 900 -~~~ +``` ### Transform Map key or value object into a different object Assuming that we have a map defined as follow: -~~~Java +```java Map sourceMap = new HashMap<>(); -~~~ +``` and we want to transform it in: -~~~Java +```java Map map = new HashMap<>(); -~~~ +``` where `FromBean` and `ToBean` are: -~~~Java +```java public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger id; @@ -133,33 +133,33 @@ public class FromBean { public class ToBean // all constructors // all args constructor // getters and setters... // getters and setters... } -~~~ +``` and `FromSubBean` and `ToSubBean` are: -~~~Java +```java public class FromBean { public class ToBean { private final String index; private final String index; // all constructor // all args constructor // getters... // getters... } -~~~ +``` what we need to do is to specify the Map `Key` and `Element` class in the destination Map. In our case it will be: -~~~Java +```java Map map = new MapUtils().getTransformer() .transform(sourceMap, ToBean.class, ToSubBean.class); -~~~ +``` ### Configure a BeanTransformer and use it fo the Map transformation Assuming that we have two classes with different field names defined as follow: -~~~Java +```java public class FromBean { public class ToBean { private final String name; private final String differentName; @@ -171,29 +171,29 @@ public class FromBean { public class ToBean // all constructor // all args constructor // getters... // getters... } -~~~ +``` and our source `Map` is: -~~~Java +```java Map> sourceMap = new HashMap<>(); -~~~ +``` and we want to transform it in: -~~~Java +```java Map> map = new HashMap<>(); -~~~ +``` we first need to define a `BeanTransformer` that maps the different field names: -~~~Java +```java BeanTransformer beanTransformer = new BeanUtils().getTransformer() .withFieldMapping(new FieldMapping<>("name", "differentName")); -~~~ +``` and then pass it as argument of our Map transformation method: -~~~Java +```java Map> map = new MapUtils().getTransformer() .transform(sourceMap, beanTransformer, ToBean.class, List.class); -~~~ \ No newline at end of file +``` \ No newline at end of file diff --git a/docs/site/markdown/transformer/mapTransformer.md b/docs/site/markdown/transformer/mapTransformer.md index 59e8dc47a..6a8958689 100644 --- a/docs/site/markdown/transformer/mapTransformer.md +++ b/docs/site/markdown/transformer/mapTransformer.md @@ -13,10 +13,10 @@ You can obtain BULL from Maven Central: ## Start using -~~~ +```xml com.hotels.beans bull-map-transformer x.y.z -~~~ \ No newline at end of file +``` \ No newline at end of file diff --git a/docs/site/markdown/validator/samples.md b/docs/site/markdown/validator/samples.md index 9763dd89f..22ac7bfe0 100644 --- a/docs/site/markdown/validator/samples.md +++ b/docs/site/markdown/validator/samples.md @@ -10,7 +10,7 @@ Validate a java bean has never been so simple. The library offers different API Given the following bean: -~~~Java +```java public class SampleBean { @NotNull private BigInteger id; @@ -19,19 +19,19 @@ public class SampleBean { // constructor // getters and setters... } -~~~ +``` an instance of the above object: -~~~Java +```java SampleBean sampleBean = new SampleBean(); -~~~ +``` And one line code as: -~~~Java +```java beanUtils.getValidator().validate(sampleBean); -~~~ +``` this will throw an `InvalidBeanException` as the `id` field is null. @@ -39,7 +39,7 @@ this will throw an `InvalidBeanException` as the `id` field is null. Given the following bean: -~~~Java +```java public class SampleBean { @NotNull private BigInteger id; @@ -48,23 +48,23 @@ public class SampleBean { // constructor // getters and setters... } -~~~ +``` an instance of the above object: -~~~Java +```java SampleBean sampleBean = new SampleBean(); -~~~ +``` And one line code as: -~~~Java +```java List violatedConstraints = beanUtils.getValidator().getConstraintViolationsMessages(sampleBean); -~~~ +``` this will returns a list containing a constraint validation message for the `id` field as it's null and the constraint: `@NotNull` is not met. in case it's needed to have the `ConstraintViolation` object: -~~~Java +```java Set> violatedConstraints = beanUtils.getValidator().getConstraintViolations(sampleBean); -~~~ +``` From b7db62abccb2d70dc5b19a96cdbfe3f2d9ad0086 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 15 May 2020 17:55:24 +0200 Subject: [PATCH 1101/1786] Specifies the syntax also for the dependencies --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e56be73b..58e47f376 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ All BULL modules are available on Maven Central: * ### Bean Transformer -``` +```xml com.hotels.beans bull-bean-transformer @@ -34,7 +34,7 @@ All BULL modules are available on Maven Central: * ### `Map` Transformer -``` +```xml com.hotels.beans bull-map-transformer From 3a331b9e79938fe2942511f558ecb4f02f2bc1c0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 18 May 2020 02:27:48 +0000 Subject: [PATCH 1102/1786] Bump spring-boot-starter-test from 2.2.7.RELEASE to 2.3.0.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.2.7.RELEASE to 2.3.0.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.2.7.RELEASE...v2.3.0.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d0b7ff145..55660114c 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 11 ${jdk.version} ${jdk.version} - 2.2.7.RELEASE + 2.3.0.RELEASE 1.18.12 3.10 0.11 From 33a2d92b6f504cf6f275817a6357c6927365ba6f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 18 May 2020 07:30:06 +0200 Subject: [PATCH 1103/1786] Updates changelog files with the new dependency version --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index d4766a6f2..bd6eb8c02 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). * Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). -* Updated `spring-boot-starter-test` version to `2.2.7.RELEASE` (was `2.2.6.RELEASE`). +* Updated `spring-boot-starter-test` version to `2.3.0.RELEASE` (was `2.2.6.RELEASE`). ### [1.7.0-jdk8] 2020.03.20 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 86d941423..c88d243b4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. #### Changed * Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). * Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). -* Updated `spring-boot-starter-test` version to `2.2.7.RELEASE` (was `2.2.6.RELEASE`). +* Updated `spring-boot-starter-test` version to `2.3.0.RELEASE` (was `2.2.6.RELEASE`). ### [1.7.1] 2020.03.21 #### Added From 298235df18dba92c7768f367d8bb20e58e8c4d56 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 May 2020 11:30:07 +0200 Subject: [PATCH 1104/1786] Adds the jdk8 branch build with whe jdk 8 --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 24444877c..9137f463a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,13 @@ script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report install: skip jobs: include: + ### JDK8 build + - stage: "JDK8 Build" + name: "JDK8 Build and Test" + jdk: openjdk8 + if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ + script: + - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 From 84848fa44d04028133962311c7363d465509cbaf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 22 May 2020 11:51:01 +0200 Subject: [PATCH 1105/1786] Fix typo in Release.md --- RELEASE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 306cdb158..b11dac62a 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -49,7 +49,7 @@ All the changes implemented needs to be reported to a `jdk8` compatible version. The BULL code for the `jdk8` is slightly different so all the changes needs to be reported on the other version starting from it's latest release tag. -The first thing to do is to create a branch (that would have the same name as the `jdk11` one plus the suffix: `-jd8`) +The first thing to do is to create a branch (that would have the same name as the `jdk11` one plus the suffix: `-jdk8`) starting from the latest `jdk8` release tag: ```shell script @@ -190,4 +190,4 @@ If the release went successfully, you can now delete the branch: ```shell script $ git branch -D release/my-new-feature $ git push --delete release/my-new-feature-jdk8 -``` \ No newline at end of file +``` From 2799938cbf4720925df76673dcf37461fae8fbce Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 07:40:36 +0200 Subject: [PATCH 1106/1786] - Deprecated the method: setDefaultValueSetEnabled and replaces it with: setDefaultValueForMissingPrimitiveField - Replaces usage of Assert.assertThat (that is deprecated) with the MatcherAssert.assertThat --- .../transformer/AbstractBeanTransformer.java | 11 +++++++++- .../beans/transformer/BeanTransformer.java | 9 +++++++++ .../java/com/hotels/beans/BeanUtilsTest.java | 2 +- .../BuilderObjectTransformationTest.java | 2 +- .../ImmutableObjectTransformationTest.java | 2 +- .../MixedObjectTransformationTest.java | 2 +- .../MutableObjectTransformationTest.java | 20 ++++++++++++++++++- .../map/transformer/MapTransformerTest.java | 2 +- 8 files changed, 43 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java index 027fa4d78..2c227aef4 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java @@ -62,6 +62,15 @@ public final BeanTransformer setDefaultValueForMissingField(final boolean useDef return this; } + /** + * {@inheritDoc} + */ + @Override + public BeanTransformer setDefaultValueForMissingPrimitiveField(final boolean useDefaultValue) { + settings.setDefaultValueSetEnabled(useDefaultValue); + return this; + } + /** * {@inheritDoc} */ @@ -88,7 +97,7 @@ public BeanTransformer setValidationEnabled(final boolean validationEnabled) { */ @Override public BeanTransformer setDefaultValueSetEnabled(final boolean defaultValueSetEnabled) { - settings.setDefaultValueSetEnabled(defaultValueSetEnabled); + setDefaultValueForMissingPrimitiveField(defaultValueSetEnabled); return this; } diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index 0926ef835..babfa8cb6 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -53,6 +53,13 @@ public interface BeanTransformer extends Transformer { */ BeanTransformer setDefaultValueForMissingField(boolean useDefaultValue); + /** + * It allows to enable/disable the set of the default value for primitive types in case they are null. + * @param useDefaultValue if true the default value for the primitive type is set. By default it's true. + * @return the {@link BeanTransformer} instance + */ + BeanTransformer setDefaultValueForMissingPrimitiveField(boolean useDefaultValue); + /** * It allows to configure the transformer in order to apply a transformation function on all fields matching the given name without keeping in consideration their full path. * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. @@ -85,7 +92,9 @@ public interface BeanTransformer extends Transformer { * It allows to enable/disable the set of the default value for primitive types in case they are null. * @param defaultValueSetEnabled if true the default value for the primitive type is set. By default it's true. * @return the {@link BeanTransformer} instance + * @deprecated use {@link #setDefaultValueForMissingPrimitiveField(boolean) setDefaultValueForMissingPrimitiveField} instead. */ + @Deprecated(since = "1.7.1", forRemoval = true) BeanTransformer setDefaultValueSetEnabled(boolean defaultValueSetEnabled); /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java index 39238946c..9dfc9fe59 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -16,8 +16,8 @@ package com.hotels.beans; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 1a1c605f9..d56717358 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -16,7 +16,7 @@ package com.hotels.beans.transformer; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 6c86cf47b..487c7d167 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -18,12 +18,12 @@ import static java.lang.String.format; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index b766f9c75..74f5d3dfb 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -16,11 +16,11 @@ package com.hotels.beans.transformer; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 14233e245..330171c81 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -18,12 +18,12 @@ import static java.lang.Integer.parseInt; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasProperty; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.jupiter.api.Assertions.assertSame; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -185,6 +185,24 @@ public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { */ @Test public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeField() { + //GIVEN + FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, null, ACTIVE); + underTest.setDefaultValueForMissingPrimitiveField(false); + + //WHEN + MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); + + //THEN + assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); + underTest.setDefaultValueForMissingPrimitiveField(true); + } + + /** + * Test that the transformer does not sets the default value for primitive type field + * in case it's disabled using the deprecated method. + */ + @Test + public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeFieldUsingDeprecatedMethod() { //GIVEN FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, null, ACTIVE); underTest.setDefaultValueSetEnabled(false); diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index b52485b2b..bc1f8f31b 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -20,13 +20,13 @@ import static java.math.BigInteger.ZERO; import static java.util.Collections.singletonList; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.both; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.everyItem; import static org.hamcrest.Matchers.isIn; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; From 286f6c7d0bcbe14c4d4bf45d7a74f3ab846cab2a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 08:04:13 +0200 Subject: [PATCH 1107/1786] Prepares the v.1.7.2 release --- CHANGELOG-JDK8.md | 3 ++- CHANGELOG.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index bd6eb8c02..3a0e8e1f2 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,8 +2,9 @@ All notable changes to this project will be documented in this file. -### [1.7.1-jdk8] TBD +### [1.7.1-jdk8] 2020.06.09 #### Changed +* Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` * Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). * Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). * Updated `spring-boot-starter-test` version to `2.3.0.RELEASE` (was `2.2.6.RELEASE`). diff --git a/CHANGELOG.md b/CHANGELOG.md index c88d243b4..4b11865d7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ All notable changes to this project will be documented in this file. -### [1.7.2] TBD +### [1.7.2] 2020.06.09 #### Changed +* Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` * Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). * Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). * Updated `spring-boot-starter-test` version to `2.3.0.RELEASE` (was `2.2.6.RELEASE`). From 4eb21c000761b031026741e7a71d85dcb829bb36 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 08:15:04 +0200 Subject: [PATCH 1108/1786] [maven-release-plugin] prepare release 1.7.2 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 3db367f2f..132bb0e55 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index fb982ae71..6e3fac21f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index f6b228da6..0212866ca 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 01b434be4..501c0acc2 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 053914ad7..f796f1a2c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/pom.xml b/pom.xml index 55660114c..7cfb0fdfc 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.2-SNAPSHOT + 1.7.2 pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.7.2 From 8ece1eb925cdb4ba586476c8d46e3a63e1febf83 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 08:15:15 +0200 Subject: [PATCH 1109/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 132bb0e55..2a36cc5d5 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 6e3fac21f..ff0e494bd 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 0212866ca..adffb6e5e 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 501c0acc2..3dd80b22c 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index f796f1a2c..4999a84e1 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index 7cfb0fdfc..9d7afa8c9 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.2 + 1.7.3-SNAPSHOT pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.2 + HEAD From 5a21ce575c9fc5055a9be25c0cac10e68fbcda42 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 08:40:47 +0200 Subject: [PATCH 1110/1786] Skips checkstyle during site generation --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9137f463a..ac05810b5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dcheckstyle.skip=true site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: provider: pages local-dir: target/site From 8660a3e8874ed3993fa10e4e6cd0d115d6243d44 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 08:42:13 +0200 Subject: [PATCH 1111/1786] Prepares release --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 2a36cc5d5..3db367f2f 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3-SNAPSHOT + 1.7.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index ff0e494bd..fb982ae71 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3-SNAPSHOT + 1.7.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index adffb6e5e..f6b228da6 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3-SNAPSHOT + 1.7.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 3dd80b22c..01b434be4 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.3-SNAPSHOT + 1.7.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 4999a84e1..053914ad7 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.3-SNAPSHOT + 1.7.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 9d7afa8c9..55660114c 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.3-SNAPSHOT + 1.7.2-SNAPSHOT pom 2019 From d1a4e0fdf2379f9ea0e5028d8f8749e46692a7fc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 08:44:02 +0200 Subject: [PATCH 1112/1786] [maven-release-plugin] prepare release 1.7.2 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 3db367f2f..132bb0e55 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index fb982ae71..6e3fac21f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index f6b228da6..0212866ca 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 01b434be4..501c0acc2 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 053914ad7..f796f1a2c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.2-SNAPSHOT + 1.7.2 diff --git a/pom.xml b/pom.xml index 55660114c..7cfb0fdfc 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.2-SNAPSHOT + 1.7.2 pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.7.2 From 469be9a06ddeec7375aadf9a8a41a6e2f270c2a4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 08:44:14 +0200 Subject: [PATCH 1113/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 132bb0e55..2a36cc5d5 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 6e3fac21f..ff0e494bd 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 0212866ca..adffb6e5e 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 501c0acc2..3dd80b22c 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index f796f1a2c..4999a84e1 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.2 + 1.7.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index 7cfb0fdfc..9d7afa8c9 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.2 + 1.7.3-SNAPSHOT pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.2 + HEAD From b49206551ed0adb58a3e2d34b83d1778920cd55b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 09:11:35 +0200 Subject: [PATCH 1114/1786] Removes the method: setDefaultValueSetEnabled --- CHANGELOG-JDK8.md | 4 ++++ CHANGELOG.md | 4 ++++ README.md | 2 +- .../transformer/AbstractBeanTransformer.java | 11 +---------- .../beans/transformer/BeanTransformer.java | 9 --------- .../beans/transformer/TransformerImpl.java | 2 +- .../MutableObjectTransformationTest.java | 18 ------------------ .../transformer/model/TransformerSettings.java | 14 +++++++------- docs/site/markdown/transformer/bean/samples.md | 2 +- 9 files changed, 19 insertions(+), 47 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 3a0e8e1f2..8e2ab2d8d 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.7.2-jdk8] 2020.06.09 +#### Changed +* Removes the deprecated method: `setDefaultValueSetEnabled` + ### [1.7.1-jdk8] 2020.06.09 #### Changed * Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b11865d7..d2bb4c53c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.7.3] 2020.06.09 +#### Changed +* Removes the deprecated method: `setDefaultValueSetEnabled` + ### [1.7.2] 2020.06.09 #### Changed * Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` diff --git a/README.md b/README.md index 58e47f376..19e964a3b 100644 --- a/README.md +++ b/README.md @@ -322,7 +322,7 @@ To disable this you can simply do: ```java ToBean toBean = beanUtils.getTransformer() - .setDefaultValueSetEnabled(false).transform(fromBean, ToBean.class); + .setDefaultValueForMissingPrimitiveField(false).transform(fromBean, ToBean.class); ``` in this case the field `id` after the transformation will be `null` diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java index 2c227aef4..7b7702130 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java @@ -67,7 +67,7 @@ public final BeanTransformer setDefaultValueForMissingField(final boolean useDef */ @Override public BeanTransformer setDefaultValueForMissingPrimitiveField(final boolean useDefaultValue) { - settings.setDefaultValueSetEnabled(useDefaultValue); + settings.setDefaultValueForMissingPrimitiveField(useDefaultValue); return this; } @@ -92,15 +92,6 @@ public BeanTransformer setValidationEnabled(final boolean validationEnabled) { return this; } - /** - * {@inheritDoc} - */ - @Override - public BeanTransformer setDefaultValueSetEnabled(final boolean defaultValueSetEnabled) { - setDefaultValueForMissingPrimitiveField(defaultValueSetEnabled); - return this; - } - /** * {@inheritDoc} */ diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index babfa8cb6..0ce51d879 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -88,15 +88,6 @@ public interface BeanTransformer extends Transformer { */ void resetFieldsTransformationSkip(); - /** - * It allows to enable/disable the set of the default value for primitive types in case they are null. - * @param defaultValueSetEnabled if true the default value for the primitive type is set. By default it's true. - * @return the {@link BeanTransformer} instance - * @deprecated use {@link #setDefaultValueForMissingPrimitiveField(boolean) setDefaultValueForMissingPrimitiveField} instead. - */ - @Deprecated(since = "1.7.1", forRemoval = true) - BeanTransformer setDefaultValueSetEnabled(boolean defaultValueSetEnabled); - /** * It allows to enable/disable the automatic conversion of primitive types. * @param primitiveTypeConversionEnabled if true primitive types are transformed automatically. By default it's false. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index c9a2e39da..01b817682 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -428,7 +428,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN && (notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass()))) { fieldValue = getFieldValue(targetClass, field, fieldValue, fieldBreadcrumb); } - } else if (primitiveType && settings.isDefaultValueSetEnabled() && !isTransformerFunctionDefined) { + } else if (primitiveType && settings.isDefaultValueForMissingPrimitiveField() && !isTransformerFunctionDefined) { fieldValue = defaultValue(fieldType); // assign the default value } fieldValue = getTransformedValue(transformerFunction, fieldValue, sourceObj.getClass(), sourceFieldName, field, primitiveType, fieldBreadcrumb); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 330171c81..e073322ad 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -197,24 +197,6 @@ public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeField() { underTest.setDefaultValueForMissingPrimitiveField(true); } - /** - * Test that the transformer does not sets the default value for primitive type field - * in case it's disabled using the deprecated method. - */ - @Test - public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeFieldUsingDeprecatedMethod() { - //GIVEN - FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, null, ACTIVE); - underTest.setDefaultValueSetEnabled(false); - - //WHEN - MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); - - //THEN - assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); - underTest.setDefaultValueSetEnabled(true); - } - /** * Test that the transformer is able to copy object even if the source object has no fields but has getter methods. */ diff --git a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java index b27a9de2b..d65b2148b 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java @@ -61,6 +61,13 @@ public class TransformerSettings { @Setter private boolean setDefaultValueForMissingField; + /** + * It allows to enable/disable the set of the default value for primitive types in case they are null. + * If set to true the default value is set. + */ + @Setter + private boolean defaultValueForMissingPrimitiveField = true; + /** * It allows to apply a transformation to all fields matching with the provided name without using their whole path. * If set to true the transformation function is applied to all fields that have a name matching with the given one without evaluating their full path. @@ -75,13 +82,6 @@ public class TransformerSettings { @Setter private boolean validationEnabled; - /** - * It allows to enable/disable the set of the default value for primitive types in case they are null. - * If set to true the default value is set. - */ - @Setter - private boolean defaultValueSetEnabled = true; - /** * It allows to enable/disable the automatic conversion of primitive types. * If set to true primitive types are transformed automatically. diff --git a/docs/site/markdown/transformer/bean/samples.md b/docs/site/markdown/transformer/bean/samples.md index b52f153d6..08dff474a 100644 --- a/docs/site/markdown/transformer/bean/samples.md +++ b/docs/site/markdown/transformer/bean/samples.md @@ -201,7 +201,7 @@ To disable this you can simply do: ```java ToBean toBean = beanUtils.getTransformer() - .setDefaultValueSetEnabled(false).transform(fromBean, ToBean.class); + .setDefaultValueForMissingPrimitiveField(false).transform(fromBean, ToBean.class); ``` in this case the field `id` after the transformation will be `null` From 59742704778984111d8b475251cb441ca297cbd6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 09:20:58 +0200 Subject: [PATCH 1115/1786] [maven-release-plugin] prepare release 1.7.3 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 2a36cc5d5..69774bd0c 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3-SNAPSHOT + 1.7.3 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index ff0e494bd..7f8d76161 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3-SNAPSHOT + 1.7.3 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index adffb6e5e..4dcd700f0 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3-SNAPSHOT + 1.7.3 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 3dd80b22c..77a16675b 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.3-SNAPSHOT + 1.7.3 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 4999a84e1..2af4cf27e 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.3-SNAPSHOT + 1.7.3 diff --git a/pom.xml b/pom.xml index 9d7afa8c9..0fe4969ba 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.3-SNAPSHOT + 1.7.3 pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.7.3 From a3021b993e9eaf355c0b9710dfc26569cbc6a576 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 Jun 2020 09:21:08 +0200 Subject: [PATCH 1116/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 69774bd0c..c824dcf5c 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3 + 1.7.4-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 7f8d76161..bec8c8f56 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3 + 1.7.4-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 4dcd700f0..1cb027a46 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3 + 1.7.4-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 77a16675b..f57bfd665 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.3 + 1.7.4-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2af4cf27e..e8fbbc799 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.3 + 1.7.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index 0fe4969ba..e7dc5e5b9 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.3 + 1.7.4-SNAPSHOT pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.3 + HEAD From 6342ce3ea0099256a11fcea4aa1bc528fa870699 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jun 2020 12:19:52 +0200 Subject: [PATCH 1117/1786] Replacing Junit and Hamcrest with AssertJ --- bull-bean-transformer/pom.xml | 5 -- .../java/com/hotels/beans/BeanUtilsTest.java | 13 ++---- .../AbstractBeanTransformerTest.java | 13 ++++++ .../transformer/BeanTransformerTest.java | 46 +++++++++---------- .../BuilderObjectTransformationTest.java | 6 +-- .../ImmutableObjectTransformationTest.java | 28 +++++------ .../MixedObjectTransformationTest.java | 30 ++++++------ .../MutableObjectTransformationTest.java | 20 ++++---- bull-map-transformer/pom.xml | 5 -- pom.xml | 32 ++++++------- 10 files changed, 90 insertions(+), 108 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c824dcf5c..0a1e04191 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -25,10 +25,5 @@ test-jar test - - com.shazam - shazamcrest - test - \ No newline at end of file diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java index 9dfc9fe59..34465187c 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -16,12 +16,9 @@ package com.hotels.beans; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; - import java.math.BigInteger; import java.util.Arrays; import java.util.List; @@ -75,7 +72,7 @@ public void testGetTransformerWorksProperly() { final BeanTransformer transformer = underTest.getTransformer(); //THEN - assertNotNull(transformer); + assertThat(transformer).isNotNull(); } /** @@ -106,9 +103,9 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip .collect(Collectors.toList()); //THEN - assertNotNull(transformerFunction); + assertThat(transformerFunction).isNotNull(); IntStream.range(0, actual.size()) - .forEach(i -> assertThat(actual.get(i), sameBeanAs(fromFooSimpleList.get(i)))); + .forEach(i -> assertThat(actual.get(i)).isEqualToComparingFieldByField(fromFooSimpleList.get(i)).usingRecursiveComparison()); } /** @@ -163,7 +160,7 @@ public void testGetPrimitiveTypeConverterWorksProperly() { Converter actual = underTest.getPrimitiveTypeConverter(); //THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index 6cd665c1a..7c8578e9d 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -16,6 +16,7 @@ package com.hotels.beans.transformer; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import org.mockito.InjectMocks; @@ -49,4 +50,16 @@ public void beforeClass() { public void beforeMethod() { initMocks(this); } + + /** + * Asserts that two Java Bean are equals. + * @param actualBean the result bean + * @param expectedBean the expected bean + * @param the bean type + */ + protected void assertBeanEquals(final T actualBean, final T expectedBean) { + assertThat(actualBean) + .isEqualToComparingFieldByField(expectedBean) + .usingRecursiveComparison(); + } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index d5cb638f4..902e2f4b2 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -20,11 +20,7 @@ import static java.math.BigInteger.ZERO; import static java.util.Optional.empty; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; @@ -74,6 +70,7 @@ public class BeanTransformerTest extends AbstractBeanTransformerTest { * Test that is possible to remove a field mapping for a given field. */ @Test + @SuppressWarnings("unchecked") public void testRemoveFieldMappingWorksProperly() { //GIVEN BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); @@ -83,7 +80,7 @@ public void testRemoveFieldMappingWorksProperly() { TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertFalse(transformerSettings.getFieldsNameMapping().containsKey(DEST_FIELD_NAME)); + assertThat(transformerSettings.getFieldsNameMapping()).doesNotContainKey(DEST_FIELD_NAME); } /** @@ -102,6 +99,7 @@ public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { * Test that is possible to remove all the fields mappings defined. */ @Test + @SuppressWarnings("unchecked") public void testResetFieldsMappingWorksProperly() { //GIVEN BeanTransformer beanTransformer = underTest @@ -112,13 +110,14 @@ public void testResetFieldsMappingWorksProperly() { TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertTrue(transformerSettings.getFieldsNameMapping().isEmpty()); + assertThat(transformerSettings.getFieldsNameMapping()).isEmpty(); } /** * Test that is possible to remove all the fields transformer defined. */ @Test + @SuppressWarnings("unchecked") public void testResetFieldsTransformerWorksProperly() { //GIVEN BeanTransformer beanTransformer = underTest @@ -129,13 +128,14 @@ public void testResetFieldsTransformerWorksProperly() { TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertTrue(transformerSettings.getFieldsTransformers().isEmpty()); + assertThat(transformerSettings.getFieldsTransformers()).isEmpty(); } /** * Test that is possible to remove a field transformer for a given field. */ @Test + @SuppressWarnings("unchecked") public void testRemoveFieldTransformerWorksProperly() { //GIVEN BeanTransformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); @@ -145,7 +145,7 @@ public void testRemoveFieldTransformerWorksProperly() { TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertFalse(transformerSettings.getFieldsTransformers().containsKey(DEST_FIELD_NAME)); + assertThat(transformerSettings.getFieldsTransformers()).doesNotContainKey(DEST_FIELD_NAME); } /** @@ -207,8 +207,8 @@ public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined //THEN verify(reflectionUtils).getFieldValue(FromFooSimple.class, AGE_FIELD_NAME, fieldType); verify(field).getType(); - assertNull(raisedException); - assertNull(actual); + assertThat(raisedException).isNull(); + assertThat(actual).isNull(); restoreUnderTestObject(); } @@ -224,7 +224,7 @@ public void testThatPrimitiveTypeConversionIsCorrectlyEnabled() { boolean actual = underTest.getSettings().isPrimitiveTypeConversionEnabled(); //THEN - assertTrue(actual); + assertThat(actual).isTrue(); underTest.setPrimitiveTypeConversionEnabled(false); } @@ -258,7 +258,7 @@ public void testGetSourceFieldTypeReturnsTheSourceObjectClass() throws Exception verify(cacheManager).getFromCache(anyString(), any(Class.class)); verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, Integer.class); verify(classUtils).isPrimitiveType(Integer.class); - assertEquals(Integer.class, actual); + assertThat(actual).isEqualTo(Integer.class); restoreUnderTestObject(); } @@ -297,7 +297,7 @@ public void testGetSourceFieldTypeReturnsNull() throws Exception { verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); verify(classUtils).isPrimitiveType(FromFooSimple.class); verify(settings).isSetDefaultValueForMissingField(); - assertNull(actual); + assertThat(actual).isNull(); restoreUnderTestObject(); } @@ -340,8 +340,8 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); verify(classUtils).isPrimitiveType(FromFooSimple.class); verify(settings).isSetDefaultValueForMissingField(); - assertNotNull(raisedException); - assertEquals(MissingFieldException.class, raisedException.getCause().getClass()); + assertThat(raisedException).isNotNull(); + assertThat(raisedException.getCause().getClass()).isEqualTo(MissingFieldException.class); restoreUnderTestObject(); } @@ -375,7 +375,7 @@ public void testGetTransformedValueWorksProperly(final String testCaseDescriptio .invoke(underTest, fieldTransformer, fieldValue, FromFooSimple.class, fieldName, field, isDestinationFieldPrimitiveType, fieldName); //THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); restoreUnderTestObject(); } @@ -427,8 +427,8 @@ public void testGetConstructorArgsValuesReturnsTheDefaultTypeIfTheDestinationFie verify(constructorParameter, times(2)).getName(); verify(constructorParameter).getType(); verify(classUtils).getDefaultTypeValue(Integer.class); - assertEquals(ONE.intValue(), actual.length); - assertEquals(ZERO.intValue(), actual[ZERO.intValue()]); + assertThat(actual.length).isEqualTo(ONE.intValue()); + assertThat(actual[ZERO.intValue()]).isEqualTo(ZERO.intValue()); restoreUnderTestObject(); } @@ -453,7 +453,7 @@ public void testValidatorIsInitializedOnlyIfValidationIsEnabled(final String tes underTest.setValidationEnabled(validationEnabled); // THEN - assertEquals(expectedNull, underTest.validator == null); + assertThat(underTest.validator == null).isEqualTo(expectedNull); underTest.setValidationEnabled(false); } @@ -483,7 +483,7 @@ public void testConversionAnalyzerIsInitializedOnlyIfValidationIsEnabled(final S underTest.setPrimitiveTypeConversionEnabled(autoConversionEnabled); // THEN - assertEquals(expectedNull, underTest.conversionAnalyzer == null); + assertThat(underTest.conversionAnalyzer == null).isEqualTo(expectedNull); underTest.setPrimitiveTypeConversionEnabled(false); } @@ -529,8 +529,8 @@ public void testHandleInjectionExceptionWorksAsExpected(final String testCaseDes } //THEN - assertNotNull(actual); - assertEquals(expectedReturnType, actual.getClass()); + assertThat(actual).isNotNull(); + assertThat(actual.getClass()).isEqualTo(expectedReturnType); restoreUnderTestObject(); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index d56717358..a5a85586a 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -16,10 +16,6 @@ package com.hotels.beans.transformer; -import static org.hamcrest.MatcherAssert.assertThat; - -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; - import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -47,7 +43,7 @@ public void testTransformationThroughBuilder(final String testDescription, final Object actual = underTest.transform(sourceObject, targetObjectClass); //THEN - assertThat(actual, sameBeanAs(sourceObject)); + assertBeanEquals(actual, sourceObject); underTest.setCustomBuilderTransformationEnabled(false); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 487c7d167..62ccbd52b 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -18,9 +18,7 @@ import static java.lang.String.format; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasProperty; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -30,8 +28,6 @@ import static org.mockito.Mockito.when; import static org.springframework.test.util.ReflectionTestUtils.setField; -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; - import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -110,7 +106,7 @@ public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, Object actual = transformer.transform(sourceObject, targetObjectClass); //THEN - assertThat(actual, sameBeanAs(sourceObject)); + assertBeanEquals(actual, sourceObject); } /** @@ -145,7 +141,7 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { underTest.setValidationEnabled(true).transform(fromFooSimple, immutableToFoo); //THEN - assertThat(immutableToFoo, sameBeanAs(fromFooSimple)); + assertBeanEquals(immutableToFoo, fromFooSimple); underTest.setValidationEnabled(false); } @@ -171,9 +167,9 @@ public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(f ImmutableFlatToFoo actual = underTestMock.withFieldMapping(phoneNumbersMapping).transform(sourceObject, ImmutableFlatToFoo.class); //THEN - assertEquals(expectedName, actual.getName()); - assertEquals(expectedId, actual.getId()); - assertEquals(expectedPhoneNumbers, actual.getPhoneNumbers()); + assertThat(actual.getName()).isEqualTo(expectedName); + assertThat(actual.getId()).isEqualTo(expectedId); + assertThat(actual.getPhoneNumbers()).isEqualTo(expectedPhoneNumbers); } /** @@ -244,7 +240,7 @@ public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotVali ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); // THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertBeanEquals(actual, fromFoo); fromFoo.setId(ID); } @@ -260,12 +256,12 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); //THEN - assertThat(actual, hasProperty(NAME_FIELD_NAME, equalTo(actual.getName()))); - assertThat(actual, hasProperty(IDENTIFIER_FIELD_NAME, equalTo(fromFoo.getId()))); + assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, actual.getName()); + assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()); assertEquals(actual.getList(), fromFoo.getList()); IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); - assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); + .forEach(i -> assertBeanEquals(actual.getNestedObjectList().get(i), fromFoo.getNestedObjectList().get(i))); + assertBeanEquals(actual.getNestedObject(), fromFoo.getNestedObject()); } /** @@ -449,7 +445,7 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor ImmutableToFooNotExistingFields immutableObjectBean = underTest.transform(fromFooSimple, ImmutableToFooNotExistingFields.class); //THEN - assertThat(immutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + assertThat(immutableObjectBean).hasFieldOrPropertyWithValue(AGE_FIELD_NAME, AGE); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 74f5d3dfb..283dc6784 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -16,14 +16,10 @@ package com.hotels.beans.transformer; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasProperty; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; - import java.math.BigInteger; import java.util.stream.IntStream; @@ -56,7 +52,7 @@ public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { MixedToFooMissingAllArgsConstructor actual = underTest.transform(fromFoo, MixedToFooMissingAllArgsConstructor.class); //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertBeanEquals(actual, fromFoo); } /** @@ -70,7 +66,7 @@ public void testMixedBeanIsCorrectlyCopied() { MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertBeanEquals(actual, fromFoo); } /** @@ -85,12 +81,12 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); //THEN - assertThat(actual, hasProperty(NAME_FIELD_NAME, equalTo(actual.getName()))); - assertThat(actual, hasProperty(IDENTIFIER_FIELD_NAME, equalTo(fromFoo.getId()))); + assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, fromFoo.getName()); + assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()); assertEquals(actual.getList(), fromFoo.getList()); IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); - assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); + .forEach(i -> assertBeanEquals(actual.getNestedObjectList().get(i), fromFoo.getNestedObjectList().get(i))); + assertBeanEquals(actual.getNestedObject(), fromFoo.getNestedObject()); } /** @@ -110,12 +106,12 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTra MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); //THEN - assertThat(actual, hasProperty(NAME_FIELD_NAME, equalTo(actual.getName()))); - assertThat(actual, hasProperty(IDENTIFIER_FIELD_NAME, equalTo(fromFoo.getId().negate()))); + assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, fromFoo.getName()); + assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId().negate()); assertEquals(actual.getList(), fromFoo.getList()); IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i), sameBeanAs(fromFoo.getNestedObjectList().get(i)))); - assertThat(actual.getNestedObject(), sameBeanAs(fromFoo.getNestedObject())); + .forEach(i -> assertBeanEquals(actual.getNestedObjectList().get(i), fromFoo.getNestedObjectList().get(i))); + assertBeanEquals(actual.getNestedObject(), fromFoo.getNestedObject()); } /** @@ -159,7 +155,7 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor MixedToFooNotExistingFields mixedObjectBean = underTest.transform(fromFooSimple, MixedToFooNotExistingFields.class); //THEN - assertThat(mixedObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + assertThat(mixedObjectBean).hasFieldOrPropertyWithValue(AGE_FIELD_NAME, AGE); } /** @@ -192,6 +188,6 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { underTest.skipTransformationForField().transform(fromFoo, mixedToFoo); //THEN - assertThat(mixedToFoo, sameBeanAs(fromFoo)); + assertBeanEquals(mixedToFoo, fromFoo); } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index e073322ad..a5a29c574 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -18,9 +18,7 @@ import static java.lang.Integer.parseInt; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasProperty; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -33,8 +31,6 @@ import static org.mockito.Mockito.when; import static org.springframework.test.util.ReflectionTestUtils.setField; -import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; - import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -88,7 +84,7 @@ public void testMutableBeanIsCorrectlyCopied() { MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); //THEN - assertThat(actual, sameBeanAs(fromFoo)); + assertBeanEquals(actual, fromFoo); } /** @@ -103,7 +99,7 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { underTest.transform(fromFooSubClass, mutableToFoo); //THEN - assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); + assertBeanEquals(mutableToFoo, fromFooSubClass); } /** @@ -119,7 +115,7 @@ public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotVali underTest.transform(fromFooSubClass, mutableToFoo); //THEN - assertThat(mutableToFoo, sameBeanAs(fromFooSubClass)); + assertBeanEquals(mutableToFoo, fromFooSubClass); fromFooSubClass.setId(ID); } @@ -177,7 +173,7 @@ public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); //THEN - assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); + assertBeanEquals(actual, fromFooSimpleNoGetters); } /** @@ -193,7 +189,7 @@ public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeField() { MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); //THEN - assertThat(actual, sameBeanAs(fromFooSimpleNoGetters)); + assertBeanEquals(actual, fromFooSimpleNoGetters); underTest.setDefaultValueForMissingPrimitiveField(true); } @@ -228,7 +224,7 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor MutableToFooNotExistingFields mutableObjectBean = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); //THEN - assertThat(mutableObjectBean, hasProperty(AGE_FIELD_NAME, equalTo(AGE))); + assertThat(mutableObjectBean).hasFieldOrPropertyWithValue(AGE_FIELD_NAME, AGE); underTest.resetFieldsTransformer(); } @@ -292,7 +288,7 @@ public void testTransformationWithFieldTransformationWorksProperly(final String MutableToFooSimple actual = underTest.transform(fromFooSimple, MutableToFooSimple.class); //THEN - assertThat(actual, hasProperty(fieldToTransform, equalTo(transformationResult))); + assertThat(actual).hasFieldOrPropertyWithValue(fieldToTransform, transformationResult); underTest.removeFieldTransformer(fieldToTransform); } diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f57bfd665..a61160e60 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -31,10 +31,5 @@ test-jar test - - com.shazam - shazamcrest - test - \ No newline at end of file diff --git a/pom.xml b/pom.xml index e7dc5e5b9..51ee52863 100644 --- a/pom.xml +++ b/pom.xml @@ -52,10 +52,10 @@ 2.3.0.RELEASE 1.18.12 3.10 - 0.11 2.8.6 7.1.0 3.3.3 + 3.16.1 1.3.0 2.0.1.Final @@ -147,6 +147,14 @@ org.mockito mockito-core + + org.hamcrest + hamcrest + + + + + @@ -155,22 +163,6 @@ ${slf4j-api.version} test - - com.shazam - shazamcrest - ${shazamcrest.version} - test - - - org.skyscreamer - jsonassert - - - junit - junit - - - com.google.code.gson gson @@ -199,6 +191,12 @@ ${mockito-core.version} test + + org.assertj + assertj-core + ${assertj-core.version} + test + From c0f560ceafeb323e8a977037cc2a09456e8ce912 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jun 2020 16:17:36 +0200 Subject: [PATCH 1118/1786] Replaces all the Junit asserts with AssertJ --- .../beans/performance/PerformanceTest.java | 6 +- .../beans/populator/ArrayPopulatorTest.java | 13 ++- .../beans/populator/PopulatorFactoryTest.java | 6 +- .../AbstractBeanTransformerTest.java | 13 --- .../BuilderObjectTransformationTest.java | 4 +- .../ImmutableObjectTransformationTest.java | 56 +++++------ .../MixedObjectTransformationTest.java | 28 +++--- .../MutableObjectTransformationTest.java | 64 ++++++------ .../hotels/transformer/base/DefaultsTest.java | 4 +- .../cache/CacheManagerFactoryTest.java | 4 +- .../transformer/cache/CacheManagerTest.java | 21 ++-- .../transformer/utils/ClassUtilsTest.java | 73 +++++++------- .../utils/ReflectionUtilsTest.java | 97 +++++++++---------- .../beans/conversion/ConverterTest.java | 14 ++- .../analyzer/ConversionAnalyzerTest.java | 9 +- .../ConversionProcessorFactoryTest.java | 9 +- .../impl/BigDecimalConversionTest.java | 26 ++--- .../impl/BigIntegerConversionTest.java | 26 ++--- .../processor/impl/BooleanConversionTest.java | 28 +++--- .../impl/ByteArrayConversionTest.java | 26 ++--- .../processor/impl/ByteConversionTest.java | 26 ++--- .../impl/CharacterConversionTest.java | 26 ++--- .../processor/impl/DoubleConversionTest.java | 27 +++--- .../processor/impl/FloatConversionTest.java | 27 +++--- .../processor/impl/IntegerConversionTest.java | 26 ++--- .../processor/impl/LongConversionTest.java | 26 ++--- .../processor/impl/ShortConversionTest.java | 26 ++--- .../processor/impl/StringConversionTest.java | 26 ++--- .../map/transformer/MapTransformerTest.java | 12 +-- .../site/markdown/transformer/bean/testing.md | 6 +- pom.xml | 8 +- 31 files changed, 362 insertions(+), 401 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java index d14ce32d3..2483a2415 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -21,7 +21,7 @@ import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -128,7 +128,9 @@ public void testCopyPropertiesGetsCompletedInTheExpectedTime(final double totalT //THEN log.info("Object: {}, Average transformation time: {} ms", destObjectClass, avgTransformationTime); - assertTrue("Performance degradation! Expected: " + maxTransformationTime + ", actual: " + avgTransformationTime, avgTransformationTime <= maxTransformationTime); + assertThat(avgTransformationTime) + .as("Performance degradation! Expected: %s, actual: %s", maxTransformationTime, avgTransformationTime) + .isLessThanOrEqualTo(maxTransformationTime); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 9a424be96..743debd5a 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -19,8 +19,7 @@ import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -83,18 +82,18 @@ public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, // THEN if (genericFieldType == Character.class) { - assertArrayEquals((char[]) array, (char[]) actual); + assertThat((char[]) actual).isEqualTo((char[]) array); } else if (genericFieldType == Integer.class) { - assertArrayEquals((int[]) array, (int[]) actual); + assertThat((int[]) actual).isEqualTo((int[]) array); } else if (genericFieldType == Object.class) { - assertArrayEquals((Object[]) array, (Object[]) actual); + assertThat((Object[]) actual).isEqualTo(array); } else if (genericFieldType == MixedToFooStaticField.class) { final MixedToFooStaticField[] expectedArray = (MixedToFooStaticField[]) array; final Object[] actualArray = (Object[]) actual; IntStream.range(0, expectedArray.length) - .forEach(i -> assertEquals(expectedArray[i].getNormalField(), ((MixedToFooStaticField) actualArray[i]).getNormalField())); + .forEach(i -> assertThat(((MixedToFooStaticField) actualArray[i]).getNormalField()).isEqualTo(expectedArray[i].getNormalField())); } else { - assertArrayEquals((Object[]) array, (Object[]) actual); + assertThat((Object[]) actual).isEqualTo(array); } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index 6f9246d01..4bf9816dc 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -18,7 +18,7 @@ import static java.util.Objects.nonNull; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.util.List; @@ -88,9 +88,9 @@ public void testGetPopulatorReturnsTheExpectedResult(final Class type, final Cla // THEN final boolean isNonNullObjectExpected = nonNull(expectedResult); - assertEquals(populator.isPresent(), isNonNullObjectExpected); + assertThat(populator.isPresent()).isEqualTo(isNonNullObjectExpected); if (isNonNullObjectExpected) { - assertEquals(expectedResult, populator.get().getClass()); + assertThat(populator.get().getClass()).isEqualTo(expectedResult); } } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index 7c8578e9d..6cd665c1a 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -16,7 +16,6 @@ package com.hotels.beans.transformer; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import org.mockito.InjectMocks; @@ -50,16 +49,4 @@ public void beforeClass() { public void beforeMethod() { initMocks(this); } - - /** - * Asserts that two Java Bean are equals. - * @param actualBean the result bean - * @param expectedBean the expected bean - * @param the bean type - */ - protected void assertBeanEquals(final T actualBean, final T expectedBean) { - assertThat(actualBean) - .isEqualToComparingFieldByField(expectedBean) - .usingRecursiveComparison(); - } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index a5a85586a..8f50fd51f 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -16,6 +16,8 @@ package com.hotels.beans.transformer; +import static org.assertj.core.api.Assertions.assertThat; + import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -43,7 +45,7 @@ public void testTransformationThroughBuilder(final String testDescription, final Object actual = underTest.transform(sourceObject, targetObjectClass); //THEN - assertBeanEquals(actual, sourceObject); + assertThat(actual).usingRecursiveComparison().isEqualTo(sourceObject); underTest.setCustomBuilderTransformationEnabled(false); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 62ccbd52b..7956fcf19 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -19,10 +19,6 @@ import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -106,7 +102,7 @@ public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, Object actual = transformer.transform(sourceObject, targetObjectClass); //THEN - assertBeanEquals(actual, sourceObject); + assertThat(actual).usingRecursiveComparison().isEqualTo(sourceObject); } /** @@ -141,7 +137,7 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { underTest.setValidationEnabled(true).transform(fromFooSimple, immutableToFoo); //THEN - assertBeanEquals(immutableToFoo, fromFooSimple); + assertThat(immutableToFoo).usingRecursiveComparison().isEqualTo(fromFooSimple); underTest.setValidationEnabled(false); } @@ -240,7 +236,7 @@ public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotVali ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); // THEN - assertBeanEquals(actual, fromFoo); + assertThat(actual).usingRecursiveComparison().isEqualTo(fromFoo); fromFoo.setId(ID); } @@ -258,10 +254,10 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { //THEN assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, actual.getName()); assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()); - assertEquals(actual.getList(), fromFoo.getList()); + assertThat(actual.getList()).usingRecursiveComparison().isEqualTo(fromFoo.getList()); IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertBeanEquals(actual.getNestedObjectList().get(i), fromFoo.getNestedObjectList().get(i))); - assertBeanEquals(actual.getNestedObject(), fromFoo.getNestedObject()); + .forEach(i -> assertThat(actual.getNestedObjectList().get(i)).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObjectList().get(i))); + assertThat(actual.getNestedObject()).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObject()); } /** @@ -285,13 +281,13 @@ public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String te ImmutableToFooAdvFields actual = (ImmutableToFooAdvFields) beanTransformer.transform(sourceObject, targetObjectClass); //THEN - assertNotNull(actual.getName()); - assertEquals(isNameFieldEmpty, actual.getName().isPresent()); - sourceObject.getName().ifPresent(name -> assertEquals(name, actual.getName().get())); - assertTrue(sourceObject.getAge().isPresent()); - assertEquals(sourceObject.getAge().get(), actual.getAge()); - assertEquals(sourceObject.getClassType(), actual.getClassType()); - assertEquals(sourceObject.getLocale(), actual.getLocale().getLanguage()); + assertThat(actual).isNotNull(); + assertThat(actual.getName().isPresent()).isEqualTo(isNameFieldEmpty); + sourceObject.getName().ifPresent(name -> assertThat(actual.getName().get()).isEqualTo(name)); + assertThat(sourceObject.getAge().isPresent()).isTrue(); + assertThat(actual.getAge()).isEqualTo(sourceObject.getAge().get()); + assertThat(actual.getClassType()).isEqualTo(sourceObject.getClassType()); + assertThat(actual.getLocale().getLanguage()).isEqualTo(sourceObject.getLocale()); } /** @@ -321,8 +317,8 @@ public void testImmutableBeanWithMissingConstructorArgIsCorrectlyCopied() { ImmutableToFooMissingCustomAnnotation actual = underTest.withFieldTransformer().transform(fromFooWithPrimitiveFields, ImmutableToFooMissingCustomAnnotation.class); //THEN - assertNotNull(actual); - assertEquals(fromFooWithPrimitiveFields.getName(), actual.getName()); + assertThat(actual).isNotNull(); + assertThat(actual.getName()).isEqualTo(fromFooWithPrimitiveFields.getName()); } /** @@ -346,7 +342,7 @@ public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNot String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); //THEN - assertEquals(DEST_FIELD_NAME, actual); + assertThat(actual).isEqualTo(DEST_FIELD_NAME); // restore modified objects restoreObjects(getDestFieldNameMethod); @@ -368,8 +364,8 @@ public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { Object[] actual = (Object[]) getConstructorValuesFromFieldsMethod.invoke(underTest, fromFooAdvFields, ImmutableToFooAdvFields.class, ""); //THEN - assertNotNull(actual); - assertEquals(TOTAL_ADV_CLASS_FIELDS, actual.length); + assertThat(actual).isNotNull(); + assertThat(actual.length).isEqualTo(TOTAL_ADV_CLASS_FIELDS); // restore modified objects restoreObjects(getConstructorValuesFromFieldsMethod); @@ -396,7 +392,7 @@ public void testGetDestFieldNameReturnsNullIfConstructorParamHasNoNameProvidedFr String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); //THEN - assertEquals(DEST_FIELD_NAME, actual); + assertThat(actual).isEqualTo(DEST_FIELD_NAME); // restore modified objects restoreObjects(getDestFieldNameMethod); @@ -426,9 +422,9 @@ public void testTransformationReturnsAMeaningfulException() { } //THEN - assertNotNull(raisedException); - assertEquals(InvalidBeanException.class, raisedException.getClass()); - assertEquals(expectedExceptionMessage, raisedException.getMessage()); + assertThat(raisedException).isNotNull(); + assertThat(raisedException.getClass()).isEqualTo(InvalidBeanException.class); + assertThat(raisedException.getMessage()).isEqualTo(expectedExceptionMessage); } /** @@ -460,9 +456,9 @@ public void testFieldTransformationSkipWorksProperly() { ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); //THEN - assertEquals(fromFoo.getId(), actual.getId()); - assertNull(actual.getName()); - assertNull(actual.getNestedObject().getPhoneNumbers()); + assertThat(actual.getId()).isEqualTo(fromFoo.getId()); + assertThat(actual.getName()).isNull(); + assertThat(actual.getNestedObject().getPhoneNumbers()).isNull(); underTest.resetFieldsTransformationSkip(); } @@ -482,7 +478,7 @@ public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); //THEN - assertTrue(actual.getWork()); + assertThat(actual.getWork()).isTrue(); underTest.resetFieldsTransformer(); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 283dc6784..952733083 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -17,8 +17,6 @@ package com.hotels.beans.transformer; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import java.math.BigInteger; import java.util.stream.IntStream; @@ -52,7 +50,7 @@ public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { MixedToFooMissingAllArgsConstructor actual = underTest.transform(fromFoo, MixedToFooMissingAllArgsConstructor.class); //THEN - assertBeanEquals(actual, fromFoo); + assertThat(actual).usingRecursiveComparison().isEqualTo(fromFoo); } /** @@ -66,7 +64,7 @@ public void testMixedBeanIsCorrectlyCopied() { MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); //THEN - assertBeanEquals(actual, fromFoo); + assertThat(actual).usingRecursiveComparison().isEqualTo(fromFoo); } /** @@ -83,10 +81,10 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { //THEN assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, fromFoo.getName()); assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()); - assertEquals(actual.getList(), fromFoo.getList()); + assertThat(actual.getList()).usingRecursiveComparison().isEqualTo(fromFoo.getList()); IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertBeanEquals(actual.getNestedObjectList().get(i), fromFoo.getNestedObjectList().get(i))); - assertBeanEquals(actual.getNestedObject(), fromFoo.getNestedObject()); + .forEach(i -> assertThat(actual.getNestedObjectList().get(i)).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObjectList().get(i))); + assertThat(actual.getNestedObject()).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObject()); } /** @@ -108,10 +106,10 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTra //THEN assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, fromFoo.getName()); assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId().negate()); - assertEquals(actual.getList(), fromFoo.getList()); + assertThat(actual.getList()).usingRecursiveComparison().isEqualTo(fromFoo.getList()); IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertBeanEquals(actual.getNestedObjectList().get(i), fromFoo.getNestedObjectList().get(i))); - assertBeanEquals(actual.getNestedObject(), fromFoo.getNestedObject()); + .forEach(i -> assertThat(actual.getNestedObjectList().get(i)).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObjectList().get(i))); + assertThat(actual.getNestedObject()).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObject()); } /** @@ -125,7 +123,7 @@ public void testMixedBeanWithMissingFieldsReturnsTheDefaultValueWhenTheSourceObj //WHEN MixedToFooMissingField actual = underTest.transform(fromFoo, MixedToFooMissingField.class); - assertNull(actual.getFooField()); + assertThat(actual.getFooField()).isNull(); underTest.setDefaultValueForMissingField(false); } @@ -170,9 +168,9 @@ public void testFieldTransformationSkipWorksProperly() { MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); //THEN - assertEquals(fromFoo.getId(), actual.getId()); - assertNull(actual.getName()); - assertNull(actual.getNestedObject().getPhoneNumbers()); + assertThat(actual.getId()).isEqualTo(fromFoo.getId()); + assertThat(actual.getName()).isNull(); + assertThat(actual.getNestedObject().getPhoneNumbers()).isNull(); underTest.resetFieldsTransformationSkip(); } @@ -188,6 +186,6 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { underTest.skipTransformationForField().transform(fromFoo, mixedToFoo); //THEN - assertBeanEquals(mixedToFoo, fromFoo); + assertThat(mixedToFoo).usingRecursiveComparison().isEqualTo(fromFoo); } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index a5a29c574..40f5f1f42 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -19,10 +19,6 @@ import static java.lang.Integer.parseInt; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doReturn; @@ -84,7 +80,7 @@ public void testMutableBeanIsCorrectlyCopied() { MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); //THEN - assertBeanEquals(actual, fromFoo); + assertThat(actual).usingRecursiveComparison().isEqualTo(fromFoo); } /** @@ -99,7 +95,7 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { underTest.transform(fromFooSubClass, mutableToFoo); //THEN - assertBeanEquals(mutableToFoo, fromFooSubClass); + assertThat(mutableToFoo).usingRecursiveComparison().isEqualTo(fromFooSubClass); } /** @@ -115,7 +111,7 @@ public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotVali underTest.transform(fromFooSubClass, mutableToFoo); //THEN - assertBeanEquals(mutableToFoo, fromFooSubClass); + assertThat(mutableToFoo).usingRecursiveComparison().isEqualTo(fromFooSubClass); fromFooSubClass.setId(ID); } @@ -134,8 +130,8 @@ public void testFieldTransformationIsAppliedOnlyToASpecificField() { .transform(fromFoo, MutableToFoo.class); //THEN - assertEquals(fromFoo.getName(), actual.getName()); - assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); + assertThat(actual.getName()).isEqualTo(fromFoo.getName()); + assertThat(actual.getNestedObject().getName()).isEqualTo(namePrefix + fromFoo.getNestedObject().getName()); underTest.resetFieldsTransformer(); } @@ -155,8 +151,8 @@ public void testFieldTransformationIsAppliedToAllMatchingFields() { .transform(fromFoo, MutableToFoo.class); //THEN - assertEquals(namePrefix + fromFoo.getName(), actual.getName()); - assertEquals(namePrefix + fromFoo.getNestedObject().getName(), actual.getNestedObject().getName()); + assertThat(actual.getName()).isEqualTo(namePrefix + fromFoo.getName()); + assertThat(actual.getNestedObject().getName()).isEqualTo(namePrefix + fromFoo.getNestedObject().getName()); underTest.resetFieldsTransformer(); } @@ -173,7 +169,7 @@ public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); //THEN - assertBeanEquals(actual, fromFooSimpleNoGetters); + assertThat(actual).usingRecursiveComparison().isEqualTo(fromFooSimpleNoGetters); } /** @@ -189,7 +185,7 @@ public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeField() { MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); //THEN - assertBeanEquals(actual, fromFooSimpleNoGetters); + assertThat(actual).usingRecursiveComparison().isEqualTo(fromFooSimpleNoGetters); underTest.setDefaultValueForMissingPrimitiveField(true); } @@ -205,9 +201,9 @@ public void testTransformerIsAbleToCopyObjectsWithoutFieldButWithGetterMethods() MutableToFooSimpleNoSetters actual = underTest.transform(fromFooNoField, MutableToFooSimpleNoSetters.class); //THEN - assertEquals(actual.getId(), fromFooNoField.getId()); - assertEquals(actual.getName(), fromFooNoField.getName()); - assertEquals(actual.isActive(), fromFooNoField.isActive()); + assertThat(actual.getId()).isEqualTo(fromFooNoField.getId()); + assertThat(actual.getName()).isEqualTo(fromFooNoField.getName()); + assertThat(actual.isActive()).isEqualTo(fromFooNoField.isActive()); } /** @@ -247,8 +243,8 @@ public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeCo } //THEN - assertNotNull(raisedException); - assertEquals(MissingFieldException.class, raisedException.getCause().getClass()); + assertThat(raisedException).isNotNull(); + assertThat(raisedException.getCause().getClass()).isEqualTo(MissingFieldException.class); underTest.setPrimitiveTypeConversionEnabled(false); } @@ -266,8 +262,8 @@ public void testTransformerDoesNotThrowExceptionIfAFieldIsMissingAndTheDefaultVa MutableToFooNotExistingFields actual = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); //THEN - assertEquals(actual.getId(), fromFooSimple.getId()); - assertEquals(actual.getName(), fromFooSimple.getName()); + assertThat(actual.getId()).isEqualTo(fromFooSimple.getId()); + assertThat(actual.getName()).isEqualTo(fromFooSimple.getName()); underTest.setPrimitiveTypeConversionEnabled(false).setDefaultValueForMissingField(false); } @@ -318,9 +314,9 @@ public void testFieldTransformationSkipWorksProperly() { MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); //THEN - assertEquals(fromFoo.getId(), actual.getId()); - assertNull(actual.getName()); - assertNull(actual.getNestedObject().getPhoneNumbers()); + assertThat(actual.getId()).isEqualTo(fromFoo.getId()); + assertThat(actual.getName()).isNull(); + assertThat(actual.getNestedObject().getPhoneNumbers()).isNull(); underTest.resetFieldsTransformationSkip(); } @@ -330,17 +326,16 @@ public void testFieldTransformationSkipWorksProperly() { @Test public void testAutomaticPrimitiveTypeTransformationWorksProperly() { //GIVEN - double delta = 0d; underTest.setPrimitiveTypeConversionEnabled(true); //WHEN MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); //THEN - assertEquals(parseInt(fromFooPrimitiveTypes.getCode()), actual.getCode()); - assertEquals(String.valueOf(fromFooPrimitiveTypes.getId()), actual.getId()); - assertEquals(Float.valueOf(fromFooPrimitiveTypes.getPrice()).doubleValue(), actual.getPrice(), delta); - assertEquals(ACTIVE, actual.isActive()); + assertThat(actual.getCode()).isEqualTo(parseInt(fromFooPrimitiveTypes.getCode())); + assertThat(actual.getId()).isEqualTo(String.valueOf(fromFooPrimitiveTypes.getId())); + assertThat(actual.getPrice()).isEqualTo(Double.valueOf(fromFooPrimitiveTypes.getPrice())); + assertThat(actual.isActive()).isEqualTo(ACTIVE); underTest.setPrimitiveTypeConversionEnabled(false); } @@ -350,7 +345,6 @@ public void testAutomaticPrimitiveTypeTransformationWorksProperly() { @Test public void testThatBothPrimitiveTypeTransformationAndCustomTransformationAreExecuted() { //GIVEN - double delta = 0d; double newPrice = PRICE * PRICE; FieldTransformer priceTransformer = new FieldTransformer<>(PRICE_FIELD_NAME, () -> newPrice); underTest.setPrimitiveTypeConversionEnabled(true).withFieldTransformer(priceTransformer); @@ -359,10 +353,10 @@ public void testThatBothPrimitiveTypeTransformationAndCustomTransformationAreExe MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); //THEN - assertEquals(parseInt(fromFooPrimitiveTypes.getCode()), actual.getCode()); - assertEquals(String.valueOf(fromFooPrimitiveTypes.getId()), actual.getId()); - assertEquals(newPrice, actual.getPrice(), delta); - assertEquals(ACTIVE, actual.isActive()); + assertThat(actual.getCode()).isEqualTo(parseInt(fromFooPrimitiveTypes.getCode())); + assertThat(actual.getId()).isEqualTo(String.valueOf(fromFooPrimitiveTypes.getId())); + assertThat(actual.isActive()).isEqualTo(ACTIVE); + assertThat(actual.getPrice()).isEqualTo(newPrice); underTest.setPrimitiveTypeConversionEnabled(false); underTest.removeFieldTransformer(PRICE_FIELD_NAME); } @@ -391,7 +385,7 @@ public void testInjectValuesThrowsException() throws Exception { Object actual = injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); // THEN - assertNotNull(actual); - assertSame(expectedException, actual); + assertThat(actual).isNotNull(); + assertThat(actual).isSameAs(expectedException); } } diff --git a/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java b/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java index f3baac6ac..9b405c9bf 100644 --- a/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java @@ -18,7 +18,7 @@ import static java.lang.Boolean.FALSE; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import org.mockito.InjectMocks; import org.testng.annotations.DataProvider; @@ -49,7 +49,7 @@ public void testDefaultValueShouldReturnTheExpectedResult(final Class type, f final Object actual = underTest.defaultValue(type); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java index f844ab820..2d87f8f13 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java @@ -16,7 +16,7 @@ package com.hotels.transformer.cache; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import org.mockito.InjectMocks; @@ -68,6 +68,6 @@ public void testGetCacheReturnsACacheManagerInstance() { final CacheManager actual = underTest.getCacheManager(CACHE_NAME); // THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); } } diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java index 590f9eb8b..f56b7992b 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java @@ -16,10 +16,7 @@ package com.hotels.transformer.cache; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; @@ -62,9 +59,9 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertTrue(actual.isPresent()); - assertEquals(CACHED_OBJECT_CLASS, actual.get().getClass()); - assertSame(VALUE, actual.get()); + assertThat(actual).isPresent(); + assertThat(actual.get().getClass()).isEqualTo(CACHED_OBJECT_CLASS); + assertThat(actual.get()).isSameAs(VALUE); } /** @@ -79,9 +76,9 @@ public void testCacheObjectStoresTheDefaultValueIfTheGivenObjectIsNull() { Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertTrue(actual.isPresent()); - assertEquals(CACHED_OBJECT_CLASS, actual.get().getClass()); - assertSame(DEFAULT_VALUE, actual.get()); + assertThat(actual).isPresent(); + assertThat(actual.get().getClass()).isEqualTo(CACHED_OBJECT_CLASS); + assertThat(actual.get()).isSameAs(DEFAULT_VALUE); } /** @@ -97,7 +94,7 @@ public void testRemoveFromCacheRemovesTheObject() { Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertFalse(actual.isPresent()); + assertThat(actual).isNotPresent(); } /** @@ -113,6 +110,6 @@ public void testRemoveMatchingKeysFromCacheRemovesTheObject() { Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertFalse(actual.isPresent()); + assertThat(actual).isNotPresent(); } } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 1c70335f0..8d0f4e230 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -19,10 +19,7 @@ import static java.lang.reflect.Modifier.isFinal; import static java.util.Objects.nonNull; -import static org.apache.commons.lang3.ArrayUtils.contains; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -143,7 +140,7 @@ public void testIsPrimitiveTypeWorksAsExpected(final String testCaseDescription, boolean actual = underTest.isPrimitiveType(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -177,7 +174,7 @@ public void testIsSpecialTypeWorksAsExpected(final String testCaseDescription, f boolean actual = underTest.isSpecialType(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -210,7 +207,7 @@ public void testIsPrimitiveOrSpecialTypeWorksAsExpected(final String testCaseDes boolean actual = underTest.isPrimitiveOrSpecialType(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -241,7 +238,7 @@ public void testIsPrimitiveArrayTypeWorksAsExpected(final String testCaseDescrip boolean actual = underTest.isPrimitiveTypeArray(testArray.getClass()); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -277,7 +274,7 @@ public void testGetPrivateFinalFieldsWorksAsExpected(final String testCaseDescri List actual = underTest.getPrivateFinalFields(testClass); // THEN - assertEquals(expectedResult, actual.size()); + assertThat(actual.size()).isEqualTo(expectedResult); } /** @@ -308,7 +305,7 @@ public void testGetNotFinalFieldsWorksAsExpected(final String testCaseDescriptio List actual = underTest.getNotFinalFields(testClass, true); // THEN - assertEquals(expectedResult, actual.size()); + assertThat(actual.size()).isEqualTo(expectedResult); } /** @@ -339,7 +336,7 @@ public void testGetTotalFieldsWorksAsExpected(final String testCaseDescription, long actual = underTest.getTotalFields(testClass, fieldPredicate); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -370,7 +367,7 @@ public void testGetPrivateFieldsWorksAsExpected(final String testCaseDescription List actual = nonNull(skipFinal) ? underTest.getPrivateFields(testClass, skipFinal) : underTest.getPrivateFields(testClass); // THEN - assertEquals(expectedResult, actual.size()); + assertThat(actual.size()).isEqualTo(expectedResult); } /** @@ -412,7 +409,7 @@ public void testGetDeclaredFieldsWorksAsExpected(final String testCaseDescriptio List actual = underTest.getDeclaredFields(testClass, skipStatic); // THEN - assertEquals(expectedResult, actual.size()); + assertThat(actual.size()).isEqualTo(expectedResult); } /** @@ -445,7 +442,7 @@ public void testGetDeclaredClassesWorksAsExpected(final String testCaseDescripti Class[] actual = underTest.getDeclaredClasses(testClass); // THEN - assertTrue(contains(actual, expectedClass)); + assertThat(actual).contains(expectedClass); } /** @@ -473,7 +470,7 @@ public void testGetAllArgsConstructorWorksAsExpected() { Constructor actual = underTest.getAllArgsConstructor(CLASS_WITH_PRIVATE_FINAL_FIELDS); // THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); } /** @@ -487,7 +484,7 @@ public void testGetNoArgsConstructorWorksAsExpected() { Supplier actual = underTest.getNoArgsConstructor(CLASS_WITHOUT_PRIVATE_FINAL_FIELDS); // THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); } /** @@ -504,7 +501,7 @@ public void testAreParameterNamesAvailableWorksAsExpected(final String testCaseD boolean actual = underTest.areParameterNamesAvailable(constructor); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } @@ -557,8 +554,8 @@ public void testGetConstructorParameters() { Parameter[] constructorParameters = underTest.getConstructorParameters(classConstructor); // THEN - assertNotNull(constructorParameters); - assertEquals(EXPECTED_CLASS_PARAMETERS, constructorParameters.length); + assertThat(constructorParameters).isNotNull(); + assertThat(constructorParameters.length).isEqualTo(EXPECTED_CLASS_PARAMETERS); } /** @@ -589,7 +586,7 @@ public void testHasFieldWorksAsExpected(final String testCaseDescription, final boolean actual = underTest.hasField(immutableToFooSubClass, fieldName); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -618,7 +615,7 @@ public void testHasPrivateFinalFieldsWorksAsExpected(final String testCaseDescri boolean actual = underTest.hasFinalFields(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -647,7 +644,7 @@ public void testHasSetterMethodsWorksAsExpected(final String testCaseDescription boolean actual = underTest.hasSetterMethods(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -678,7 +675,7 @@ public void testAllParameterAnnotatedWithWorksAsExpected(final String testCaseDe boolean actual = underTest.allParameterAnnotatedWith(constructor, annotationClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -707,7 +704,7 @@ public void testGetClassTypeWorksAsExpected(final String testCaseDescription, fi final ClassType actual = underTest.getClassType(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -737,7 +734,7 @@ public void testGetSetterMethodsWorksAsExpected(final String testCaseDescription final List actual = underTest.getSetterMethods(testClass); // THEN - assertEquals(expectedResult, actual.isEmpty()); + assertThat(actual.isEmpty()).isEqualTo(expectedResult); } /** @@ -766,7 +763,7 @@ public void testGetGetterMethodsWorksAsExpected(final String testCaseDescription final List actual = underTest.getGetterMethods(testClass); // THEN - assertEquals(expectedGetterMethods, actual.size()); + assertThat(actual.size()).isEqualTo(expectedGetterMethods); } /** @@ -794,7 +791,7 @@ public void testGetDefaultTypeValueWorksAsExpected() { Object actual = underTest.getDefaultTypeValue(Integer.class); // THEN - assertEquals(EXPECTED_DEFAULT_VALUE, actual); + assertThat(actual).isEqualTo(EXPECTED_DEFAULT_VALUE); } /** @@ -823,7 +820,7 @@ public void testHasAccessibleConstructorsWorksAsExpected(final String testCaseDe final boolean actual = underTest.hasAccessibleConstructors(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -852,7 +849,7 @@ public void testIsStringWorksAsExpected(final String testCaseDescription, final boolean actual = underTest.isString(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -881,7 +878,7 @@ public void testIsBigIntegerWorksAsExpected(final String testCaseDescription, fi boolean actual = underTest.isBigInteger(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -910,7 +907,7 @@ public void testIsBigDecimalWorksAsExpected(final String testCaseDescription, fi boolean actual = underTest.isBigDecimal(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -939,7 +936,7 @@ public void testIsBiteArrayWorksAsExpected(final String testCaseDescription, fin boolean actual = underTest.isByteArray(testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -968,7 +965,7 @@ public void testGetFieldClassWorksAsExpected() throws Exception { Class actual = underTest.getFieldClass(listField, fromFoo); // THEN - assertEquals(LinkedList.class, actual); + assertThat(actual).isEqualTo(LinkedList.class); } /** @@ -986,7 +983,7 @@ public void testGetConcreteClassWorksAsExpected(final String testCaseDescription Class actual = underTest.getConcreteClass(field, fieldValue); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -1041,8 +1038,8 @@ public void testGetBuildMethodReturnsTheBuildMethod() { Method actual = underTest.getBuildMethod(MutableToFooWithBuilder.class, MutableToFooWithBuilder.Builder.class); // THEN - assertNotNull(actual); - assertEquals(BUILD_METHOD_NAME, actual.getName()); + assertThat(actual).isNotNull(); + assertThat(actual.getName()).isEqualTo(BUILD_METHOD_NAME); } /** @@ -1059,8 +1056,8 @@ public void testGetConcreteClassWorksAsExpected(final String testCaseDescription Optional> actual = underTest.getBuilderClass(testClass); // THEN - assertEquals(expectedResult.isPresent(), actual.isPresent()); - expectedResult.ifPresent(clazz -> assertEquals(clazz, actual.get())); + assertThat(actual.isPresent()).isEqualTo(expectedResult.isPresent()); + expectedResult.ifPresent(clazz -> assertThat(actual.get()).isEqualTo(clazz)); } /** diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 1704efd25..17e9e7d34 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -20,10 +20,7 @@ import static java.math.BigInteger.ZERO; import static java.util.Objects.isNull; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -128,7 +125,7 @@ public void testGetFieldValueWorksAsExpected(final String testCaseDescription, f Object actual = underTest.getFieldValue(beanObject, fieldName, fieldType); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -145,7 +142,7 @@ public void testGetFieldValueWithAGivenFieldWorksAsExpected() throws Exception { Object actual = underTest.getFieldValue(fromFooSimpleNoGetters, field); // THEN - assertEquals(ZERO, actual); + assertThat(actual).isEqualTo(ZERO); } /** @@ -178,7 +175,7 @@ public void testGetFieldValueCatchesRuntimeException() { Object actual = underTestMock.getFieldValue(mutableToFoo, LIST_FIELD_NAME, FromFooSubClass.class); //THEN - assertNull(actual); + assertThat(actual).isNull(); verify(underTestMock, times(1)).getDeclaredField(LIST_FIELD_NAME, MutableToFoo.class); } @@ -209,7 +206,7 @@ public void testGetFieldValueDirectAccessWorksAsExpected() throws Exception { Object actual = getFieldValueDirectAccessMethod.invoke(underTest, mutableToFoo, ID_FIELD_NAME); // THEN - assertEquals(ZERO, actual); + assertThat(actual).isEqualTo(ZERO); } /** @@ -255,7 +252,7 @@ public void testHandleReflectionExceptionThrowsMissingMethodExceptionWhenGivenEx RuntimeException actual = underTest.handleReflectionException(noSuchMethodException); // THEN - assertSame(MissingMethodException.class, actual.getClass()); + assertThat(actual.getClass()).isEqualTo(MissingMethodException.class); } /** @@ -267,10 +264,10 @@ public void testHandleReflectionExceptionThrowsIllegalStateExceptionWhenGivenExc IllegalAccessException illegalAccessException = new IllegalAccessException(); // WHEN - RuntimeException exception = underTest.handleReflectionException(illegalAccessException); + RuntimeException actual = underTest.handleReflectionException(illegalAccessException); // THEN - assertSame(IllegalStateException.class, exception.getClass()); + assertThat(actual.getClass()).isEqualTo(IllegalStateException.class); } /** @@ -282,10 +279,10 @@ public void testHandleReflectionExceptionThrowsRuntimeExceptionWhenGivenExceptio RuntimeException runtimeException = new RuntimeException(); // WHEN - RuntimeException exception = underTest.handleReflectionException(runtimeException); + RuntimeException actual = underTest.handleReflectionException(runtimeException); // THEN - assertSame(RuntimeException.class, exception.getClass()); + assertThat(actual.getClass()).isEqualTo(RuntimeException.class); } /** @@ -300,7 +297,7 @@ public void testHandleReflectionExceptionThrowsUndeclaredThrowableExceptionWhenG RuntimeException actual = underTest.handleReflectionException(genericException); // THEN - assertSame(UndeclaredThrowableException.class, actual.getClass()); + assertThat(actual.getClass()).isEqualTo(UndeclaredThrowableException.class); } /** @@ -331,7 +328,7 @@ public void testGetGetterMethodPrefixWorksAsExpected(final String testCaseDescri String actual = (String) method.invoke(underTest, testClass); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -365,7 +362,7 @@ public void testGetFieldAnnotationWorksProperly(final String testCaseDescription final Annotation actual = underTest.getFieldAnnotation(nameField, annotationToGet); // THEN - assertEquals(expectNull, isNull(actual)); + assertThat(isNull(actual)).isEqualTo(expectNull); } /** @@ -391,8 +388,8 @@ public void testGetSetterMethodForFieldWorksProperly() { final Method actual = underTest.getSetterMethodForField(MutableToFoo.class, ID_FIELD_NAME, BigInteger.class); // THEN - assertNotNull(actual); - assertEquals(EXPECTED_SETTER_METHOD_NAME, actual.getName()); + assertThat(actual).isNotNull(); + assertThat(actual.getName()).isEqualTo(EXPECTED_SETTER_METHOD_NAME); } /** @@ -421,8 +418,8 @@ public void testGetParameterAnnotationReturnsTheAnnotationIfExists() { final Annotation actual = underTest.getParameterAnnotation(parameter, NotNull.class, DECLARING_CLASS_NAME); // THEN - assertNotNull(actual); - assertEquals(notNullAnnotation, actual); + assertThat(actual).isNotNull(); + assertThat(actual).isEqualTo(notNullAnnotation); } /** @@ -438,7 +435,7 @@ public void testGetParameterAnnotationReturnsNullIfTheAnnotationDoesNotExists() final Annotation actual = underTest.getParameterAnnotation(parameter, NotNull.class, DECLARING_CLASS_NAME); // THEN - assertNull(actual); + assertThat(actual).isNull(); } /** @@ -456,7 +453,7 @@ public void testInvokeMethodWorksProperly() throws Exception { .invoke(underTest, idSetterMethod, mutableToFoo, new Object[] {ONE}); // THEN - assertEquals(ONE, mutableToFoo.getId()); + assertThat(mutableToFoo.getId()).isEqualTo(ONE); } /** @@ -480,8 +477,8 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong } // THEN - assertNotNull(actualException); - assertEquals(IllegalArgumentException.class, actualException.getTargetException().getClass()); + assertThat(actualException).isNotNull(); + assertThat(actualException.getTargetException().getClass()).isEqualTo(IllegalArgumentException.class); } /** @@ -498,7 +495,7 @@ public void testGetDeclaredFieldWorksProperly(final String testCaseDescription, Field actual = underTest.getDeclaredField(fieldName, targetClass); // THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); } /** @@ -520,8 +517,8 @@ public void testGetClassDeclaredFieldThrowsTheRightException() throws Exception } // THEN - assertNotNull(actualException); - assertEquals(NullPointerException.class, actualException.getTargetException().getClass()); + assertThat(actualException).isNotNull(); + assertThat(actualException.getTargetException().getClass()).isEqualTo(NullPointerException.class); } /** @@ -547,7 +544,7 @@ public void testGetDeclaredFieldRaisesAnExceptionIfTheFieldDoesNotExists() { Field actual = underTest.getDeclaredField(NOT_EXISTING_FIELD_NAME, FromFooSubClass.class); // THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); } /** @@ -561,7 +558,7 @@ public void testGetDeclaredFieldTypeWorksProperly() { Class actual = underTest.getDeclaredFieldType(ID_FIELD_NAME, FromFooSubClass.class); // THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); } @@ -581,7 +578,7 @@ public void testGetGenericFieldTypeWorksProperly(final String testCaseDescriptio Class actual = underTest.getGenericFieldType(field); // THEN - assertEquals(expectedType, actual); + assertThat(actual).isEqualTo(expectedType); } /** @@ -608,7 +605,7 @@ public void testGetArrayTypeWorksProperly() { Class actual = underTest.getArrayType(phoneNumbersField); // THEN - assertEquals(int.class, actual); + assertThat(actual).isEqualTo(int.class); } /** @@ -634,12 +631,12 @@ public void testMapGenericFieldTypeWorksProperly() { ItemType actualNestedMapElemType = (ItemType) ((MapType) actual.getElemType()).getElemType(); // THEN - assertEquals(expectedMapKeyType.getObjectClass(), actualMapKeyType.getObjectClass()); - assertEquals(expectedMapKeyType.getGenericClass(), actualMapKeyType.getGenericClass()); - assertEquals(expectedNestedMapKeyType.getObjectClass(), actualNestedMapKeyType.getObjectClass()); - assertEquals(expectedNestedMapKeyType.getGenericClass(), actualNestedMapKeyType.getGenericClass()); - assertEquals(expectedNestedMapElemType.getObjectClass(), actualNestedMapElemType.getObjectClass()); - assertEquals(expectedNestedMapElemType.getGenericClass(), actualNestedMapElemType.getGenericClass()); + assertThat(actualMapKeyType.getObjectClass()).isEqualTo(expectedMapKeyType.getObjectClass()); + assertThat(actualMapKeyType.getGenericClass()).isEqualTo(expectedMapKeyType.getGenericClass()); + assertThat(actualNestedMapKeyType.getObjectClass()).isEqualTo(expectedNestedMapKeyType.getObjectClass()); + assertThat(actualNestedMapKeyType.getGenericClass()).isEqualTo(expectedNestedMapKeyType.getGenericClass()); + assertThat(actualNestedMapElemType.getObjectClass()).isEqualTo(expectedNestedMapElemType.getObjectClass()); + assertThat(actualNestedMapElemType.getGenericClass()).isEqualTo(expectedNestedMapElemType.getGenericClass()); } @Test @@ -659,10 +656,10 @@ public void testMapGenericFieldTypeWorksProperlyForUnparametrizedMap() { ItemType actualMapElemType = (ItemType) actual.getElemType(); // THEN - assertEquals(expectedMapKeyType.getObjectClass(), actualMapKeyType.getObjectClass()); - assertEquals(expectedMapKeyType.getGenericClass(), actualMapKeyType.getGenericClass()); - assertEquals(expectedMapElemType.getObjectClass(), actualMapElemType.getObjectClass()); - assertEquals(expectedMapElemType.getGenericClass(), actualMapElemType.getGenericClass()); + assertThat(actualMapKeyType.getObjectClass()).isEqualTo(expectedMapKeyType.getObjectClass()); + assertThat(actualMapKeyType.getGenericClass()).isEqualTo(expectedMapKeyType.getGenericClass()); + assertThat(actualMapElemType.getObjectClass()).isEqualTo(expectedMapElemType.getObjectClass()); + assertThat(actualMapElemType.getGenericClass()).isEqualTo(expectedMapElemType.getGenericClass()); } /** @@ -678,7 +675,7 @@ public void testGetGetterMethodWorksProperly() throws Exception { Object actual = methodUnderTest.invoke(underTest, FromFooSimple.class, ID_FIELD_NAME, BigInteger.class); // THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); } /** @@ -696,7 +693,7 @@ public void testThatTheReturnedMethodFromGetGetterMethodReturnsTheExpectedValue( BigInteger actual = (BigInteger) methodUnderTest.invoke(mutableToFoo); // THEN - assertEquals(ONE, actual); + assertThat(actual).isEqualTo(ONE); } /** @@ -717,8 +714,8 @@ public void testGetGetterMethodThrowsExceptionIfTheMethodDoesNotExists() throws } // THEN - assertNotNull(actualException); - assertEquals(MissingFieldException.class, actualException.getTargetException().getClass()); + assertThat(actualException).isNotNull(); + assertThat(actualException.getTargetException().getClass()).isEqualTo(MissingFieldException.class); } /** @@ -757,7 +754,7 @@ public void testSetFieldValueWorksProperly() { underTest.setFieldValue(mutableToFoo, idField, ONE); // THEN - assertEquals(ONE, mutableToFoo.getId()); + assertThat(mutableToFoo.getId()).isEqualTo(ONE); } @Test @@ -772,7 +769,7 @@ public void testSetFieldValueInvokesTheSetterMethodInCaseAnExceptionIsRaised() { underTestMock.setFieldValue(mutableToFoo, idField, ONE); // THEN - assertEquals(ONE, mutableToFoo.getId()); + assertThat(mutableToFoo.getId()).isEqualTo(ONE); } /** @@ -800,8 +797,8 @@ public void testInvokeMethodCorrectlyHandlesExceptions(final String testCaseDesc } // THEN - assertNotNull(actualException); - assertEquals(expectedException, actualException.getClass()); + assertThat(actualException).isNotNull(); + assertThat(actualException.getClass()).isEqualTo(expectedException); } /** @@ -832,7 +829,7 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro Object actual = getRealTargetMethod.invoke(underTest, optionalBigInteger); //THEN - assertEquals(ZERO, actual); + assertThat(actual).isEqualTo(ZERO); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 0f9032ea4..dd783290c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -21,9 +21,7 @@ import static java.nio.ByteBuffer.wrap; import static java.util.Optional.empty; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -91,7 +89,7 @@ public void testGetConversionFunctionReturnsAnEmptyOptional(final String testCas Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN - assertEquals(empty(), actual); + assertThat(actual).isEqualTo(empty()); } /** @@ -124,8 +122,8 @@ public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN - assertTrue(actual.isPresent()); - assertEquals(expectedConversionFunction, actual.get()); + assertThat(actual.isPresent()).isTrue(); + assertThat(actual.get()).isEqualTo(expectedConversionFunction); } /** @@ -192,7 +190,7 @@ public void testConvertValueWorksProperly(final String testCaseDescription, Object actual = underTest.convertValue(valueToConvert, targetClass); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } /** @@ -455,7 +453,7 @@ public void testConvertByteArrayValueWorksProperly(final String testCaseDesc byte[] actual = underTest.convertValue(valueToConvert, byte[].class); // THEN - assertArrayEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index f46910feb..b659a2cd5 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -18,8 +18,7 @@ import static java.util.Optional.empty; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -78,7 +77,7 @@ public void testGetConversionFunctionReturnsAnEmptyOptional(final String testCas Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN - assertEquals(empty(), actual); + assertThat(actual).isEqualTo(empty()); } /** @@ -115,8 +114,8 @@ public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN - assertTrue(actual.isPresent()); - assertEquals(expectedConversionFunction, actual.get()); + assertThat(actual.isPresent()).isTrue(); + assertThat(actual.get()).isEqualTo(expectedConversionFunction); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index d24fc494e..cbbfa7928 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -16,8 +16,7 @@ package com.hotels.beans.conversion.processor; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -72,7 +71,7 @@ public void testGetConversionProcessorReturnsNullInCaseNoProcessorExistsForTheGi Optional actual = underTest.getConversionProcessor(Pair.class); // THEN - assertTrue(actual.isEmpty()); + assertThat(actual.isEmpty()).isTrue(); } /** @@ -90,8 +89,8 @@ public void testGetConversionProcessorWorksAsExpected(final String testCaseDescr Optional actual = underTest.getConversionProcessor(targetClass); // THEN - assertTrue(actual.isPresent()); - assertEquals(expectedResult, actual.get().getClass()); + assertThat(actual.isPresent()).isTrue(); + assertThat(actual.get().getClass()).isEqualTo(expectedResult); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java index 1aa8ca184..de6aae067 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java @@ -20,7 +20,7 @@ import static java.math.BigDecimal.valueOf; import static java.nio.ByteBuffer.wrap; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -61,7 +61,7 @@ public void testConvertByteShouldReturnProperResult() { BigDecimal actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -73,7 +73,7 @@ public void testConvertByteArrayShouldReturnProperResult() { BigDecimal actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test(expectedExceptions = TypeConversionException.class) @@ -93,7 +93,7 @@ public void testConvertShortShouldReturnProperResult() { BigDecimal actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -105,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { BigDecimal actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -117,7 +117,7 @@ public void testConvertLongShouldReturnProperResult() { BigDecimal actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -129,7 +129,7 @@ public void testConvertFloatShouldReturnProperResult() { BigDecimal actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -141,7 +141,7 @@ public void testConvertDoubleShouldReturnProperResult() { BigDecimal actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -153,7 +153,7 @@ public void testConvertCharacterShouldReturnProperResult() { BigDecimal actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } /** @@ -170,7 +170,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc BigDecimal actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -194,7 +194,7 @@ public void testConvertStringShouldReturnProperResult() { BigDecimal actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -206,7 +206,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { BigDecimal actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -218,6 +218,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { BigDecimal actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java index 1ed19ef52..1280fbc47 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java @@ -20,7 +20,7 @@ import static java.math.BigInteger.valueOf; import static java.nio.ByteBuffer.wrap; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -61,7 +61,7 @@ public void testConvertByteShouldReturnProperResult() { BigInteger actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -73,7 +73,7 @@ public void testConvertByteArrayShouldReturnProperResult() { BigInteger actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test(expectedExceptions = TypeConversionException.class) @@ -93,7 +93,7 @@ public void testConvertShortShouldReturnProperResult() { BigInteger actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -105,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { BigInteger actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -117,7 +117,7 @@ public void testConvertLongShouldReturnProperResult() { BigInteger actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -129,7 +129,7 @@ public void testConvertFloatShouldReturnProperResult() { BigInteger actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -141,7 +141,7 @@ public void testConvertDoubleShouldReturnProperResult() { BigInteger actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -153,7 +153,7 @@ public void testConvertCharacterShouldReturnProperResult() { BigInteger actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } /** @@ -170,7 +170,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc BigInteger actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -194,7 +194,7 @@ public void testConvertStringShouldReturnProperResult() { BigInteger actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -205,7 +205,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { BigInteger actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(BigInteger.ZERO, actual); + assertThat(actual).isEqualTo(BigInteger.ZERO); } @Test @@ -217,6 +217,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { BigInteger actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java index d7897e9f3..49fb9f359 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java @@ -16,9 +16,7 @@ package com.hotels.beans.conversion.processor.impl; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -63,7 +61,7 @@ public void testConvertByteShouldReturnProperResult(final String testCaseDescrip boolean actual = underTest.convertByte().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -92,7 +90,7 @@ public void testConvertByteArrayShouldReturnProperResult(final String testCaseDe boolean actual = underTest.convertByteArray().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -121,7 +119,7 @@ public void testConvertShortShouldReturnProperResult(final String testCaseDescri boolean actual = underTest.convertShort().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -150,7 +148,7 @@ public void testConvertIntegerShouldReturnProperResult(final String testCaseDesc boolean actual = underTest.convertInteger().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -179,7 +177,7 @@ public void testConvertLongShouldReturnProperResult(final String testCaseDescrip boolean actual = underTest.convertLong().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -208,7 +206,7 @@ public void testConvertFloatShouldReturnProperResult(final String testCaseDescri boolean actual = underTest.convertFloat().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -237,7 +235,7 @@ public void testConvertDoubleShouldReturnProperResult(final String testCaseDescr boolean actual = underTest.convertDouble().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -260,7 +258,7 @@ public void testConvertCharacterShouldReturnProperResult() { boolean actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertFalse(actual); + assertThat(actual).isFalse(); } @Test @@ -271,7 +269,7 @@ public void testConvertBooleanShouldReturnProperResult() { boolean actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); // THEN - assertEquals(BOOLEAN_VALUE, actual); + assertThat(actual).isEqualTo(BOOLEAN_VALUE); } @Test @@ -282,7 +280,7 @@ public void testConvertStringShouldReturnProperResult() { boolean actual = underTest.convertString().apply(TRUE_AS_STRING); // THEN - assertTrue(actual); + assertThat(actual).isTrue(); } /** @@ -299,7 +297,7 @@ public void testConvertBigIntegerShouldReturnProperResult(final String testCaseD boolean actual = underTest.convertBigInteger().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -328,7 +326,7 @@ public void testConvertBigIntegerShouldReturnProperResult(final String testCaseD boolean actual = underTest.convertBigDecimal().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java index 168ee87eb..3257b1f36 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java @@ -16,7 +16,7 @@ package com.hotels.beans.conversion.processor.impl; -import static org.junit.Assert.assertArrayEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -59,7 +59,7 @@ public void testConvertByteShouldReturnProperResult() { byte[] actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertArrayEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -70,7 +70,7 @@ public void testConvertByteArrayShouldReturnProperResult() { byte[] actual = underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); // THEN - assertArrayEquals(ONE_BYTE_BYTE_ARRAY, actual); + assertThat(actual).isEqualTo(ONE_BYTE_BYTE_ARRAY); } @Test @@ -82,7 +82,7 @@ public void testConvertShortShouldReturnProperResult() { byte[] actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertArrayEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -94,7 +94,7 @@ public void testConvertIntegerShouldReturnProperResult() { byte[] actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertArrayEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -106,7 +106,7 @@ public void testConvertLongShouldReturnProperResult() { byte[] actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertArrayEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -118,7 +118,7 @@ public void testConvertFloatShouldReturnProperResult() { byte[] actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertArrayEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -130,7 +130,7 @@ public void testConvertDoubleShouldReturnProperResult() { byte[] actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertArrayEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -142,7 +142,7 @@ public void testConvertCharacterShouldReturnProperResult() { byte[] actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertArrayEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } /** @@ -159,7 +159,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc byte[] actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertArrayEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -183,7 +183,7 @@ public void testConvertStringShouldReturnProperResult() { byte[] actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertArrayEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -195,7 +195,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { byte[] actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertArrayEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } @Test @@ -207,6 +207,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { byte[] actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertArrayEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java index 0a110f6dc..f86deb10d 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java @@ -18,7 +18,7 @@ import static java.lang.Byte.valueOf; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -60,7 +60,7 @@ public void testConvertByteShouldReturnProperResult() { Byte actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals(BYTE_VALUE, actual); + assertThat(actual).isEqualTo(BYTE_VALUE); } @Test @@ -71,7 +71,7 @@ public void testConvertByteArrayShouldReturnProperResult() { byte actual = underTest.convertByteArray().apply(ONE_BYTE_BYTE_ARRAY); // THEN - assertEquals(ONE_BYTE_BYTE_ARRAY[0], actual); + assertThat(actual).isEqualTo(ONE_BYTE_BYTE_ARRAY[0]); } @Test @@ -82,7 +82,7 @@ public void testConvertShortShouldReturnProperResult() { byte actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals(SHORT_VALUE.byteValue(), actual); + assertThat(actual).isEqualTo(SHORT_VALUE.byteValue()); } @Test @@ -93,7 +93,7 @@ public void testConvertIntegerShouldReturnProperResult() { byte actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals(INTEGER_VALUE.byteValue(), actual); + assertThat(actual).isEqualTo(INTEGER_VALUE.byteValue()); } @Test @@ -104,7 +104,7 @@ public void testConvertLongShouldReturnProperResult() { byte actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals(LONG_VALUE.byteValue(), actual); + assertThat(actual).isEqualTo(LONG_VALUE.byteValue()); } @Test @@ -115,7 +115,7 @@ public void testConvertFloatShouldReturnProperResult() { byte actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals(FLOAT_VALUE.byteValue(), actual); + assertThat(actual).isEqualTo(FLOAT_VALUE.byteValue()); } @Test @@ -126,7 +126,7 @@ public void testConvertDoubleShouldReturnProperResult() { byte actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals(DOUBLE_VALUE.byteValue(), actual); + assertThat(actual).isEqualTo(DOUBLE_VALUE.byteValue()); } @Test @@ -137,7 +137,7 @@ public void testConvertCharacterShouldReturnProperResult() { byte actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals((byte) CHAR_VALUE, actual); + assertThat(actual).isEqualTo((byte) CHAR_VALUE); } /** @@ -154,7 +154,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc int actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -177,7 +177,7 @@ public void testConvertStringShouldReturnProperResult() { Byte actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(valueOf(STRING_VALUE), actual); + assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); } @Test @@ -189,7 +189,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { byte actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } @Test @@ -201,6 +201,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { byte actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java index 723528c26..6adbfbaf7 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java @@ -18,7 +18,7 @@ import static java.nio.ByteBuffer.wrap; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -61,7 +61,7 @@ public void testConvertByteShouldReturnProperResult() { char actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals((char) BYTE_VALUE.byteValue(), actual); + assertThat(actual).isEqualTo((char) BYTE_VALUE.byteValue()); } @Test @@ -73,7 +73,7 @@ public void testConvertByteArrayShouldReturnProperResult() { char actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test(expectedExceptions = TypeConversionException.class) @@ -92,7 +92,7 @@ public void testConvertShortShouldReturnProperResult() { char actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals((char) SHORT_VALUE.byteValue(), actual); + assertThat(actual).isEqualTo((char) SHORT_VALUE.byteValue()); } @Test @@ -103,7 +103,7 @@ public void testConvertIntegerShouldReturnProperResult() { char actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals((char) INTEGER_VALUE.intValue(), actual); + assertThat(actual).isEqualTo((char) INTEGER_VALUE.intValue()); } @Test @@ -114,7 +114,7 @@ public void testConvertLongShouldReturnProperResult() { char actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals((char) LONG_VALUE.longValue(), actual); + assertThat(actual).isEqualTo((char) LONG_VALUE.longValue()); } @Test @@ -125,7 +125,7 @@ public void testConvertFloatShouldReturnProperResult() { char actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals((char) FLOAT_VALUE.floatValue(), actual); + assertThat(actual).isEqualTo((char) FLOAT_VALUE.floatValue()); } @Test @@ -136,7 +136,7 @@ public void testConvertDoubleShouldReturnProperResult() { char actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals((char) DOUBLE_VALUE.doubleValue(), actual); + assertThat(actual).isEqualTo((char) DOUBLE_VALUE.doubleValue()); } @Test @@ -147,7 +147,7 @@ public void testConvertCharacterShouldReturnProperResult() { char actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(CHAR_VALUE, actual); + assertThat(actual).isEqualTo(CHAR_VALUE); } /** @@ -164,7 +164,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc char actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -187,7 +187,7 @@ public void testConvertStringShouldReturnProperResult() { char actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(STRING_VALUE.charAt(0), actual); + assertThat(actual).isEqualTo(STRING_VALUE.charAt(0)); } @Test @@ -199,7 +199,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { char actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } @Test @@ -211,6 +211,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { char actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index a893c1102..0c05e6a30 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -20,7 +20,7 @@ import static java.lang.Double.valueOf; import static java.nio.ByteBuffer.wrap; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -40,7 +40,6 @@ public class DoubleConversionTest extends AbstractConversionTest { private static final double TRUE_AS_DOUBLE = 1d; private static final double FALSE_AS_DOUBLE = 0d; - private static final double DELTA = 0.0; /** * The class to be tested. @@ -64,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Double actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals((Double) BYTE_VALUE.doubleValue(), actual); + assertThat(actual).isEqualTo((Double) BYTE_VALUE.doubleValue()); } @Test @@ -76,7 +75,7 @@ public void testConvertByteArrayShouldReturnProperResult() { Double actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test(expectedExceptions = TypeConversionException.class) @@ -95,7 +94,7 @@ public void testConvertShortShouldReturnProperResult() { Double actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals(DOUBLE_VALUE, actual); + assertThat(actual).isEqualTo(DOUBLE_VALUE); } @Test @@ -106,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { Double actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals((Double) INTEGER_VALUE.doubleValue(), actual); + assertThat(actual).isEqualTo((Double) INTEGER_VALUE.doubleValue()); } @Test @@ -117,7 +116,7 @@ public void testConvertLongShouldReturnProperResult() { Double actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals((Double) LONG_VALUE.doubleValue(), actual); + assertThat(actual).isEqualTo((Double) LONG_VALUE.doubleValue()); } @Test @@ -128,7 +127,7 @@ public void testConvertFloatShouldReturnProperResult() { Double actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals((Double) FLOAT_VALUE.doubleValue(), actual); + assertThat(actual).isEqualTo((Double) FLOAT_VALUE.doubleValue()); } @Test @@ -139,7 +138,7 @@ public void testConvertDoubleShouldReturnProperResult() { Double actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals(DOUBLE_VALUE, actual); + assertThat(actual).isEqualTo(DOUBLE_VALUE); } @Test @@ -150,7 +149,7 @@ public void testConvertCharacterShouldReturnProperResult() { Double actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(valueOf((short) getNumericValue(CHAR_VALUE)), actual); + assertThat(actual).isEqualTo(valueOf((short) getNumericValue(CHAR_VALUE))); } /** @@ -167,7 +166,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc Double actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual, DELTA); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -190,7 +189,7 @@ public void testConvertStringShouldReturnProperResult() { Double actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(valueOf(STRING_VALUE), actual); + assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); } @Test @@ -202,7 +201,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { double actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expectedValue, actual, DELTA); + assertThat(actual).isEqualTo(expectedValue); } @Test @@ -214,6 +213,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { double actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual, DELTA); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index b7aa816e2..8175feee0 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -20,7 +20,7 @@ import static java.lang.Float.valueOf; import static java.nio.ByteBuffer.wrap; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -40,7 +40,6 @@ public class FloatConversionTest extends AbstractConversionTest { private static final float TRUE_AS_FLOAT = 1f; private static final float FALSE_AS_FLOAT = 0f; - private static final double DELTA = 0.0; /** * The class to be tested. @@ -64,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Float actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals((Float) BYTE_VALUE.floatValue(), actual); + assertThat(actual).isEqualTo((Float) BYTE_VALUE.floatValue()); } @Test @@ -76,7 +75,7 @@ public void testConvertByteArrayShouldReturnProperResult() { Float actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test(expectedExceptions = TypeConversionException.class) @@ -95,7 +94,7 @@ public void testConvertShortShouldReturnProperResult() { Float actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals((Float) SHORT_VALUE.floatValue(), actual); + assertThat(actual).isEqualTo((Float) SHORT_VALUE.floatValue()); } @Test @@ -106,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { Float actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals((Float) INTEGER_VALUE.floatValue(), actual); + assertThat(actual).isEqualTo((Float) INTEGER_VALUE.floatValue()); } @Test @@ -117,7 +116,7 @@ public void testConvertLongShouldReturnProperResult() { Float actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals((Float) LONG_VALUE.floatValue(), actual); + assertThat(actual).isEqualTo((Float) LONG_VALUE.floatValue()); } @Test @@ -128,7 +127,7 @@ public void testConvertFloatShouldReturnProperResult() { Float actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals(FLOAT_VALUE, actual); + assertThat(actual).isEqualTo(FLOAT_VALUE); } @Test @@ -139,7 +138,7 @@ public void testConvertDoubleShouldReturnProperResult() { Float actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals((Float) DOUBLE_VALUE.floatValue(), actual); + assertThat(actual).isEqualTo((Float) DOUBLE_VALUE.floatValue()); } @Test @@ -150,7 +149,7 @@ public void testConvertCharacterShouldReturnProperResult() { Float actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(Float.valueOf(getNumericValue(CHAR_VALUE)), actual); + assertThat(actual).isEqualTo(Float.valueOf(getNumericValue(CHAR_VALUE))); } /** @@ -167,7 +166,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc Float actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual, DELTA); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -190,7 +189,7 @@ public void testConvertStringShouldReturnProperResult() { Float actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(valueOf(STRING_VALUE), actual); + assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); } @Test @@ -202,7 +201,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { double actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expectedValue, actual, DELTA); + assertThat(actual).isEqualTo(expectedValue); } @Test @@ -214,6 +213,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { float actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual, DELTA); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index 8b99f5974..8cc8ef64a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -20,7 +20,7 @@ import static java.lang.Integer.valueOf; import static java.nio.ByteBuffer.wrap; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -63,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Integer actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals((Integer) BYTE_VALUE.intValue(), actual); + assertThat(actual).isEqualTo((Integer) BYTE_VALUE.intValue()); } @Test @@ -75,7 +75,7 @@ public void testConvertByteArrayShouldReturnProperResult() { Integer actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test(expectedExceptions = TypeConversionException.class) @@ -94,7 +94,7 @@ public void testConvertShortShouldReturnProperResult() { Integer actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals((Integer) SHORT_VALUE.intValue(), actual); + assertThat(actual).isEqualTo((Integer) SHORT_VALUE.intValue()); } @Test @@ -105,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { Integer actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals(INTEGER_VALUE, actual); + assertThat(actual).isEqualTo(INTEGER_VALUE); } @Test @@ -116,7 +116,7 @@ public void testConvertLongShouldReturnProperResult() { Integer actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals((Integer) LONG_VALUE.intValue(), actual); + assertThat(actual).isEqualTo((Integer) LONG_VALUE.intValue()); } @Test @@ -127,7 +127,7 @@ public void testConvertFloatShouldReturnProperResult() { Integer actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals((Integer) FLOAT_VALUE.intValue(), actual); + assertThat(actual).isEqualTo((Integer) FLOAT_VALUE.intValue()); } @Test @@ -138,7 +138,7 @@ public void testConvertDoubleShouldReturnProperResult() { Integer actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals((Integer) DOUBLE_VALUE.intValue(), actual); + assertThat(actual).isEqualTo((Integer) DOUBLE_VALUE.intValue()); } @Test @@ -149,7 +149,7 @@ public void testConvertCharacterShouldReturnProperResult() { Integer actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals((Integer) getNumericValue(CHAR_VALUE), actual); + assertThat(actual).isEqualTo((Integer) getNumericValue(CHAR_VALUE)); } /** @@ -166,7 +166,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc int actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -189,7 +189,7 @@ public void testConvertStringShouldReturnProperResult() { Integer actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(valueOf(STRING_VALUE), actual); + assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); } @Test @@ -201,7 +201,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { int actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } @Test @@ -213,6 +213,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { int actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java index 63d4b5e84..db34d1307 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java @@ -20,7 +20,7 @@ import static java.lang.Long.valueOf; import static java.nio.ByteBuffer.wrap; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -63,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Long actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals((Long) BYTE_VALUE.longValue(), actual); + assertThat(actual).isEqualTo((Long) BYTE_VALUE.longValue()); } @Test @@ -75,7 +75,7 @@ public void testConvertByteArrayShouldReturnProperResult() { Long actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test(expectedExceptions = TypeConversionException.class) @@ -94,7 +94,7 @@ public void testConvertShortShouldReturnProperResult() { Long actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals((Long) SHORT_VALUE.longValue(), actual); + assertThat(actual).isEqualTo((Long) SHORT_VALUE.longValue()); } @Test @@ -105,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { Long actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals((Long) INTEGER_VALUE.longValue(), actual); + assertThat(actual).isEqualTo((Long) INTEGER_VALUE.longValue()); } @Test @@ -116,7 +116,7 @@ public void testConvertLongShouldReturnProperResult() { Long actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals(LONG_VALUE, actual); + assertThat(actual).isEqualTo(LONG_VALUE); } @Test @@ -127,7 +127,7 @@ public void testConvertFloatShouldReturnProperResult() { Long actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals((Long) FLOAT_VALUE.longValue(), actual); + assertThat(actual).isEqualTo((Long) FLOAT_VALUE.longValue()); } @Test @@ -138,7 +138,7 @@ public void testConvertDoubleShouldReturnProperResult() { Long actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals((Long) DOUBLE_VALUE.longValue(), actual); + assertThat(actual).isEqualTo((Long) DOUBLE_VALUE.longValue()); } @Test @@ -149,7 +149,7 @@ public void testConvertCharacterShouldReturnProperResult() { Long actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(valueOf(getNumericValue(CHAR_VALUE)), actual); + assertThat(actual).isEqualTo(valueOf(getNumericValue(CHAR_VALUE))); } /** @@ -166,7 +166,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc long actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -189,7 +189,7 @@ public void testConvertStringShouldReturnProperResult() { Long actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(valueOf(STRING_VALUE), actual); + assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); } @Test @@ -201,7 +201,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { long actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } @Test @@ -213,6 +213,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { long actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java index eb1a4d929..7ad948b6f 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java @@ -20,7 +20,7 @@ import static java.lang.Short.valueOf; import static java.nio.ByteBuffer.wrap; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -63,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Short actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals((Short) BYTE_VALUE.shortValue(), actual); + assertThat(actual).isEqualTo((Short) BYTE_VALUE.shortValue()); } @Test @@ -74,7 +74,7 @@ public void testConvertShortShouldReturnProperResult() { Short actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals(SHORT_VALUE, actual); + assertThat(actual).isEqualTo(SHORT_VALUE); } @Test @@ -86,7 +86,7 @@ public void testConvertByteArrayShouldReturnProperResult() { Short actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test(expectedExceptions = TypeConversionException.class) @@ -105,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { Short actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals((Short) INTEGER_VALUE.shortValue(), actual); + assertThat(actual).isEqualTo((Short) INTEGER_VALUE.shortValue()); } @Test @@ -116,7 +116,7 @@ public void testConvertLongShouldReturnProperResult() { Short actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals((Short) LONG_VALUE.shortValue(), actual); + assertThat(actual).isEqualTo((Short) LONG_VALUE.shortValue()); } @Test @@ -127,7 +127,7 @@ public void testConvertFloatShouldReturnProperResult() { Short actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals((Short) FLOAT_VALUE.shortValue(), actual); + assertThat(actual).isEqualTo((Short) FLOAT_VALUE.shortValue()); } @Test @@ -138,7 +138,7 @@ public void testConvertDoubleShouldReturnProperResult() { Short actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals((Short) DOUBLE_VALUE.shortValue(), actual); + assertThat(actual).isEqualTo((Short) DOUBLE_VALUE.shortValue()); } @Test @@ -149,7 +149,7 @@ public void testConvertCharacterShouldReturnProperResult() { Short actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(valueOf((short) getNumericValue(CHAR_VALUE)), actual); + assertThat(actual).isEqualTo(valueOf((short) getNumericValue(CHAR_VALUE))); } /** @@ -166,7 +166,7 @@ public void testConvertBooleanShouldReturnProperResult(final String testCaseDesc short actual = underTest.convertBoolean().apply(valueToConvert); // THEN - assertEquals(expectedResult, actual); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -189,7 +189,7 @@ public void testConvertStringShouldReturnProperResult() { Short actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(valueOf(STRING_VALUE), actual); + assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); } @Test @@ -201,7 +201,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { short actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } @Test @@ -213,6 +213,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { short actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java index 33041fc30..fbfdd7d00 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java @@ -18,7 +18,7 @@ import static java.lang.String.valueOf; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigDecimal; @@ -56,7 +56,7 @@ public void testConvertByteShouldReturnProperResult() { String actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertEquals(BYTE_VALUE.toString(), actual); + assertThat(actual).isEqualTo(BYTE_VALUE.toString()); } @Test @@ -68,7 +68,7 @@ public void testConvertByteArrayShouldReturnProperResult() { String actual = underTest.convertByteArray().apply(EIGHT_BYTE_BYTE_ARRAY); // THEN - assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } @Test @@ -79,7 +79,7 @@ public void testConvertShortShouldReturnProperResult() { String actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertEquals(SHORT_VALUE.toString(), actual); + assertThat(actual).isEqualTo(SHORT_VALUE.toString()); } @Test @@ -90,7 +90,7 @@ public void testConvertIntegerShouldReturnProperResult() { String actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertEquals(INTEGER_VALUE.toString(), actual); + assertThat(actual).isEqualTo(INTEGER_VALUE.toString()); } @Test @@ -101,7 +101,7 @@ public void testConvertLongShouldReturnProperResult() { String actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertEquals(LONG_VALUE.toString(), actual); + assertThat(actual).isEqualTo(LONG_VALUE.toString()); } @Test @@ -112,7 +112,7 @@ public void testConvertFloatShouldReturnProperResult() { String actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertEquals(FLOAT_VALUE.toString(), actual); + assertThat(actual).isEqualTo(FLOAT_VALUE.toString()); } @Test @@ -123,7 +123,7 @@ public void testConvertDoubleShouldReturnProperResult() { String actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertEquals(DOUBLE_VALUE.toString(), actual); + assertThat(actual).isEqualTo(DOUBLE_VALUE.toString()); } @Test @@ -134,7 +134,7 @@ public void testConvertCharacterShouldReturnProperResult() { String actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertEquals(valueOf(CHAR_VALUE), actual); + assertThat(actual).isEqualTo(valueOf(CHAR_VALUE)); } @Test @@ -145,7 +145,7 @@ public void testConvertBooleanShouldReturnProperResult() { String actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); // THEN - assertEquals(BOOLEAN_VALUE.toString(), actual); + assertThat(actual).isEqualTo(BOOLEAN_VALUE.toString()); } @Test @@ -156,7 +156,7 @@ public void testConvertStringShouldReturnProperResult() { String actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertEquals(STRING_VALUE, actual); + assertThat(actual).isEqualTo(STRING_VALUE); } @Test @@ -168,7 +168,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { String actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } @Test @@ -180,6 +180,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { String actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertEquals(expectedValue, actual); + assertThat(actual).isEqualTo(expectedValue); } } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index bc1f8f31b..97e6f7193 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.everyItem; import static org.hamcrest.Matchers.isIn; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; @@ -127,7 +127,7 @@ public void testTransformWorksProperly(final String testCaseDescription, Map actual = underTest.transform(sourceMap); //THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); assertEquals(actual.size(), sourceMap.size()); assertThat(actual.entrySet(), both(everyItem(isIn(sourceMap.entrySet()))).and(containsInAnyOrder(sourceMap.entrySet().toArray()))); @@ -162,7 +162,7 @@ public void testTransformWorksProperlyWithKeyMapping() { Map actual = underTest.transform(sourceMap); //THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); assertEquals(actual.size(), sourceMap.size()); assertEquals(actual.get(MAP_KEY_1), sourceMap.get(MAP_KEY_1)); assertEquals(actual.get(MAP_KEY_2), sourceMap.get(MAP_KEY_1)); @@ -184,7 +184,7 @@ public void testTransformWorksProperlyWithTransformer() { Map actual = underTest.transform(sourceMap); //THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); assertEquals(actual.size(), sourceMap.size()); assertTrue(actual.containsKey(MAP_KEY_1.toUpperCase())); } @@ -214,7 +214,7 @@ public void testTransformWorksProperlyWithTargetKeyAndElemType() { Map actual = underTest.transform(EXTREME_COMPLEX_MAP, MutableToFooSimple.class, Map.class); //THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); assertEquals(actual.size(), EXTREME_COMPLEX_MAP.size()); // check that the element has been converted for (Map.Entry entry : actual.entrySet()) { @@ -236,7 +236,7 @@ public void testTransformWorksProperlyWithMapContainingList() { Map actual = underTest.transform(sourceMap, MutableToFooSimple.class, List.class); //THEN - assertNotNull(actual); + assertThat(actual).isNotNull(); assertEquals(actual.size(), sourceMap.size()); for (Map.Entry entry : actual.entrySet()) { assertEquals(MutableToFooSimple.class, entry.getKey().getClass()); diff --git a/docs/site/markdown/transformer/bean/testing.md b/docs/site/markdown/transformer/bean/testing.md index b7307724d..af81c5e08 100644 --- a/docs/site/markdown/transformer/bean/testing.md +++ b/docs/site/markdown/transformer/bean/testing.md @@ -70,7 +70,7 @@ public class SampleClass { ``` The test class will be: ```java -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import static org.mockito.Mockito.when; import static org.mockito.Mockito.mock; @@ -186,7 +186,7 @@ public class SampleClass { ``` The test class will be: ```java -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import static org.mockito.Mockito.when; import static org.mockito.Mockito.mock; @@ -306,7 +306,7 @@ public class SampleClass { ``` The test class will be: ```java -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import java.lang.reflect.Field; diff --git a/pom.xml b/pom.xml index 51ee52863..8fa7cd927 100644 --- a/pom.xml +++ b/pom.xml @@ -151,10 +151,10 @@ org.hamcrest hamcrest - - - - + + junit + junit + From b150ddf35f7205ffff96cf54ae01c330eb477718 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jun 2020 17:12:44 +0200 Subject: [PATCH 1119/1786] Replaces libraries asserts with AssertJ --- .../java/com/hotels/map/MapUtilsTest.java | 4 +- .../map/transformer/MapTransformerTest.java | 37 ++++++++----------- pom.xml | 19 ++++++---- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java index 481e9e1ab..71fa0dc7d 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java @@ -16,7 +16,7 @@ package com.hotels.map; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; import org.mockito.InjectMocks; @@ -54,6 +54,6 @@ public void testGetTransformerWorksProperly() { final MapTransformer transformer = underTest.getTransformer(); //THEN - assertNotNull(transformer); + assertThat(transformer).isNotNull(); } } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 97e6f7193..4d6dcb858 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -20,14 +20,7 @@ import static java.math.BigInteger.ZERO; import static java.util.Collections.singletonList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.both; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.everyItem; -import static org.hamcrest.Matchers.isIn; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigInteger; @@ -128,9 +121,11 @@ public void testTransformWorksProperly(final String testCaseDescription, //THEN assertThat(actual).isNotNull(); - assertEquals(actual.size(), sourceMap.size()); - assertThat(actual.entrySet(), - both(everyItem(isIn(sourceMap.entrySet()))).and(containsInAnyOrder(sourceMap.entrySet().toArray()))); + assertThat(actual.size()).isEqualTo(sourceMap.size()); + assertThat(actual.entrySet()) + .containsExactlyInAnyOrderElementsOf(sourceMap.entrySet()); +// assertThat(actual.entrySet(), +// both(everyItem(isIn(sourceMap.entrySet()))).and(containsInAnyOrder(sourceMap.entrySet().toArray()))); } /** @@ -163,9 +158,9 @@ public void testTransformWorksProperlyWithKeyMapping() { //THEN assertThat(actual).isNotNull(); - assertEquals(actual.size(), sourceMap.size()); - assertEquals(actual.get(MAP_KEY_1), sourceMap.get(MAP_KEY_1)); - assertEquals(actual.get(MAP_KEY_2), sourceMap.get(MAP_KEY_1)); + assertThat(actual.size()).isEqualTo(sourceMap.size()); + assertThat(actual.get(MAP_KEY_1)).isEqualTo(sourceMap.get(MAP_KEY_1)); + assertThat(actual.get(MAP_KEY_2)).isEqualTo(sourceMap.get(MAP_KEY_1)); underTest.resetFieldsMapping(); } @@ -185,8 +180,8 @@ public void testTransformWorksProperlyWithTransformer() { //THEN assertThat(actual).isNotNull(); - assertEquals(actual.size(), sourceMap.size()); - assertTrue(actual.containsKey(MAP_KEY_1.toUpperCase())); + assertThat(actual.size()).isEqualTo(sourceMap.size()); + assertThat(actual).containsKey(MAP_KEY_1.toUpperCase()); } /** @@ -215,10 +210,10 @@ public void testTransformWorksProperlyWithTargetKeyAndElemType() { //THEN assertThat(actual).isNotNull(); - assertEquals(actual.size(), EXTREME_COMPLEX_MAP.size()); + assertThat(actual.size()).isEqualTo(EXTREME_COMPLEX_MAP.size()); // check that the element has been converted for (Map.Entry entry : actual.entrySet()) { - assertEquals(MutableToFooSimple.class, entry.getKey().getClass()); + assertThat(entry.getKey().getClass()).isEqualTo(MutableToFooSimple.class); } } @@ -237,10 +232,10 @@ public void testTransformWorksProperlyWithMapContainingList() { //THEN assertThat(actual).isNotNull(); - assertEquals(actual.size(), sourceMap.size()); + assertThat(actual.size()).isEqualTo(sourceMap.size()); for (Map.Entry entry : actual.entrySet()) { - assertEquals(MutableToFooSimple.class, entry.getKey().getClass()); - assertEquals(sampleList, entry.getValue()); + assertThat(entry.getKey().getClass()).isEqualTo(MutableToFooSimple.class); + assertThat(entry.getValue()).isEqualTo(sampleList); } } @@ -258,7 +253,7 @@ public void testResetKeyTransformerWorksProperly() { (MapTransformerSettings) REFLECTION_UTILS.getFieldValue(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); //THEN - assertTrue(transformerSettings.getKeyFieldsTransformers().isEmpty()); + assertThat(transformerSettings.getKeyFieldsTransformers()).isEmpty(); underTest.resetKeyTransformer(); } } diff --git a/pom.xml b/pom.xml index 8fa7cd927..8549b9416 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,6 @@ 2.8.6 7.1.0 3.3.3 - 3.16.1 1.3.0 2.0.1.Final @@ -155,6 +154,18 @@ junit junit + + org.junit.jupiter + junit-jupiter + + + org.skyscreamer + jsonassert + + + org.junit.vintage + junit-vintage-engine + @@ -191,12 +202,6 @@ ${mockito-core.version} test - - org.assertj - assertj-core - ${assertj-core.version} - test - From 82129176a535a284af29ac996111a59f95e516f5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 12 Jun 2020 17:42:22 +0200 Subject: [PATCH 1120/1786] Fixes failing test --- .../beans/transformer/ImmutableObjectTransformationTest.java | 4 +++- .../src/test/java/com/hotels/beans/sample/FromFooSimple.java | 2 ++ .../hotels/beans/sample/immutable/ImmutableToFooSimple.java | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 7956fcf19..b2932c709 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -102,7 +102,9 @@ public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, Object actual = transformer.transform(sourceObject, targetObjectClass); //THEN - assertThat(actual).usingRecursiveComparison().isEqualTo(sourceObject); + assertThat(actual).usingRecursiveComparison() + .ignoringAllOverriddenEquals() + .isEqualTo(sourceObject); } /** diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java index 164564f56..7c3d909f6 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java @@ -19,6 +19,7 @@ import java.math.BigInteger; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -32,6 +33,7 @@ @Getter @Setter @ToString +@EqualsAndHashCode public class FromFooSimple { public String name; public BigInteger id; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java index f3d0fd587..cb6e12803 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java @@ -19,6 +19,7 @@ import java.math.BigInteger; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; /** @@ -26,6 +27,7 @@ */ @AllArgsConstructor @Getter +@EqualsAndHashCode public class ImmutableToFooSimple { private final String name; private final BigInteger id; From ccf7068d068460b48755d6f444dd2e06bf162ac9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 14 Jun 2020 11:23:13 +0200 Subject: [PATCH 1121/1786] Removes the dependency from spring-boot-starter-test --- bull-bean-transformer/pom.xml | 5 ++ .../AbstractBeanTransformerTest.java | 6 ++ .../transformer/BeanTransformerTest.java | 55 +++++++------- .../ImmutableObjectTransformationTest.java | 9 ++- .../MutableObjectTransformationTest.java | 3 +- .../transformer/utils/ReflectionUtils.java | 10 +++ .../transformer/utils/ClassUtilsTest.java | 3 +- pom.xml | 71 ++++++------------- 8 files changed, 75 insertions(+), 87 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 0a1e04191..9424c7691 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -25,5 +25,10 @@ test-jar test + + org.slf4j + slf4j-api + test + \ No newline at end of file diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index 6cd665c1a..3c998cb4f 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -23,6 +23,7 @@ import org.testng.annotations.BeforeMethod; import com.hotels.transformer.AbstractTransformerTest; +import com.hotels.transformer.utils.ReflectionUtils; /** * Unit test for {@link BeanTransformer}. @@ -34,6 +35,11 @@ public abstract class AbstractBeanTransformerTest extends AbstractTransformerTes @InjectMocks TransformerImpl underTest; + /** + * The reflection utils class. + */ + final ReflectionUtils reflectionUtils = new ReflectionUtils(); + /** * Initializes the arguments and objects. */ diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 902e2f4b2..c7c1cb663 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -27,7 +27,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.springframework.test.util.ReflectionTestUtils.setField; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -183,14 +182,14 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro @SuppressWarnings("unchecked") public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined() throws Exception { //GIVEN - ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + ReflectionUtils reflectionUtilsMock = mock(ReflectionUtils.class); Field field = mock(Field.class); Class fieldType = Integer.class; - when(reflectionUtils.getFieldValue(FromFooSimple.class, AGE_FIELD_NAME, fieldType)).thenThrow(InvalidBeanException.class); + when(reflectionUtilsMock.getFieldValue(FromFooSimple.class, AGE_FIELD_NAME, fieldType)).thenThrow(InvalidBeanException.class); when(field.getType()).thenReturn(fieldType); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); + reflectionUtils.setFieldValue(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtilsMock); Method getSourceFieldValueMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_VALUE_METHOD_NAME, Object.class, String.class, Field.class, boolean.class); getSourceFieldValueMethod.setAccessible(true); @@ -205,7 +204,7 @@ public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined } //THEN - verify(reflectionUtils).getFieldValue(FromFooSimple.class, AGE_FIELD_NAME, fieldType); + verify(reflectionUtilsMock).getFieldValue(FromFooSimple.class, AGE_FIELD_NAME, fieldType); verify(field).getType(); assertThat(raisedException).isNull(); assertThat(actual).isNull(); @@ -237,16 +236,16 @@ public void testThatPrimitiveTypeConversionIsCorrectlyEnabled() { public void testGetSourceFieldTypeReturnsTheSourceObjectClass() throws Exception { //GIVEN CacheManager cacheManager = mock(CacheManager.class); - ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + ReflectionUtils reflectionUtilsMock = mock(ReflectionUtils.class); ClassUtils classUtils = mock(ClassUtils.class); when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(empty()); - when(reflectionUtils.getDeclaredFieldType(AGE_FIELD_NAME, Integer.class)).thenThrow(MissingFieldException.class); + when(reflectionUtilsMock.getDeclaredFieldType(AGE_FIELD_NAME, Integer.class)).thenThrow(MissingFieldException.class); when(classUtils.isPrimitiveType(Integer.class)).thenReturn(true); - setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); - setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + reflectionUtils.setFieldValue(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); + reflectionUtils.setFieldValue(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtilsMock); + reflectionUtils.setFieldValue(underTest, CLASS_UTILS_FIELD_NAME, classUtils); Method getSourceFieldTypeMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_TYPE_METHOD_NAME, Class.class, String.class); getSourceFieldTypeMethod.setAccessible(true); @@ -256,7 +255,7 @@ public void testGetSourceFieldTypeReturnsTheSourceObjectClass() throws Exception //THEN verify(cacheManager).getFromCache(anyString(), any(Class.class)); - verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, Integer.class); + verify(reflectionUtilsMock).getDeclaredFieldType(AGE_FIELD_NAME, Integer.class); verify(classUtils).isPrimitiveType(Integer.class); assertThat(actual).isEqualTo(Integer.class); restoreUnderTestObject(); @@ -272,19 +271,19 @@ public void testGetSourceFieldTypeReturnsTheSourceObjectClass() throws Exception public void testGetSourceFieldTypeReturnsNull() throws Exception { //GIVEN CacheManager cacheManager = mock(CacheManager.class); - ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + ReflectionUtils reflectionUtilsMock = mock(ReflectionUtils.class); ClassUtils classUtils = mock(ClassUtils.class); TransformerSettings settings = mock(TransformerSettings.class); when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(empty()); - when(reflectionUtils.getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class)).thenThrow(MissingFieldException.class); + when(reflectionUtilsMock.getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class)).thenThrow(MissingFieldException.class); when(classUtils.isPrimitiveType(Integer.class)).thenReturn(true); when(settings.isSetDefaultValueForMissingField()).thenReturn(true); - setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); - setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); - setField(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); + reflectionUtils.setFieldValue(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); + reflectionUtils.setFieldValue(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtilsMock); + reflectionUtils.setFieldValue(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + reflectionUtils.setFieldValue(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); Method getSourceFieldTypeMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_TYPE_METHOD_NAME, Class.class, String.class); getSourceFieldTypeMethod.setAccessible(true); @@ -294,7 +293,7 @@ public void testGetSourceFieldTypeReturnsNull() throws Exception { //THEN verify(cacheManager).getFromCache(anyString(), any(Class.class)); - verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); + verify(reflectionUtilsMock).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); verify(classUtils).isPrimitiveType(FromFooSimple.class); verify(settings).isSetDefaultValueForMissingField(); assertThat(actual).isNull(); @@ -310,19 +309,19 @@ public void testGetSourceFieldTypeReturnsNull() throws Exception { public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception { //GIVEN CacheManager cacheManager = mock(CacheManager.class); - ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); + ReflectionUtils reflectionUtilsMock = mock(ReflectionUtils.class); ClassUtils classUtils = mock(ClassUtils.class); TransformerSettings settings = mock(TransformerSettings.class); when(cacheManager.getFromCache(anyString(), any(Class.class))).thenReturn(empty()); - when(reflectionUtils.getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class)).thenThrow(MissingFieldException.class); + when(reflectionUtilsMock.getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class)).thenThrow(MissingFieldException.class); when(classUtils.isPrimitiveType(Integer.class)).thenReturn(false); when(settings.isSetDefaultValueForMissingField()).thenReturn(false); - setField(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); - setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); - setField(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); + reflectionUtils.setFieldValue(underTest, CACHE_MANAGER_FIELD_NAME, cacheManager); + reflectionUtils.setFieldValue(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtilsMock); + reflectionUtils.setFieldValue(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + reflectionUtils.setFieldValue(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); Method getSourceFieldTypeMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_TYPE_METHOD_NAME, Class.class, String.class); getSourceFieldTypeMethod.setAccessible(true); @@ -337,7 +336,7 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception //THEN verify(cacheManager).getFromCache(anyString(), any(Class.class)); - verify(reflectionUtils).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); + verify(reflectionUtilsMock).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); verify(classUtils).isPrimitiveType(FromFooSimple.class); verify(settings).isSetDefaultValueForMissingField(); assertThat(raisedException).isNotNull(); @@ -364,7 +363,7 @@ public void testGetTransformedValueWorksProperly(final String testCaseDescriptio Field field = mock(Field.class); TransformerSettings settings = mock(TransformerSettings.class); when(settings.isPrimitiveTypeConversionEnabled()).thenReturn(isPrimitiveTypeConversionEnabled); - setField(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); + reflectionUtils.setFieldValue(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, settings); Class[] transformedValueMethodParams = {FieldTransformer.class, Object.class, Class.class, String.class, Field.class, boolean.class, String.class}; Method getTransformerFunctionMethod = underTest.getClass().getDeclaredMethod(GET_TRANSFORMER_VALUE_METHOD_NAME, transformedValueMethodParams); @@ -412,7 +411,7 @@ public void testGetConstructorArgsValuesReturnsTheDefaultTypeIfTheDestinationFie when(constructorParameter.getType()).thenReturn((Class) Integer.class); when(classUtils.getDefaultTypeValue(Integer.class)).thenReturn(ZERO.intValue()); - setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + reflectionUtils.setFieldValue(underTest, CLASS_UTILS_FIELD_NAME, classUtils); Method getConstructorArgsValuesMethod = underTest.getClass() .getDeclaredMethod(GET_CONSTRUCTOR_ARGS_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class); @@ -514,7 +513,7 @@ public void testHandleInjectionExceptionWorksAsExpected(final String testCaseDes when(classUtils.areParameterNamesAvailable(any(Constructor.class))).thenReturn(false); when(classUtils.getConstructorParameters(any())).thenReturn(new Parameter[] {}); when(classUtils.getInstance(any(), any())).thenReturn(new MutableToFoo()); - setField(underTest, CLASS_UTILS_FIELD_NAME, classUtils); + reflectionUtils.setFieldValue(underTest, CLASS_UTILS_FIELD_NAME, classUtils); Method handleInjectionExceptionMethod = underTest.getClass().getDeclaredMethod(HANDLE_INJECTION_EXCEPTION_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, Object[].class, boolean.class, Exception.class); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index b2932c709..39631f5a7 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -22,7 +22,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import static org.springframework.test.util.ReflectionTestUtils.setField; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -513,9 +512,9 @@ private void initGetDestFieldNameTestMock(final String declaringClassName, final ConstructorArg constructorArg = mock(ConstructorArg.class); when(constructorArg.value()).thenReturn(DEST_FIELD_NAME); // ReflectionUtils mock setup - ReflectionUtils reflectionUtils = mock(ReflectionUtils.class); - when(reflectionUtils.getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)).thenReturn(constructorArg); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtils); + ReflectionUtils reflectionUtilsMock = mock(ReflectionUtils.class); + when(reflectionUtilsMock.getParameterAnnotation(constructorParameter, ConstructorArg.class, declaringClassName)).thenReturn(constructorArg); + reflectionUtils.setFieldValue(underTest, REFLECTION_UTILS_FIELD_NAME, reflectionUtilsMock); } /** @@ -524,7 +523,7 @@ private void initGetDestFieldNameTestMock(final String declaringClassName, final */ private void restoreObjects(final Method getDestFieldNameMethod) { getDestFieldNameMethod.setAccessible(false); - setField(underTest, REFLECTION_UTILS_FIELD_NAME, new ReflectionUtils()); + reflectionUtils.setFieldValue(underTest, REFLECTION_UTILS_FIELD_NAME, new ReflectionUtils()); } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 40f5f1f42..975a9e1c5 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -25,7 +25,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import static org.springframework.test.util.ReflectionTestUtils.setField; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -376,7 +375,7 @@ public void testInjectValuesThrowsException() throws Exception { when(classUtils.getConstructorParameters(constructor)).thenReturn(new Parameter[] {}); when(classUtils.areParameterNamesAvailable(constructor)).thenReturn(true); doReturn(expectedException).when(underTestMock).handleInjectionException(any(), any(), any(), any(), any(), anyBoolean(), any()); - setField(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); + reflectionUtils.setFieldValue(underTestMock, CLASS_UTILS_FIELD_NAME, classUtils); Method injectValuesMethod = TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); injectValuesMethod.setAccessible(true); diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index 15db1a4ea..bcfe1b5d2 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -351,6 +351,16 @@ public Class getDeclaredFieldType(final String fieldName, final Class claz }); } + /** + * Set the value of a field. + * @param target the field's class + * @param fieldName the field name to set + * @param fieldValue the value to set + */ + public void setFieldValue(final Object target, final String fieldName, final Object fieldValue) { + setFieldValue(target, getDeclaredField(fieldName, target.getClass()), fieldValue); + } + /** * Set the value of a field. * @param target the field's class diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 8d0f4e230..5ecb7670a 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -47,7 +47,6 @@ import javax.validation.constraints.NotNull; import org.mockito.InjectMocks; -import org.springframework.test.util.ReflectionTestUtils; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -523,7 +522,7 @@ private Object[][] dataAreParameterNamesAvailableTesting() { */ private Constructor createMockedConstructor() { Parameter parameter = mock(Parameter.class); - ReflectionTestUtils.setField(parameter, "name", "paramName"); + new ReflectionUtils().setFieldValue(parameter, "name", "paramName"); when(parameter.isNamePresent()).thenReturn(false); Constructor constructor = mock(Constructor.class); when(constructor.getDeclaringClass()).thenReturn(ImmutableToFoo.class); diff --git a/pom.xml b/pom.xml index 8549b9416..1a3088d37 100644 --- a/pom.xml +++ b/pom.xml @@ -49,13 +49,14 @@ 11 ${jdk.version} ${jdk.version} - 2.3.0.RELEASE 1.18.12 3.10 - 2.8.6 - 7.1.0 - 3.3.3 1.3.0 + + 3.3.3 + 7.1.0 + 3.16.1 + 1.7.30 2.0.1.Final 6.1.5.Final @@ -132,42 +133,6 @@ ${hibernate-validator.version} - - org.springframework.boot - spring-boot-starter-test - ${spring-boot.version} - test - - - org.mockito - mockito-junit-jupiter - - - org.mockito - mockito-core - - - org.hamcrest - hamcrest - - - junit - junit - - - org.junit.jupiter - junit-jupiter - - - org.skyscreamer - jsonassert - - - org.junit.vintage - junit-vintage-engine - - - org.slf4j slf4j-api @@ -175,9 +140,9 @@ test - com.google.code.gson - gson - ${gson.version} + org.mockito + mockito-core + ${mockito-core.version} test @@ -197,9 +162,15 @@ - org.mockito - mockito-core - ${mockito-core.version} + org.assertj + assertj-core + ${assertj-core.version} + test + + + org.slf4j + slf4j-api + ${slf4j-api.version} test @@ -214,8 +185,8 @@ - org.springframework.boot - spring-boot-starter-test + org.mockito + mockito-core test @@ -224,8 +195,8 @@ test - org.mockito - mockito-core + org.assertj + assertj-core test From e32e0912523a394e7de21bf530013c0f60802978 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 14 Jun 2020 11:36:24 +0200 Subject: [PATCH 1122/1786] Adds in the CONTRIBUTING.md file the testing rules --- CONTRIBUTING.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 061a1652d..c4a41c373 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ Contributing [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/dwyl/esta/issues) ============ If you want to contribute to the project and make it better, your help is very welcome. Contributing is also a great way to learn more about social coding on Github, new -technologies and and their ecosystems and how to make constructive, helpful bug reports, feature requests and the noblest of all contributions: a good, clean pull request. +technologies and their ecosystems and how to make constructive, helpful bug reports, feature requests and the noblest of all contributions: a good, clean pull request. ### How to make a clean pull request @@ -13,7 +13,7 @@ technologies and and their ecosystems and how to make constructive, helpful bug - **The branch name should follow the best practices naming convention:** 1. Use grouping tokens (words) at the beginning of your branch names. * `feature`: Feature I'm adding or expanding - * `bug`: Bug fix or experiment + * `bug`: Bugfix or experiment * `wip`: Work in progress; stuff I know won't be finished soon 2. Define and use short lead tokens to differentiate branches in a way that is meaningful to your workflow. 3. Use slashes to separate parts of your branch names. @@ -27,8 +27,16 @@ technologies and and their ecosystems and how to make constructive, helpful bug - Squash your commits into a single commit with git's [interactive rebase](https://help.github.com/articles/interactive-rebase). Create a new branch if necessary. - Push your branch to your fork on Github, the remote `origin`. - From your fork open a pull request in the correct branch. Target the project's `develop` branch if there is one, else go for `master`! -- If the maintainer requests further changes just push them to your branch. The PR will be updated automatically. +- If the maintainer requests further change just push them to your branch. The pull request will be updated automatically. - Once the pull request is approved and merged you can [pull the changes from upstream](https://help.github.com/articles/syncing-a-fork/) to your local repo and delete your extra branch(es). -And last but not least: Always write your commit messages in the present tense. Your commit message should describe what the commit, when applied, does to the code – not what you -did to the code. \ No newline at end of file +And last but not least: Always write your commit messages in the present tense. Your commit message should describe what the commit when applied, does to the code – not what you +did to the code. + +### Testing + +- The new code should be tested enough to meet the expected coverage +- The default libraries for testing implementations are: +    1. AssertJ for the assertion +    2. Mockito for the object mocking +    3. Testng for testing annotations and data provider \ No newline at end of file From f4e98e3e069685e3ab3b0f032b852cbeac82878e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2020 02:24:39 +0000 Subject: [PATCH 1123/1786] Bump spring-boot-starter-test from 2.3.0.RELEASE to 2.3.1.RELEASE Bumps [spring-boot-starter-test](https://github.com/spring-projects/spring-boot) from 2.3.0.RELEASE to 2.3.1.RELEASE. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.3.0.RELEASE...v2.3.1.RELEASE) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e7dc5e5b9..87417b34c 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 11 ${jdk.version} ${jdk.version} - 2.3.0.RELEASE + 2.3.1.RELEASE 1.18.12 3.10 0.11 From 7c5dbf3b982e7ea4b4554293459be400ae31b9d3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Jun 2020 05:55:16 +0200 Subject: [PATCH 1124/1786] Removes from CHANGELOG-JDK8.md and CHANGELOG.md all the changes not relevant for the release --- CHANGELOG-JDK8.md | 44 ++++++-------------------------------------- CHANGELOG.md | 43 +++++++------------------------------------ 2 files changed, 13 insertions(+), 74 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 8e2ab2d8d..670f85f57 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -9,9 +9,7 @@ All notable changes to this project will be documented in this file. ### [1.7.1-jdk8] 2020.06.09 #### Changed * Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` -* Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). * Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). -* Updated `spring-boot-starter-test` version to `2.3.0.RELEASE` (was `2.2.6.RELEASE`). ### [1.7.0-jdk8] 2020.03.20 #### Added @@ -20,24 +18,15 @@ All notable changes to this project will be documented in this file. * Updated `hibernate-validator` version to `6.1.3.Final` (was `6.1.2.Final`). ### [1.6.5-jdk8] 2020.03.16 -### Added -* Added `maven-spotless-plugin` for the code automatic formatting during the maven build -* Added `coveralls-maven-plugin` for the test coverage analysis and report during the maven build: [Coverall report](https://coveralls.io/github/HotelsDotCom/bull) #### Changed -* Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). -* Updated `mockito-core` version to `3.3.3` (was `3.2.4`). -* Updated `spring-boot-starter-test` version to `2.2.6.RELEASE` (was `2.2.4.RELEASE`). -* Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). * Updated `commons-lang3` version to `3.10` (was `3.9`). -### [1.6.4-jdk8] 2020.01.21 +### [1.6.5] 2020.01.21 #### Changed -* Updated `testng` version to `7.1.0` (was `7.0.0`). -* Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). -* Updated `hibernate-validator` version to `6.1.2.Final` (was `6.1.0.Final`). +* Testing dependencies update -### [1.6.3.2-jdk8] 2019.12.24 +### [1.6.4] 2019.12.24 #### Added * Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). * Implemented transformation of a field declared with its interface. @@ -45,17 +34,11 @@ All notable changes to this project will be documented in this file. ### [1.6.3.1-jdk8] 2019.12.19 #### Added * Added method for retrieving the class getter methods. -#### Changed -* Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). -* Updated `mockito-core` version to `3.2.4` (was `3.2.0`). -* Updated `slf4j-api` version to `1.7.30` (was `1.7.29`). ### [1.6.3-jdk8] 2019.12.02 ### Added * Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. * Modified Travis configuration in order to test the compatibility with other JDKs versions -#### Changed -* Updated maven wrapper version to `3.6.3` (was `3.6.2`). ### [1.6.2-jdk8] 2019.11.27 #### Changed @@ -68,13 +51,9 @@ All notable changes to this project will be documented in this file. ### [1.1.26] 2019.11.18 ### Added -* Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. +* Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. #### Changed * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). -* Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). -* Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). -* Updated `spring-boot-starter-test` version to `2.2.1.RELEASE` (was `2.2.0.RELEASE`). -* Updated `wagon-ssh` version to `3.3.4` (was `3.3.3`). ### [1.1.25] 2019.10.30 ### Removed @@ -88,12 +67,6 @@ All notable changes to this project will be documented in this file. * Implemented a new functionality that allows to transform also Map object applying transformation function and mappings #### Changed * `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` -* Updated `spring-boot-starter-test` version to `2.2.0.RELEASE` (was `2.1.7.RELEASE`). -* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). -* Updated `testng` version to `7.0.0` (was `6.14.3`). -* Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). -* Updated `jacoco-maven-plugin` version to `0.8.4` (was `0.8.2`). -* Updated `lombok` version to `1.18.10` (was `1.18.8`). * Updated `hibernate-validator` version to `6.1.0.Final` (was `6.0.17.Final`). ### [1.1.24] 2019.09.02 @@ -145,7 +118,7 @@ All notable changes to this project will be documented in this file. ### [1.1.18] 2019.05.18 #### Changed * Removed deprecated method: `setValidationDisabled` -* Updated dependencies +* * Testing dependencies update ### [1.1.17] 2019.05.13 #### Changed @@ -176,12 +149,9 @@ All notable changes to this project will be documented in this file. ### [1.1.10] 2019.03.31 #### Added * Improved field value retrieval function. -* Added link to Gitter channel for BULL. -* Integrated Gitter notification in order to keep up to date BULL community ### [1.1.9] 2019.03.23 #### Changed -* Updated `spring-boot-starter-test` version to `2.1.3.RELEASE` (was `2.1.2.RELEASE`). * Added caching for method: `getDeclaredField` ### [1.1.8] 2019.03.22 @@ -191,7 +161,7 @@ All notable changes to this project will be documented in this file. ### [1.1.7] 2019.03.20 #### Changed -* Replaced `junit` test with `testng` +* Testing dependencies update ### [1.1.6] 2019.03.05 #### Added @@ -228,8 +198,6 @@ All notable changes to this project will be documented in this file. * Improved readme file ### [1.1.0] 2019.02.04 -#### Changed -* Improved travis configuration #### Added * Added dependency to: `slf4j-api` as no longer available from Spring. - Added ValidationUtils class for raising an `IllegalArgumentException` in case any parameter is null. diff --git a/CHANGELOG.md b/CHANGELOG.md index d2bb4c53c..01225ff03 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,7 @@ All notable changes to this project will be documented in this file. ### [1.7.2] 2020.06.09 #### Changed * Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` -* Updated `wagon-ssh` version to `3.4.0` (was `3.3.4`). * Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). -* Updated `spring-boot-starter-test` version to `2.3.0.RELEASE` (was `2.2.6.RELEASE`). ### [1.7.1] 2020.03.21 #### Added @@ -20,22 +18,13 @@ All notable changes to this project will be documented in this file. * Updated `hibernate-validator` version to `6.1.4.Final` (was `6.1.2.Final`). ### [1.6.6] 2020.03.16 -### Added -* Added `maven-spotless-plugin` for the code automatic formatting during the maven build -* Added `coveralls-maven-plugin` for the test coverage analysis and report during the maven build: [Coverall report](https://coveralls.io/github/HotelsDotCom/bull) #### Changed -* Updated `lombok` version to `1.18.12` (was `1.18.10`). * Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). -* Updated `mockito-core` version to `3.3.3` (was `3.2.4`). -* Updated `spring-boot-starter-test` version to `2.2.6.RELEASE` (was `2.2.4.RELEASE`). -* Updated `maven-site-plugin` version to `3.9.0` (was `3.8.2`). * Updated `commons-lang3` version to `3.10` (was `3.9`). ### [1.6.5] 2020.01.21 #### Changed -* Updated `testng` version to `7.1.0` (was `7.0.0`). -* Updated `spring-boot-starter-test` version to `2.2.4.RELEASE` (was `2.2.3.RELEASE`). -* Updated `hibernate-validator` version to `6.1.2.Final` (was `6.1.0.Final`). +* Testing dependencies update ### [1.6.4] 2019.12.24 #### Added @@ -43,21 +32,17 @@ All notable changes to this project will be documented in this file. * Implemented transformation of a field declared with its interface. ### [1.6.3.2] 2019.12.19 -#### Changed +#### Added * Added method for retrieving the class getter methods. ### [1.6.3.1] 2019.12.09 #### Changed -* Updated `spring-boot-starter-test` version to `2.2.2.RELEASE` (was `2.2.1.RELEASE`). -* Updated `mockito-core` version to `3.2.4` (was `3.2.0`). -* Updated `slf4j-api` version to `1.7.30` (was `1.7.29`). +* Testing dependencies update ### [1.6.3] 2019.12.02 ### Added * Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. * Modified Travis configuration in order to test the compatibility with other JDKs versions -#### Changed -* Updated maven wrapper version to `3.6.3` (was `3.6.2`). ### [1.6.2] 2019.11.22 #### Changed @@ -69,10 +54,6 @@ All notable changes to this project will be documented in this file. * Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. #### Changed * Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). -* Updated `jacoco-maven-plugin` version to `0.8.5` (was `0.8.3`). -* Updated `slf4j-api` version to `1.7.29` (was `1.7.28`). -* Updated `spring-boot-starter-test` version to `2.2.1.RELEASE` (was `2.2.0.RELEASE`). -* Updated `wagon-ssh` version to `3.3.4` (was `3.3.3`). ### [1.6.0.2] 2019.10.30 ### Removed @@ -86,11 +67,6 @@ All notable changes to this project will be documented in this file. * Implemented a new functionality that allows to transform also Map object applying transformation function and mappings #### Changed * `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` -* Updated `spring-boot-starter-test` version to `2.2.0.RELEASE` (was `2.1.7.RELEASE`). -* Updated `testng` version to `7.0.0` (was `6.14.3`). -* Updated `slf4j-api` version to `1.7.28` (was `1.7.27`). -* Updated `jacoco-maven-plugin` version to `0.8.4` (was `0.8.2`). -* Updated `lombok` version to `1.18.10` (was `1.18.8`). * Updated `hibernate-validator` version to `6.1.0.Final` (was `6.0.17.Final`). ### [1.5.1] 2019.09.02 @@ -156,7 +132,7 @@ All notable changes to this project will be documented in this file. ### [1.4.1] 2019.05.18 #### Changed * Removed deprecated method: `setValidationDisabled` -* Updated dependencies +* Testing dependencies update ### [1.4.0] 2019.05.13 #### Changed @@ -181,7 +157,7 @@ All notable changes to this project will be documented in this file. ### [1.2.7] 2019.04.18 #### Changed * Improved optional usage. -* Fixed bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). +* Fixed a bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). ### [1.2.6] 2019.04.06 #### Added @@ -190,12 +166,9 @@ All notable changes to this project will be documented in this file. ### [1.2.5] 2019.03.31 #### Added * Improved field value retrieval function. -* Added link to Gitter channel for BULL. -* Integrated Gitter notification in order to keep up to date BULL community ### [1.2.4] 2019.03.23 #### Changed -* Updated `spring-boot-starter-test` version to `2.1.3.RELEASE` (was `2.1.2.RELEASE`). * Added caching for method: `getDeclaredField` ### [1.2.3] 2019.03.22 @@ -205,7 +178,7 @@ All notable changes to this project will be documented in this file. ### [1.2.2] 2019.03.20 #### Changed -* Replaced `junit` test with `testng` +* Testing dependencies update ### [1.2.1] 2019.03.05 #### Added @@ -215,7 +188,7 @@ All notable changes to this project will be documented in this file. ### [1.2.0] 2019.02.25 #### Added * Added possibility to skip the object validation (see: [Issue 31](https://github.com/HotelsDotCom/bull/issues/31)) -* Added documentation and samples for the above functionality +* Provided documentation and samples for the above functionality ### Changed - Updated `jdk` version to `11` (was `1.8`). - Updated Travis configuration in order to work with java 11 @@ -247,8 +220,6 @@ All notable changes to this project will be documented in this file. * Improved readme file ### [1.1.0] 2019.02.04 -#### Changed -* Improved travis configuration #### Added * Added dependency to: `slf4j-api` as no longer available from Spring. - Added ValidationUtils class for raising an `IllegalArgumentException` in case any parameter is null. From 9bb671e6a8d55a343c23551b05f79ae99454e066 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Jun 2020 08:54:05 +0200 Subject: [PATCH 1125/1786] Makes the dependencies in the same order as master --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index a32c6f540..9434ac0a0 100644 --- a/pom.xml +++ b/pom.xml @@ -186,8 +186,8 @@ - org.mockito - mockito-core + org.assertj + assertj-core test @@ -196,8 +196,8 @@ test - org.assertj - assertj-core + org.mockito + mockito-core test From 56a51755e9f9ce40fbb01e32686910053970d323 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 15 Jun 2020 09:07:00 +0200 Subject: [PATCH 1126/1786] Minor: restores a removed line --- CHANGELOG-JDK8.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 670f85f57..c08644ae2 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -67,6 +67,7 @@ All notable changes to this project will be documented in this file. * Implemented a new functionality that allows to transform also Map object applying transformation function and mappings #### Changed * `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` +* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). * Updated `hibernate-validator` version to `6.1.0.Final` (was `6.0.17.Final`). ### [1.1.24] 2019.09.02 @@ -118,7 +119,7 @@ All notable changes to this project will be documented in this file. ### [1.1.18] 2019.05.18 #### Changed * Removed deprecated method: `setValidationDisabled` -* * Testing dependencies update +* Testing dependencies update ### [1.1.17] 2019.05.13 #### Changed From 07b28a38ba20a47a560a9ff7a34ff4be135b9dab Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2020 02:35:02 +0000 Subject: [PATCH 1127/1786] Bump maven-site-plugin from 3.9.0 to 3.9.1 Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.9.0 to 3.9.1. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.9.0...maven-site-plugin-3.9.1) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 87417b34c..0ef58b637 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.4.0 0.12 github - 3.9.0 + 3.9.1 3.1.1 false From 7015c4b2806ac51a83bb6582d3d92879f5768b79 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 25 Jun 2020 14:11:30 +0200 Subject: [PATCH 1128/1786] Update bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java Co-authored-by: Matteo Mirk --- .../java/com/hotels/beans/populator/PopulatorFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index 4bf9816dc..4ffd68e94 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -90,7 +90,7 @@ public void testGetPopulatorReturnsTheExpectedResult(final Class type, final Cla final boolean isNonNullObjectExpected = nonNull(expectedResult); assertThat(populator.isPresent()).isEqualTo(isNonNullObjectExpected); if (isNonNullObjectExpected) { - assertThat(populator.get().getClass()).isEqualTo(expectedResult); + assertThat(populator).containsInstanceOf(expectedResult); } } } From 8feb373358cfdc0992f15b1f5fb619fbc06f0966 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 26 Jun 2020 07:07:22 +0200 Subject: [PATCH 1129/1786] Update bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java Assertion improvement Co-authored-by: Matteo Mirk --- .../com/hotels/map/transformer/MapTransformerTest.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 4d6dcb858..015ea2fab 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -120,12 +120,7 @@ public void testTransformWorksProperly(final String testCaseDescription, Map actual = underTest.transform(sourceMap); //THEN - assertThat(actual).isNotNull(); - assertThat(actual.size()).isEqualTo(sourceMap.size()); - assertThat(actual.entrySet()) - .containsExactlyInAnyOrderElementsOf(sourceMap.entrySet()); -// assertThat(actual.entrySet(), -// both(everyItem(isIn(sourceMap.entrySet()))).and(containsInAnyOrder(sourceMap.entrySet().toArray()))); + assertThat(actual).isEqualTo(sourceMap); } /** From 611a014b24117fd8f1ae4b17cdf1c03d4911a0e1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 26 Jun 2020 07:09:16 +0200 Subject: [PATCH 1130/1786] Update bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java Assertion improvements Co-authored-by: Matteo Mirk --- .../java/com/hotels/beans/transformer/BeanTransformerTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index c7c1cb663..c39fe9224 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -426,8 +426,7 @@ public void testGetConstructorArgsValuesReturnsTheDefaultTypeIfTheDestinationFie verify(constructorParameter, times(2)).getName(); verify(constructorParameter).getType(); verify(classUtils).getDefaultTypeValue(Integer.class); - assertThat(actual.length).isEqualTo(ONE.intValue()); - assertThat(actual[ZERO.intValue()]).isEqualTo(ZERO.intValue()); + assertThat(actual).containsOnly(0); restoreUnderTestObject(); } From 4a262cc08e02f616099a32998c78ae70f4a9d624 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 26 Jun 2020 07:09:54 +0200 Subject: [PATCH 1131/1786] Update bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java Co-authored-by: Matteo Mirk --- .../java/com/hotels/beans/transformer/BeanTransformerTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index c39fe9224..208fad678 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -527,8 +527,7 @@ public void testHandleInjectionExceptionWorksAsExpected(final String testCaseDes } //THEN - assertThat(actual).isNotNull(); - assertThat(actual.getClass()).isEqualTo(expectedReturnType); + assertThat(actual).isInstanceOf(expectedReturnType); restoreUnderTestObject(); } From 58cbe7f868e5074951bdaf35d0744550ddb8b7af Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 26 Jun 2020 07:14:11 +0200 Subject: [PATCH 1132/1786] Update bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java Co-authored-by: Matteo Mirk --- .../beans/transformer/MutableObjectTransformationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 975a9e1c5..0890398fd 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -129,8 +129,8 @@ public void testFieldTransformationIsAppliedOnlyToASpecificField() { .transform(fromFoo, MutableToFoo.class); //THEN - assertThat(actual.getName()).isEqualTo(fromFoo.getName()); - assertThat(actual.getNestedObject().getName()).isEqualTo(namePrefix + fromFoo.getNestedObject().getName()); + assertThat(actual).extracting("name", "nestedObject.name") + .containsExactly(fromFoo.getName(), namePrefix + fromFoo.getNestedObject().getName()); underTest.resetFieldsTransformer(); } From edfc2fbced1ead24aea1957e32e400ba5612ac27 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 26 Jun 2020 07:17:44 +0200 Subject: [PATCH 1133/1786] Update bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java Co-authored-by: Matteo Mirk --- .../beans/transformer/MixedObjectTransformationTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 952733083..5b2e25e1d 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -168,9 +168,7 @@ public void testFieldTransformationSkipWorksProperly() { MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); //THEN - assertThat(actual.getId()).isEqualTo(fromFoo.getId()); - assertThat(actual.getName()).isNull(); - assertThat(actual.getNestedObject().getPhoneNumbers()).isNull(); + assertThat(actual).hasNoNullFieldsOrPropertiesExcept(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); underTest.resetFieldsTransformationSkip(); } From bbc679d6927c09be23e7f7bd37be608e2d32e128 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 12:29:34 +0200 Subject: [PATCH 1134/1786] Update bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java Co-authored-by: Matteo Mirk --- .../beans/transformer/BuilderObjectTransformationTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 8f50fd51f..2ce02da02 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -45,7 +45,8 @@ public void testTransformationThroughBuilder(final String testDescription, final Object actual = underTest.transform(sourceObject, targetObjectClass); //THEN - assertThat(actual).usingRecursiveComparison().isEqualTo(sourceObject); + assertThat(actual).usingRecursiveComparison() + .isEqualTo(sourceObject); underTest.setCustomBuilderTransformationEnabled(false); } From 7cf9df9d867b6863b65d9477926cca9945a130be Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 13:35:13 +0200 Subject: [PATCH 1135/1786] Update bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java Co-authored-by: Matteo Mirk --- .../beans/transformer/MixedObjectTransformationTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 5b2e25e1d..1103ec494 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -50,7 +50,8 @@ public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { MixedToFooMissingAllArgsConstructor actual = underTest.transform(fromFoo, MixedToFooMissingAllArgsConstructor.class); //THEN - assertThat(actual).usingRecursiveComparison().isEqualTo(fromFoo); + assertThat(actual).usingRecursiveComparison() + .isEqualTo(fromFoo); } /** From 78430a2d12b55e5acc75b55f41f2794455572fe1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 13:36:30 +0200 Subject: [PATCH 1136/1786] Changes as per PR --- .../java/com/hotels/beans/BeanUtilsTest.java | 4 +- .../beans/populator/ArrayPopulatorTest.java | 14 ++--- .../transformer/BeanTransformerTest.java | 1 - .../ImmutableObjectTransformationTest.java | 55 ++++++++----------- .../map/transformer/MapTransformerTest.java | 3 +- 5 files changed, 34 insertions(+), 43 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java index 34465187c..76d2fbe97 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -105,7 +105,9 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip //THEN assertThat(transformerFunction).isNotNull(); IntStream.range(0, actual.size()) - .forEach(i -> assertThat(actual.get(i)).isEqualToComparingFieldByField(fromFooSimpleList.get(i)).usingRecursiveComparison()); + .forEach(i -> assertThat(actual.get(i)) + .isEqualToComparingFieldByField(fromFooSimpleList.get(i)) + .usingRecursiveComparison()); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 743debd5a..70f47c48c 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -25,8 +25,6 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import java.util.stream.IntStream; - import org.mockito.InjectMocks; import org.mockito.Mock; import org.testng.annotations.BeforeClass; @@ -48,6 +46,7 @@ public class ArrayPopulatorTest { private static final int ZERO = 0; private static final int[] INT_ARRAY = new int[] {ZERO}; private static final MixedToFooStaticField MIXED_TO_FOO_STATIC_FIELDS_OBJECTS = new MixedToFooStaticField(); + private static final String NORMAL_FIELD = "normalField"; @Mock private BeanTransformer transformer; @@ -88,10 +87,9 @@ public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, } else if (genericFieldType == Object.class) { assertThat((Object[]) actual).isEqualTo(array); } else if (genericFieldType == MixedToFooStaticField.class) { - final MixedToFooStaticField[] expectedArray = (MixedToFooStaticField[]) array; - final Object[] actualArray = (Object[]) actual; - IntStream.range(0, expectedArray.length) - .forEach(i -> assertThat(((MixedToFooStaticField) actualArray[i]).getNormalField()).isEqualTo(expectedArray[i].getNormalField())); + assertThat((Object[]) actual) + .usingElementComparatorOnFields(NORMAL_FIELD) + .isEqualTo(array); } else { assertThat((Object[]) actual).isEqualTo(array); } @@ -125,7 +123,7 @@ private static MixedToFooStaticField[] createMixedToFooArray() { * Creates an array containing an instance of {@link Boolean}. * @return an array containing an instance of {@link Boolean}. */ - private static Object[] createBooleanArray() { - return new Object[] {TRUE, FALSE}; + private static Boolean[] createBooleanArray() { + return new Boolean[] {TRUE, FALSE}; } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 208fad678..5a0d79eb2 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -16,7 +16,6 @@ package com.hotels.beans.transformer; -import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; import static java.util.Optional.empty; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 39631f5a7..4c189d8ff 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -19,6 +19,7 @@ import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -29,8 +30,8 @@ import java.math.BigInteger; import java.util.Locale; import java.util.Optional; -import java.util.stream.IntStream; +import org.assertj.core.api.ThrowableAssert; import org.testng.annotations.AfterMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -75,6 +76,7 @@ public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTe private static final String GROSS_PRICE_FIELD_NAME = "price.grossPrice"; private static final String WORK_FIELD_NAME = "work"; private static final boolean ACTIVE = true; + private static final String LOCALE_LANGUAGE_FIELD_NAME = "locale.language"; /** * After method actions. @@ -138,7 +140,9 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { underTest.setValidationEnabled(true).transform(fromFooSimple, immutableToFoo); //THEN - assertThat(immutableToFoo).usingRecursiveComparison().isEqualTo(fromFooSimple); + assertThat(immutableToFoo) + .usingRecursiveComparison() + .isEqualTo(fromFooSimple); underTest.setValidationEnabled(false); } @@ -164,9 +168,8 @@ public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(f ImmutableFlatToFoo actual = underTestMock.withFieldMapping(phoneNumbersMapping).transform(sourceObject, ImmutableFlatToFoo.class); //THEN - assertThat(actual.getName()).isEqualTo(expectedName); - assertThat(actual.getId()).isEqualTo(expectedId); - assertThat(actual.getPhoneNumbers()).isEqualTo(expectedPhoneNumbers); + assertThat(actual).extracting(NAME_FIELD_NAME, ID_FIELD_NAME, PHONE_NUMBER_DEST_FIELD_NAME) + .containsExactly(expectedName, expectedId, expectedPhoneNumbers); } /** @@ -253,12 +256,10 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); //THEN - assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, actual.getName()); - assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()); - assertThat(actual.getList()).usingRecursiveComparison().isEqualTo(fromFoo.getList()); - IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i)).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObjectList().get(i))); - assertThat(actual.getNestedObject()).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObject()); + assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()) + .usingRecursiveComparison() + .ignoringFields(IDENTIFIER_FIELD_NAME) + .isEqualTo(fromFoo); } /** @@ -272,23 +273,21 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String testCaseDescription, final FromFooAdvFields sourceObject, final Class targetObjectClass, final boolean isNameFieldEmpty) { //GIVEN - - //WHEN final BeanTransformer beanTransformer = underTest .withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)) .withFieldMapping(new FieldMapping<>(PRICE_FIELD_NAME, NET_PRICE_FIELD_NAME)) .withFieldMapping(new FieldMapping<>(PRICE_FIELD_NAME, GROSS_PRICE_FIELD_NAME)) .withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); + + //WHEN ImmutableToFooAdvFields actual = (ImmutableToFooAdvFields) beanTransformer.transform(sourceObject, targetObjectClass); //THEN - assertThat(actual).isNotNull(); - assertThat(actual.getName().isPresent()).isEqualTo(isNameFieldEmpty); - sourceObject.getName().ifPresent(name -> assertThat(actual.getName().get()).isEqualTo(name)); - assertThat(sourceObject.getAge().isPresent()).isTrue(); - assertThat(actual.getAge()).isEqualTo(sourceObject.getAge().get()); - assertThat(actual.getClassType()).isEqualTo(sourceObject.getClassType()); - assertThat(actual.getLocale().getLanguage()).isEqualTo(sourceObject.getLocale()); + assertThat(actual).usingRecursiveComparison() + .ignoringFields(AGE_FIELD_NAME, PRICE_FIELD_NAME, LOCALE_FIELD_NAME) + .isEqualTo(sourceObject); + assertThat(actual).extracting(AGE_FIELD_NAME, NET_PRICE_FIELD_NAME, GROSS_PRICE_FIELD_NAME, LOCALE_LANGUAGE_FIELD_NAME) + .containsExactly(sourceObject.getAge().orElse(null), sourceObject.getPrice(), sourceObject.getPrice(), sourceObject.getLocale()); } /** @@ -415,17 +414,11 @@ public void testTransformationReturnsAMeaningfulException() { format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getName()); //WHEN - Exception raisedException = null; - try { - underTest.transform(fromFooSimple, targetClass); - } catch (final Exception e) { - raisedException = e; - } + ThrowableAssert.ThrowingCallable code = () -> underTest.transform(fromFooSimple, targetClass); //THEN - assertThat(raisedException).isNotNull(); - assertThat(raisedException.getClass()).isEqualTo(InvalidBeanException.class); - assertThat(raisedException.getMessage()).isEqualTo(expectedExceptionMessage); + assertThatThrownBy(code).isInstanceOf(InvalidBeanException.class) + .hasMessage(expectedExceptionMessage); } /** @@ -457,9 +450,7 @@ public void testFieldTransformationSkipWorksProperly() { ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); //THEN - assertThat(actual.getId()).isEqualTo(fromFoo.getId()); - assertThat(actual.getName()).isNull(); - assertThat(actual.getNestedObject().getPhoneNumbers()).isNull(); + assertThat(actual).hasNoNullFieldsOrPropertiesExcept(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); underTest.resetFieldsTransformationSkip(); } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 015ea2fab..bc971117f 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -208,7 +208,8 @@ public void testTransformWorksProperlyWithTargetKeyAndElemType() { assertThat(actual.size()).isEqualTo(EXTREME_COMPLEX_MAP.size()); // check that the element has been converted for (Map.Entry entry : actual.entrySet()) { - assertThat(entry.getKey().getClass()).isEqualTo(MutableToFooSimple.class); + assertThat(entry.getKey().getClass()) + .isEqualTo(MutableToFooSimple.class); } } From fba0644da20427a70cb1c93f4ecdf220dd589890 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 14:45:48 +0200 Subject: [PATCH 1137/1786] Changes as per PR --- .../MixedObjectTransformationTest.java | 27 ++++--- .../MutableObjectTransformationTest.java | 72 ++++++++++--------- .../immutable/ImmutableToFooSimple.java | 2 + .../transformer/cache/CacheManagerTest.java | 8 +-- .../transformer/utils/ClassUtilsTest.java | 25 ++++--- .../utils/ReflectionUtilsTest.java | 10 +-- 6 files changed, 72 insertions(+), 72 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index 1103ec494..bdf463efa 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.assertThat; import java.math.BigInteger; -import java.util.stream.IntStream; import org.testng.annotations.Test; @@ -65,7 +64,8 @@ public void testMixedBeanIsCorrectlyCopied() { MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); //THEN - assertThat(actual).usingRecursiveComparison().isEqualTo(fromFoo); + assertThat(actual).usingRecursiveComparison() + .isEqualTo(fromFoo); } /** @@ -80,12 +80,10 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); //THEN - assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, fromFoo.getName()); - assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()); - assertThat(actual.getList()).usingRecursiveComparison().isEqualTo(fromFoo.getList()); - IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i)).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObjectList().get(i))); - assertThat(actual.getNestedObject()).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObject()); + assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()) + .usingRecursiveComparison() + .ignoringFields(IDENTIFIER_FIELD_NAME) + .isEqualTo(fromFoo); } /** @@ -105,12 +103,10 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTra MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); //THEN - assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, fromFoo.getName()); - assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId().negate()); - assertThat(actual.getList()).usingRecursiveComparison().isEqualTo(fromFoo.getList()); - IntStream.range(0, actual.getNestedObjectList().size()) - .forEach(i -> assertThat(actual.getNestedObjectList().get(i)).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObjectList().get(i))); - assertThat(actual.getNestedObject()).usingRecursiveComparison().isEqualTo(fromFoo.getNestedObject()); + assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId().negate()) + .usingRecursiveComparison() + .ignoringFields(IDENTIFIER_FIELD_NAME) + .isEqualTo(fromFoo); } /** @@ -185,6 +181,7 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { underTest.skipTransformationForField().transform(fromFoo, mixedToFoo); //THEN - assertThat(mixedToFoo).usingRecursiveComparison().isEqualTo(fromFoo); + assertThat(mixedToFoo).usingRecursiveComparison() + .isEqualTo(fromFoo); } } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 0890398fd..c0361debf 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -19,6 +19,7 @@ import static java.lang.Integer.parseInt; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doReturn; @@ -30,6 +31,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Parameter; +import org.assertj.core.api.ThrowableAssert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -56,6 +58,9 @@ public class MutableObjectTransformationTest extends AbstractBeanTransformerTest private static final String PRICE_FIELD_NAME = "price"; private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; private static final String INJECT_VALUES_METHOD_NAME = "injectValues"; + private static final String NESTED_OBJECT_NAME_FIELD_NAME = "nestedObject.name"; + private static final String ACTIVE_FIELD_NAME = "active"; + private static final String CODE_FIELD_NAME = "code"; /** * Test that an exception is thrown if there is no default constructor defined for the mutable bean object. @@ -79,7 +84,8 @@ public void testMutableBeanIsCorrectlyCopied() { MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); //THEN - assertThat(actual).usingRecursiveComparison().isEqualTo(fromFoo); + assertThat(actual).usingRecursiveComparison() + .isEqualTo(fromFoo); } /** @@ -94,7 +100,8 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { underTest.transform(fromFooSubClass, mutableToFoo); //THEN - assertThat(mutableToFoo).usingRecursiveComparison().isEqualTo(fromFooSubClass); + assertThat(mutableToFoo).usingRecursiveComparison() + .isEqualTo(fromFooSubClass); } /** @@ -110,7 +117,8 @@ public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotVali underTest.transform(fromFooSubClass, mutableToFoo); //THEN - assertThat(mutableToFoo).usingRecursiveComparison().isEqualTo(fromFooSubClass); + assertThat(mutableToFoo).usingRecursiveComparison() + .isEqualTo(fromFooSubClass); fromFooSubClass.setId(ID); } @@ -121,7 +129,7 @@ public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotVali public void testFieldTransformationIsAppliedOnlyToASpecificField() { //GIVEN String namePrefix = "prefix-"; - FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", val -> namePrefix + val); + FieldTransformer nameTransformer = new FieldTransformer<>(NESTED_OBJECT_NAME_FIELD_NAME, val -> namePrefix + val); //WHEN MutableToFoo actual = underTest @@ -129,7 +137,8 @@ public void testFieldTransformationIsAppliedOnlyToASpecificField() { .transform(fromFoo, MutableToFoo.class); //THEN - assertThat(actual).extracting("name", "nestedObject.name") + assertThat(actual) + .extracting(NAME_FIELD_NAME, NESTED_OBJECT_NAME_FIELD_NAME) .containsExactly(fromFoo.getName(), namePrefix + fromFoo.getNestedObject().getName()); underTest.resetFieldsTransformer(); } @@ -151,7 +160,8 @@ public void testFieldTransformationIsAppliedToAllMatchingFields() { //THEN assertThat(actual.getName()).isEqualTo(namePrefix + fromFoo.getName()); - assertThat(actual.getNestedObject().getName()).isEqualTo(namePrefix + fromFoo.getNestedObject().getName()); + assertThat(actual.getNestedObject().getName()) + .isEqualTo(namePrefix + fromFoo.getNestedObject().getName()); underTest.resetFieldsTransformer(); } @@ -168,7 +178,8 @@ public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); //THEN - assertThat(actual).usingRecursiveComparison().isEqualTo(fromFooSimpleNoGetters); + assertThat(actual).usingRecursiveComparison() + .isEqualTo(fromFooSimpleNoGetters); } /** @@ -184,7 +195,8 @@ public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeField() { MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); //THEN - assertThat(actual).usingRecursiveComparison().isEqualTo(fromFooSimpleNoGetters); + assertThat(actual).usingRecursiveComparison() + .isEqualTo(fromFooSimpleNoGetters); underTest.setDefaultValueForMissingPrimitiveField(true); } @@ -200,9 +212,8 @@ public void testTransformerIsAbleToCopyObjectsWithoutFieldButWithGetterMethods() MutableToFooSimpleNoSetters actual = underTest.transform(fromFooNoField, MutableToFooSimpleNoSetters.class); //THEN - assertThat(actual.getId()).isEqualTo(fromFooNoField.getId()); - assertThat(actual.getName()).isEqualTo(fromFooNoField.getName()); - assertThat(actual.isActive()).isEqualTo(fromFooNoField.isActive()); + assertThat(actual).extracting(ID_FIELD_NAME, NAME_FIELD_NAME, ACTIVE_FIELD_NAME) + .containsExactly(fromFooNoField.getId(), fromFooNoField.getName(), fromFooNoField.isActive()); } /** @@ -234,16 +245,10 @@ public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeCo underTest.setPrimitiveTypeConversionEnabled(true); //WHEN - Exception raisedException = null; - try { - underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); - } catch (final Exception e) { - raisedException = e; - } + ThrowableAssert.ThrowingCallable code = () -> underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); //THEN - assertThat(raisedException).isNotNull(); - assertThat(raisedException.getCause().getClass()).isEqualTo(MissingFieldException.class); + assertThatThrownBy(code).hasCauseInstanceOf(MissingFieldException.class); underTest.setPrimitiveTypeConversionEnabled(false); } @@ -261,8 +266,8 @@ public void testTransformerDoesNotThrowExceptionIfAFieldIsMissingAndTheDefaultVa MutableToFooNotExistingFields actual = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); //THEN - assertThat(actual.getId()).isEqualTo(fromFooSimple.getId()); - assertThat(actual.getName()).isEqualTo(fromFooSimple.getName()); + assertThat(actual).extracting(ID_FIELD_NAME, NAME_FIELD_NAME) + .containsExactly(fromFooSimple.getId(), fromFooSimple.getName()); underTest.setPrimitiveTypeConversionEnabled(false).setDefaultValueForMissingField(false); } @@ -313,9 +318,7 @@ public void testFieldTransformationSkipWorksProperly() { MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); //THEN - assertThat(actual.getId()).isEqualTo(fromFoo.getId()); - assertThat(actual.getName()).isNull(); - assertThat(actual.getNestedObject().getPhoneNumbers()).isNull(); + assertThat(actual).hasNoNullFieldsOrPropertiesExcept(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); underTest.resetFieldsTransformationSkip(); } @@ -331,10 +334,12 @@ public void testAutomaticPrimitiveTypeTransformationWorksProperly() { MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); //THEN - assertThat(actual.getCode()).isEqualTo(parseInt(fromFooPrimitiveTypes.getCode())); - assertThat(actual.getId()).isEqualTo(String.valueOf(fromFooPrimitiveTypes.getId())); - assertThat(actual.getPrice()).isEqualTo(Double.valueOf(fromFooPrimitiveTypes.getPrice())); - assertThat(actual.isActive()).isEqualTo(ACTIVE); + assertThat(actual).extracting(CODE_FIELD_NAME, ID_FIELD_NAME, PRICE_FIELD_NAME, ACTIVE_FIELD_NAME) + .containsExactly( + parseInt(fromFooPrimitiveTypes.getCode()), + String.valueOf(fromFooPrimitiveTypes.getId()), + (double) fromFooPrimitiveTypes.getPrice(), + ACTIVE); underTest.setPrimitiveTypeConversionEnabled(false); } @@ -352,10 +357,12 @@ public void testThatBothPrimitiveTypeTransformationAndCustomTransformationAreExe MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); //THEN - assertThat(actual.getCode()).isEqualTo(parseInt(fromFooPrimitiveTypes.getCode())); - assertThat(actual.getId()).isEqualTo(String.valueOf(fromFooPrimitiveTypes.getId())); - assertThat(actual.isActive()).isEqualTo(ACTIVE); - assertThat(actual.getPrice()).isEqualTo(newPrice); + assertThat(actual).extracting(CODE_FIELD_NAME, ID_FIELD_NAME, ACTIVE_FIELD_NAME, PRICE_FIELD_NAME) + .containsExactly( + parseInt(fromFooPrimitiveTypes.getCode()), + String.valueOf(fromFooPrimitiveTypes.getId()), + ACTIVE, + newPrice); underTest.setPrimitiveTypeConversionEnabled(false); underTest.removeFieldTransformer(PRICE_FIELD_NAME); } @@ -384,7 +391,6 @@ public void testInjectValuesThrowsException() throws Exception { Object actual = injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); // THEN - assertThat(actual).isNotNull(); assertThat(actual).isSameAs(expectedException); } } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java index cb6e12803..d4decff9d 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java @@ -21,12 +21,14 @@ import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.ToString; /** * Sample immutable object. */ @AllArgsConstructor @Getter +@ToString @EqualsAndHashCode public class ImmutableToFooSimple { private final String name; diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java index f56b7992b..30b8bc159 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java @@ -59,9 +59,7 @@ public void testCacheObjectStoresTheGivenObjectWithTheGivenKey() { Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertThat(actual).isPresent(); - assertThat(actual.get().getClass()).isEqualTo(CACHED_OBJECT_CLASS); - assertThat(actual.get()).isSameAs(VALUE); + assertThat(actual).containsSame(VALUE); } /** @@ -76,9 +74,7 @@ public void testCacheObjectStoresTheDefaultValueIfTheGivenObjectIsNull() { Optional actual = underTest.getFromCache(CACHE_KEY, CACHED_OBJECT_CLASS); // THEN - assertThat(actual).isPresent(); - assertThat(actual.get().getClass()).isEqualTo(CACHED_OBJECT_CLASS); - assertThat(actual.get()).isSameAs(DEFAULT_VALUE); + assertThat(actual).containsSame(DEFAULT_VALUE); } /** diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 5ecb7670a..767ebe56f 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -88,7 +88,7 @@ public class ClassUtilsTest { private static final Class CLASS_WITH_STATIC_FIELDS = MixedToFooStaticField.class; private static final Class CLASS_WITHOUT_CONSTRUCTOR = MixedToFooMissingConstructor.class; private static final int EXPECTED_NOT_STATIC_FIELDS = 1; - private static final String NAME = "name"; + private static final String NAME_FIELD_NAME = "name"; private static final int EXPECTED_CLASS_PARAMETERS = 5; private static final String NOT_EXISTING_FIELD_NAME = "notExistingFieldName"; private static final Class CLASS_WITH_PRIVATE_FINAL_FIELDS_AND_SUB_CLASS = ImmutableToFooSubClass.class; @@ -273,7 +273,7 @@ public void testGetPrivateFinalFieldsWorksAsExpected(final String testCaseDescri List actual = underTest.getPrivateFinalFields(testClass); // THEN - assertThat(actual.size()).isEqualTo(expectedResult); + assertThat(actual).hasSize(expectedResult); } /** @@ -304,7 +304,7 @@ public void testGetNotFinalFieldsWorksAsExpected(final String testCaseDescriptio List actual = underTest.getNotFinalFields(testClass, true); // THEN - assertThat(actual.size()).isEqualTo(expectedResult); + assertThat(actual).hasSize(expectedResult); } /** @@ -366,7 +366,7 @@ public void testGetPrivateFieldsWorksAsExpected(final String testCaseDescription List actual = nonNull(skipFinal) ? underTest.getPrivateFields(testClass, skipFinal) : underTest.getPrivateFields(testClass); // THEN - assertThat(actual.size()).isEqualTo(expectedResult); + assertThat(actual).hasSize(expectedResult); } /** @@ -408,7 +408,7 @@ public void testGetDeclaredFieldsWorksAsExpected(final String testCaseDescriptio List actual = underTest.getDeclaredFields(testClass, skipStatic); // THEN - assertThat(actual.size()).isEqualTo(expectedResult); + assertThat(actual).hasSize(expectedResult); } /** @@ -553,8 +553,7 @@ public void testGetConstructorParameters() { Parameter[] constructorParameters = underTest.getConstructorParameters(classConstructor); // THEN - assertThat(constructorParameters).isNotNull(); - assertThat(constructorParameters.length).isEqualTo(EXPECTED_CLASS_PARAMETERS); + assertThat(constructorParameters).hasSize(EXPECTED_CLASS_PARAMETERS); } /** @@ -566,7 +565,7 @@ public void testGetInstanceRaisesAnInstanceCreationExceptionIfAnErrorOccurs() { Constructor classConstructor = underTest.getAllArgsConstructor(AbstractClass.class); // WHEN - underTest.getInstance(classConstructor, NAME, ZERO); + underTest.getInstance(classConstructor, NAME_FIELD_NAME, ZERO); } /** @@ -596,7 +595,7 @@ public void testHasFieldWorksAsExpected(final String testCaseDescription, final private Object[][] dataHasFieldTesting() { return new Object[][] { {"Tests that the method returns false if the given field does not exists", NOT_EXISTING_FIELD_NAME, false}, - {"Tests that the method returns true if the given field exists", NAME, true} + {"Tests that the method returns true if the given field exists", NAME_FIELD_NAME, true} }; } @@ -762,7 +761,7 @@ public void testGetGetterMethodsWorksAsExpected(final String testCaseDescription final List actual = underTest.getGetterMethods(testClass); // THEN - assertThat(actual.size()).isEqualTo(expectedGetterMethods); + assertThat(actual).hasSize(expectedGetterMethods); } /** @@ -1039,6 +1038,7 @@ public void testGetBuildMethodReturnsTheBuildMethod() { // THEN assertThat(actual).isNotNull(); assertThat(actual.getName()).isEqualTo(BUILD_METHOD_NAME); + assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, BUILD_METHOD_NAME); } /** @@ -1055,8 +1055,7 @@ public void testGetConcreteClassWorksAsExpected(final String testCaseDescription Optional> actual = underTest.getBuilderClass(testClass); // THEN - assertThat(actual.isPresent()).isEqualTo(expectedResult.isPresent()); - expectedResult.ifPresent(clazz -> assertThat(actual.get()).isEqualTo(clazz)); + assertThat(actual).isEqualTo(expectedResult); } /** @@ -1091,6 +1090,6 @@ private Field getField(final T objectInstance, final String fieldName) throw * @return a {@link FromFoo} instance */ private FromFoo createFromFoo() { - return new FromFoo(NAME, null, null, LINKED_LIST, null); + return new FromFoo(NAME_FIELD_NAME, null, null, LINKED_LIST, null); } } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 17e9e7d34..144049f33 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -76,7 +76,7 @@ public class ReflectionUtilsTest { private static final String ID_FIELD_NAME = "id"; private static final String NOT_EXISTING_FIELD_NAME = "notExistingField"; - private static final String NESTED_OBJECT_FIELD_NAME = "nestedObject.name"; + private static final String NESTED_OBJECT_NAME_FIELD_NAME = "nestedObject.name"; private static final String LIST_FIELD_NAME = "list"; private static final String PHONE_NUMBERS_FIELD_NAME = "phoneNumbers"; private static final String GETTER_METHOD_PREFIX_METHOD_NAME = "getGetterMethodPrefix"; @@ -154,7 +154,7 @@ private Object[][] dataGetFieldValueTesting() { MutableToFoo mutableToFoo = createMutableToFoo(ZERO); return new Object[][] { {"Tests that the method returns the field value", mutableToFoo, ID_FIELD_NAME, BigInteger.class, ZERO}, - {"Tests that the method returns null if the required field is inside a null object", mutableToFoo, NESTED_OBJECT_FIELD_NAME, + {"Tests that the method returns null if the required field is inside a null object", mutableToFoo, NESTED_OBJECT_NAME_FIELD_NAME, String.class, null}, {"Tests that the method returns the field value even if there is no getter method defined", createFromFooSimpleNoGetters(), ID_FIELD_NAME, BigInteger.class, ZERO} @@ -236,7 +236,7 @@ private Object[][] dataGetFieldValueDirectAccessTesting() { MutableToFoo mutableToFoo = createMutableToFoo(null); return new Object[][] { {"Tests that the method throws Exception if the field does not exists", mutableToFoo, NOT_EXISTING_FIELD_NAME}, - {"Tests that the method throws Exception if the bean is null", null, NESTED_OBJECT_FIELD_NAME} + {"Tests that the method throws Exception if the bean is null", null, NESTED_OBJECT_NAME_FIELD_NAME} }; } @@ -252,7 +252,7 @@ public void testHandleReflectionExceptionThrowsMissingMethodExceptionWhenGivenEx RuntimeException actual = underTest.handleReflectionException(noSuchMethodException); // THEN - assertThat(actual.getClass()).isEqualTo(MissingMethodException.class); + assertThat(actual).isInstanceOf(MissingMethodException.class); } /** @@ -529,7 +529,7 @@ public void testGetClassDeclaredFieldThrowsTheRightException() throws Exception private Object[][] dataGetDeclaredFieldTesting() { return new Object[][] { {"Tests that the method returns the class field from first object", ID_FIELD_NAME, FromFooSubClass.class}, - {"Tests that the method returns the class field from a nested object", NESTED_OBJECT_FIELD_NAME, MutableToFoo.class} + {"Tests that the method returns the class field from a nested object", NESTED_OBJECT_NAME_FIELD_NAME, MutableToFoo.class} }; } From 03d1f43f5630299f5a102c5c7d5481c1b5cd1eff Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 14:47:01 +0200 Subject: [PATCH 1138/1786] Update bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java Co-authored-by: Matteo Mirk --- .../java/com/hotels/transformer/utils/ReflectionUtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 144049f33..1c04ef275 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -267,7 +267,7 @@ public void testHandleReflectionExceptionThrowsIllegalStateExceptionWhenGivenExc RuntimeException actual = underTest.handleReflectionException(illegalAccessException); // THEN - assertThat(actual.getClass()).isEqualTo(IllegalStateException.class); + assertThat(actual).isInstanceOf(IllegalStateException.class); } /** From 42a6ed9a4ea96fee3fbc43edf49c19c89c171ee3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 14:47:38 +0200 Subject: [PATCH 1139/1786] Update bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java Co-authored-by: Matteo Mirk --- .../java/com/hotels/transformer/utils/ReflectionUtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 1c04ef275..f70959c08 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -282,7 +282,7 @@ public void testHandleReflectionExceptionThrowsRuntimeExceptionWhenGivenExceptio RuntimeException actual = underTest.handleReflectionException(runtimeException); // THEN - assertThat(actual.getClass()).isEqualTo(RuntimeException.class); + assertThat(actual).isInstanceOf(RuntimeException.class); } /** From c91cb7356672d9d954e6ee40a98e8af1994383d3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 14:48:27 +0200 Subject: [PATCH 1140/1786] Update bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java Co-authored-by: Matteo Mirk --- .../java/com/hotels/transformer/utils/ReflectionUtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index f70959c08..3011a8f86 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -297,7 +297,7 @@ public void testHandleReflectionExceptionThrowsUndeclaredThrowableExceptionWhenG RuntimeException actual = underTest.handleReflectionException(genericException); // THEN - assertThat(actual.getClass()).isEqualTo(UndeclaredThrowableException.class); + assertThat(actual).isInstanceOf(UndeclaredThrowableException.class); } /** From d7b6daac1dba34d569768abf5e1691190fdc4961 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 14:50:04 +0200 Subject: [PATCH 1141/1786] Update bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java Co-authored-by: Matteo Mirk --- .../java/com/hotels/transformer/utils/ReflectionUtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 3011a8f86..16277b879 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -453,7 +453,7 @@ public void testInvokeMethodWorksProperly() throws Exception { .invoke(underTest, idSetterMethod, mutableToFoo, new Object[] {ONE}); // THEN - assertThat(mutableToFoo.getId()).isEqualTo(ONE); + assertThat(mutableToFoo).hasFieldOrPropertyWithValue(ID_FIELD_NAME, ONE); } /** From 2d234fa647fc83e2a90baf72095b7bebab4858aa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 14:57:09 +0200 Subject: [PATCH 1142/1786] Changes as per PR --- .../utils/ReflectionUtilsTest.java | 89 ++++++------------- .../site/markdown/transformer/bean/testing.md | 2 +- 2 files changed, 29 insertions(+), 62 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 16277b879..fa321b4df 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -21,6 +21,8 @@ import static java.util.Objects.isNull; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.catchThrowable; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -46,6 +48,7 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import org.assertj.core.api.ThrowableAssert; import org.mockito.InjectMocks; import org.mockito.Mockito; import org.testng.annotations.BeforeClass; @@ -93,6 +96,7 @@ public class ReflectionUtilsTest { private static final String INDEX_NUMBER = "123"; private static final String GET_REAL_TARGET_METHOD_NAME = "getRealTarget"; private static final String GET_CLASS_DECLARED_FIELD_METHOD_NAME = "getClassDeclaredField"; + private static final String NAME_FIELD_NAME = "name"; /** * The class to be tested. @@ -388,8 +392,7 @@ public void testGetSetterMethodForFieldWorksProperly() { final Method actual = underTest.getSetterMethodForField(MutableToFoo.class, ID_FIELD_NAME, BigInteger.class); // THEN - assertThat(actual).isNotNull(); - assertThat(actual.getName()).isEqualTo(EXPECTED_SETTER_METHOD_NAME); + assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, EXPECTED_SETTER_METHOD_NAME); } /** @@ -418,7 +421,6 @@ public void testGetParameterAnnotationReturnsTheAnnotationIfExists() { final Annotation actual = underTest.getParameterAnnotation(parameter, NotNull.class, DECLARING_CLASS_NAME); // THEN - assertThat(actual).isNotNull(); assertThat(actual).isEqualTo(notNullAnnotation); } @@ -461,24 +463,19 @@ public void testInvokeMethodWorksProperly() throws Exception { * @throws Exception if something goes wrong. */ @Test - public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong() throws Exception { + public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong() { // GIVEN MutableToFoo mutableToFoo = createMutableToFoo(null); Method idSetterMethod = underTest.getSetterMethodForField(MutableToFoo.class, LIST_FIELD_NAME, List.class); // WHEN - InvocationTargetException actualException = null; - try { - getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) - .invoke(underTest, idSetterMethod, mutableToFoo, new Object[] {ONE}); - } catch (final InvocationTargetException e) { - actualException = e; - } + ThrowableAssert.ThrowingCallable code = () -> + getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) + .invoke(underTest, idSetterMethod, mutableToFoo, new Object[]{ONE}); // THEN - assertThat(actualException).isNotNull(); - assertThat(actualException.getTargetException().getClass()).isEqualTo(IllegalArgumentException.class); + assertThatThrownBy(code).hasCauseInstanceOf(IllegalArgumentException.class); } /** @@ -503,22 +500,18 @@ public void testGetDeclaredFieldWorksProperly(final String testCaseDescription, * @throws Exception if the invoke method fails */ @Test - public void testGetClassDeclaredFieldThrowsTheRightException() throws Exception { + public void testGetClassDeclaredFieldThrowsTheRightException() { //GIVEN //WHEN - InvocationTargetException actualException = null; - try { + Throwable actualException = catchThrowable(() -> { Method getClassDeclaredFieldMethod = underTest.getClass().getDeclaredMethod(GET_CLASS_DECLARED_FIELD_METHOD_NAME, String.class, Class.class); getClassDeclaredFieldMethod.setAccessible(true); getClassDeclaredFieldMethod.invoke(underTest, null, FromFoo.class); - } catch (final InvocationTargetException e) { - actualException = e; - } + }); // THEN - assertThat(actualException).isNotNull(); - assertThat(actualException.getTargetException().getClass()).isEqualTo(NullPointerException.class); + assertThat(actualException).hasCauseInstanceOf(NullPointerException.class); } /** @@ -619,47 +612,31 @@ public void testMapGenericFieldTypeWorksProperly() { .build(); final MapType expectedElemType = new MapType(keyType, keyType); final MapType expectedMapType = new MapType(keyType, expectedElemType); - ItemType expectedMapKeyType = (ItemType) expectedMapType.getKeyType(); - ItemType expectedNestedMapKeyType = (ItemType) ((MapType) expectedMapType.getElemType()).getKeyType(); - ItemType expectedNestedMapElemType = (ItemType) ((MapType) expectedMapType.getElemType()).getElemType(); Field field = underTest.getDeclaredField(VERY_COMPLEX_MAP_FIELD_NAME, ImmutableToSubFoo.class); // WHEN MapType actual = underTest.getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); - ItemType actualMapKeyType = (ItemType) actual.getKeyType(); - ItemType actualNestedMapKeyType = (ItemType) ((MapType) actual.getElemType()).getKeyType(); - ItemType actualNestedMapElemType = (ItemType) ((MapType) actual.getElemType()).getElemType(); // THEN - assertThat(actualMapKeyType.getObjectClass()).isEqualTo(expectedMapKeyType.getObjectClass()); - assertThat(actualMapKeyType.getGenericClass()).isEqualTo(expectedMapKeyType.getGenericClass()); - assertThat(actualNestedMapKeyType.getObjectClass()).isEqualTo(expectedNestedMapKeyType.getObjectClass()); - assertThat(actualNestedMapKeyType.getGenericClass()).isEqualTo(expectedNestedMapKeyType.getGenericClass()); - assertThat(actualNestedMapElemType.getObjectClass()).isEqualTo(expectedNestedMapElemType.getObjectClass()); - assertThat(actualNestedMapElemType.getGenericClass()).isEqualTo(expectedNestedMapElemType.getGenericClass()); + assertThat(actual).usingRecursiveComparison() + .isEqualTo(expectedMapType); } @Test public void testMapGenericFieldTypeWorksProperlyForUnparametrizedMap() { // GIVEN MapElemType keyType = ItemType.builder() - .objectClass(Map.class) - .build(); + .objectClass(Map.class) + .build(); final MapType expectedMapType = new MapType(keyType, keyType); - ItemType expectedMapKeyType = (ItemType) expectedMapType.getKeyType(); - ItemType expectedMapElemType = (ItemType) expectedMapType.getElemType(); Field field = underTest.getDeclaredField(UNPARAMETRIZED_MAP_FIELD_NAME, FromFooMap.class); // WHEN MapType actual = underTest.getMapGenericType(field.getGenericType(), field.getDeclaringClass().getName(), field.getName()); - ItemType actualMapKeyType = (ItemType) actual.getKeyType(); - ItemType actualMapElemType = (ItemType) actual.getElemType(); // THEN - assertThat(actualMapKeyType.getObjectClass()).isEqualTo(expectedMapKeyType.getObjectClass()); - assertThat(actualMapKeyType.getGenericClass()).isEqualTo(expectedMapKeyType.getGenericClass()); - assertThat(actualMapElemType.getObjectClass()).isEqualTo(expectedMapElemType.getObjectClass()); - assertThat(actualMapElemType.getGenericClass()).isEqualTo(expectedMapElemType.getGenericClass()); + assertThat(actual).usingRecursiveComparison() + .isEqualTo(expectedMapType); } /** @@ -706,16 +683,11 @@ public void testGetGetterMethodThrowsExceptionIfTheMethodDoesNotExists() throws Method methodUnderTest = getMethod(underTest.getClass(), GET_GETTER_METHOD_NAME, true, Class.class, String.class, Class.class); // WHEN - InvocationTargetException actualException = null; - try { - methodUnderTest.invoke(underTest, FromFooSimpleNoGetters.class, ID_FIELD_NAME, BigInteger.class); - } catch (final InvocationTargetException e) { - actualException = e; - } + ThrowableAssert.ThrowingCallable code = () -> + methodUnderTest.invoke(underTest, FromFooSimpleNoGetters.class, ID_FIELD_NAME, BigInteger.class); // THEN - assertThat(actualException).isNotNull(); - assertThat(actualException.getTargetException().getClass()).isEqualTo(MissingFieldException.class); + assertThatThrownBy(code).hasCauseInstanceOf(MissingFieldException.class); } /** @@ -754,7 +726,7 @@ public void testSetFieldValueWorksProperly() { underTest.setFieldValue(mutableToFoo, idField, ONE); // THEN - assertThat(mutableToFoo.getId()).isEqualTo(ONE); + assertThat(mutableToFoo).hasFieldOrPropertyWithValue(ID_FIELD_NAME, ONE); } @Test @@ -769,7 +741,7 @@ public void testSetFieldValueInvokesTheSetterMethodInCaseAnExceptionIsRaised() { underTestMock.setFieldValue(mutableToFoo, idField, ONE); // THEN - assertThat(mutableToFoo.getId()).isEqualTo(ONE); + assertThat(mutableToFoo).hasFieldOrPropertyWithValue(ID_FIELD_NAME, ONE); } /** @@ -789,16 +761,11 @@ public void testInvokeMethodCorrectlyHandlesExceptions(final String testCaseDesc Method setMethodToInvoke = getMethod(targetObject.getClass(), methodNameToInvoke, isAccessible, String.class); // WHEN - Throwable actualException = null; - try { - underTest.invokeMethod(setMethodToInvoke, targetObject, methodArg); - } catch (final Throwable e) { - actualException = e; - } + ThrowableAssert.ThrowingCallable code = () -> + underTest.invokeMethod(setMethodToInvoke, targetObject, methodArg); // THEN - assertThat(actualException).isNotNull(); - assertThat(actualException.getClass()).isEqualTo(expectedException); + assertThatThrownBy(code).isInstanceOf(expectedException); } /** diff --git a/docs/site/markdown/transformer/bean/testing.md b/docs/site/markdown/transformer/bean/testing.md index af81c5e08..382059a08 100644 --- a/docs/site/markdown/transformer/bean/testing.md +++ b/docs/site/markdown/transformer/bean/testing.md @@ -14,7 +14,7 @@ extent to which the component or system under test: * can be installed and run in its intended environments * achieves the general result its stakeholders desire. -This page will show how to test BULL into a simple project. All the examples utilizes [JUnit](https://github.com/junit-team) and [Mockito](https://site.mockito.org/). +This page will show how to test BULL into a simple project. All the examples utilize [JUnit](https://github.com/junit-team), [Mockito](https://site.mockito.org/) and [AssertJ](http://joel-costigliola.github.io/assertj/) The Java Bean transformation function can be tested in two different ways that depends on the following scenarios: From 0648156fd350fa2e2887a48286f6836f4db178af Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 14:59:49 +0200 Subject: [PATCH 1143/1786] Changes as per PR --- docs/site/markdown/transformer/bean/testing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/site/markdown/transformer/bean/testing.md b/docs/site/markdown/transformer/bean/testing.md index 382059a08..3d05df29c 100644 --- a/docs/site/markdown/transformer/bean/testing.md +++ b/docs/site/markdown/transformer/bean/testing.md @@ -123,7 +123,7 @@ public class SampleClassTest { //THEN verify(beanUtils).getTransformer(); verify(beanTransformer).transform(sampleRequest, DestObject.class); - assertEquals(EXPECTED_RESULT, actual); + assertThat(actual).isEqualTo(EXPECTED_RESULT); } /** @@ -242,7 +242,7 @@ public class SampleClassTest { verify(beanUtils).getTransformer(); verify(beanTransformer).withFieldTransformer(any(FieldTransformer.class)); verify(beanTransformer).transform(sampleRequest, DestObject.class); - assertEquals(EXPECTED_RESULT, actual); + assertThat(actual).isEqualTo(EXPECTED_RESULT); } /** @@ -350,7 +350,7 @@ public class SampleClassTest { final BigInteger actual = underTest.doSomething(sampleRequest); //THEN - assertEquals(EXPECTED_RESULT, actual); + assertThat(actual).isEqualTo(EXPECTED_RESULT); } /** From 6a7ba5d7d1eae78bd7647ecd94cd7dcaa3b50d6e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:43:34 +0200 Subject: [PATCH 1144/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/analyzer/ConversionAnalyzerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index b659a2cd5..4d6b44f01 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -77,7 +77,7 @@ public void testGetConversionFunctionReturnsAnEmptyOptional(final String testCas Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN - assertThat(actual).isEqualTo(empty()); + assertThat(actual).isEmpty(); } /** From 53294c5630700ff8512f00c6236626d87c3c98a7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:43:55 +0200 Subject: [PATCH 1145/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/analyzer/ConversionAnalyzerTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index 4d6b44f01..2ae7abf0b 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -114,8 +114,7 @@ public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN - assertThat(actual.isPresent()).isTrue(); - assertThat(actual.get()).isEqualTo(expectedConversionFunction); + assertThat(actual).contains((Function) expectedConversionFunction); } /** From 29dd880363c12b8243e0339f9e622f5b3962ca4e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:44:31 +0200 Subject: [PATCH 1146/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java Co-authored-by: Matteo Mirk --- .../conversion/processor/ConversionProcessorFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index cbbfa7928..4c9b69b10 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -71,7 +71,7 @@ public void testGetConversionProcessorReturnsNullInCaseNoProcessorExistsForTheGi Optional actual = underTest.getConversionProcessor(Pair.class); // THEN - assertThat(actual.isEmpty()).isTrue(); + assertThat(actual).isEmpty(); } /** From 1444f83877c5daef5b30c06aed8695a12f77a156 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:45:07 +0200 Subject: [PATCH 1147/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java Co-authored-by: Matteo Mirk --- .../conversion/processor/ConversionProcessorFactoryTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index 4c9b69b10..340d27c85 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -89,8 +89,7 @@ public void testGetConversionProcessorWorksAsExpected(final String testCaseDescr Optional actual = underTest.getConversionProcessor(targetClass); // THEN - assertThat(actual.isPresent()).isTrue(); - assertThat(actual.get().getClass()).isEqualTo(expectedResult); + assertThat(actual).containsInstanceOf(expectedResult); } /** From 38fd78faef501628e5916ade148f0266f892e4f7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:46:20 +0200 Subject: [PATCH 1148/1786] Changes as per PR --- .../beans/conversion/analyzer/ConversionAnalyzerTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index 2ae7abf0b..b9a488f58 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -16,8 +16,6 @@ package com.hotels.beans.conversion.analyzer; -import static java.util.Optional.empty; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; From bc767f5583bd5809f6568d79eb9d72cbc8ec4161 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:53:22 +0200 Subject: [PATCH 1149/1786] Changes as per PR --- .../processor/impl/BigDecimalConversionTest.java | 6 ++---- .../processor/impl/BigIntegerConversionTest.java | 5 ++--- .../conversion/processor/impl/ByteConversionTest.java | 10 +++------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java index de6aae067..cc08756ac 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java @@ -200,24 +200,22 @@ public void testConvertStringShouldReturnProperResult() { @Test public void testConvertBigIntegerShouldReturnProperResult() { // GIVEN - BigDecimal expected = valueOf(BigInteger.ZERO.intValue()); // WHEN BigDecimal actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isEqualTo(expected); + assertThat(actual).isZero(); } @Test public void testConvertBigDecimalShouldReturnProperResult() { // GIVEN - BigDecimal expectedValue = BigDecimal.ZERO; // WHEN BigDecimal actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java index 1280fbc47..9bb4f4ea5 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java @@ -205,18 +205,17 @@ public void testConvertBigIntegerShouldReturnProperResult() { BigInteger actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isEqualTo(BigInteger.ZERO); + assertThat(actual).isZero(); } @Test public void testConvertBigDecimalShouldReturnProperResult() { // GIVEN - BigInteger expectedValue = BigDecimal.ZERO.toBigInteger(); // WHEN BigInteger actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java index f86deb10d..4e7c495e9 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java @@ -16,8 +16,6 @@ package com.hotels.beans.conversion.processor.impl; -import static java.lang.Byte.valueOf; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; @@ -177,30 +175,28 @@ public void testConvertStringShouldReturnProperResult() { Byte actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); + assertThat(actual).isEqualTo(BYTE_VALUE); } @Test public void testConvertBigIntegerShouldReturnProperResult() { // GIVEN - byte expectedValue = BigInteger.ZERO.byteValue(); // WHEN byte actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } @Test public void testConvertBigDecimalShouldReturnProperResult() { // GIVEN - byte expectedValue = BigDecimal.ZERO.byteValue(); // WHEN byte actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } } From eec05e5f11ea6bf66be31b9d6fe49490d5d87339 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:54:05 +0200 Subject: [PATCH 1150/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java Co-authored-by: Matteo Mirk --- .../conversion/processor/impl/CharacterConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java index 6adbfbaf7..b3d18ada0 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java @@ -199,7 +199,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { char actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } @Test From 018048893e2f8ecdaf0b8aab4d789a510551087f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:57:05 +0200 Subject: [PATCH 1151/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/DoubleConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index 0c05e6a30..e181458f3 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -63,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Double actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertThat(actual).isEqualTo((Double) BYTE_VALUE.doubleValue()); + assertThat(actual).isEqualTo(DOUBLE_VALUE); } @Test From a37be3236bfefc7c97aa6b341e32352bb9bb1716 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:57:35 +0200 Subject: [PATCH 1152/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/DoubleConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index e181458f3..d5fd96375 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -105,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { Double actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertThat(actual).isEqualTo((Double) INTEGER_VALUE.doubleValue()); + assertThat(actual).isEqualTo(DOUBLE_VALUE); } @Test From 1417202dd4f497c4eba0fb4a2153ed251ddb21d0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:58:04 +0200 Subject: [PATCH 1153/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/DoubleConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index d5fd96375..902a17709 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -116,7 +116,7 @@ public void testConvertLongShouldReturnProperResult() { Double actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertThat(actual).isEqualTo((Double) LONG_VALUE.doubleValue()); + assertThat(actual).isEqualTo(DOUBLE_VALUE); } @Test From 5f06d1a79422869426c506999926597aad644f2f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 15:58:41 +0200 Subject: [PATCH 1154/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/DoubleConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index 902a17709..c532a45ff 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -127,7 +127,7 @@ public void testConvertFloatShouldReturnProperResult() { Double actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertThat(actual).isEqualTo((Double) FLOAT_VALUE.doubleValue()); + assertThat(actual).isEqualTo(DOUBLE_VALUE); } @Test From 3c4b8c95646dfdcaae46470091b8b2cc23194c7a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:00:09 +0200 Subject: [PATCH 1155/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/DoubleConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index c532a45ff..9a5e9f38c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -201,7 +201,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { double actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } @Test From decd782945b6037c845781655583d4e4c0d509fc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:00:37 +0200 Subject: [PATCH 1156/1786] Changes as per PR --- .../beans/conversion/processor/impl/DoubleConversionTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index 0c05e6a30..9315bc547 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -144,12 +144,13 @@ public void testConvertDoubleShouldReturnProperResult() { @Test public void testConvertCharacterShouldReturnProperResult() { // GIVEN + double expected = 1.0; // WHEN Double actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertThat(actual).isEqualTo(valueOf((short) getNumericValue(CHAR_VALUE))); + assertThat(actual).isEqualTo(expected); } /** From 983a5c20f62f39c70e3cf7b7ab269e22aeaafccf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:02:35 +0200 Subject: [PATCH 1157/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/FloatConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 8175feee0..d3fa33999 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -63,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Float actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertThat(actual).isEqualTo((Float) BYTE_VALUE.floatValue()); + assertThat(actual).isEqualTo(FLOAT_VALUE); } @Test From 9e572699362efbf39c3299b40bf86e05ce0e4446 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:02:58 +0200 Subject: [PATCH 1158/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/FloatConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index d3fa33999..1fb701065 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -94,7 +94,7 @@ public void testConvertShortShouldReturnProperResult() { Float actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertThat(actual).isEqualTo((Float) SHORT_VALUE.floatValue()); + assertThat(actual).isEqualTo(FLOAT_VALUE); } @Test From fc85470056b9a24309da9234dc7be7a2468d0bce Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:03:17 +0200 Subject: [PATCH 1159/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/FloatConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 1fb701065..4daeaedcf 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -105,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { Float actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertThat(actual).isEqualTo((Float) INTEGER_VALUE.floatValue()); + assertThat(actual).isEqualTo(FLOAT_VALUE); } @Test From c04ebdc0feee28e439ef3676d4b079306ff61a97 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:03:37 +0200 Subject: [PATCH 1160/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/FloatConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 4daeaedcf..49c7361e1 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -116,7 +116,7 @@ public void testConvertLongShouldReturnProperResult() { Float actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertThat(actual).isEqualTo((Float) LONG_VALUE.floatValue()); + assertThat(actual).isEqualTo(FLOAT_VALUE); } @Test From ee79641024477b017ade4eb40ecf6578e540750a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:04:02 +0200 Subject: [PATCH 1161/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/FloatConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 49c7361e1..3e2251b65 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -138,7 +138,7 @@ public void testConvertDoubleShouldReturnProperResult() { Float actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertThat(actual).isEqualTo((Float) DOUBLE_VALUE.floatValue()); + assertThat(actual).isEqualTo(FLOAT_VALUE); } @Test From 35ab59be0501ed12792e098aefbbefae1060c7e5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:04:16 +0200 Subject: [PATCH 1162/1786] Changes as per PR --- .../conversion/processor/impl/CharacterConversionTest.java | 2 +- .../conversion/processor/impl/DoubleConversionTest.java | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java index b3d18ada0..6adbfbaf7 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java @@ -199,7 +199,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { char actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isZero(); + assertThat(actual).isEqualTo(expectedValue); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index 5bdaa8d58..4205aafea 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -16,7 +16,6 @@ package com.hotels.beans.conversion.processor.impl; -import static java.lang.Character.getNumericValue; import static java.lang.Double.valueOf; import static java.nio.ByteBuffer.wrap; @@ -196,7 +195,6 @@ public void testConvertStringShouldReturnProperResult() { @Test public void testConvertBigIntegerShouldReturnProperResult() { // GIVEN - double expectedValue = BigInteger.ZERO.doubleValue(); // WHEN double actual = underTest.convertBigInteger().apply(BigInteger.ZERO); @@ -208,12 +206,11 @@ public void testConvertBigIntegerShouldReturnProperResult() { @Test public void testConvertBigDecimalShouldReturnProperResult() { // GIVEN - double expectedValue = BigDecimal.ZERO.doubleValue(); // WHEN double actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } } From 348b799ef4a9e6e4deba427ee398a9e6e71e8256 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:05:06 +0200 Subject: [PATCH 1163/1786] Changes as per PR --- .../beans/conversion/processor/impl/FloatConversionTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 3e2251b65..ac37453ad 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -144,12 +144,13 @@ public void testConvertDoubleShouldReturnProperResult() { @Test public void testConvertCharacterShouldReturnProperResult() { // GIVEN + float expected = 1.0f; // WHEN Float actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertThat(actual).isEqualTo(Float.valueOf(getNumericValue(CHAR_VALUE))); + assertThat(actual).isEqualTo(expected); } /** From 96f88ca62f09b2bb96cfb1858c315128230b9623 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:05:26 +0200 Subject: [PATCH 1164/1786] Changes as per PR --- .../beans/conversion/processor/impl/FloatConversionTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index ac37453ad..1a5482315 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -16,7 +16,6 @@ package com.hotels.beans.conversion.processor.impl; -import static java.lang.Character.getNumericValue; import static java.lang.Float.valueOf; import static java.nio.ByteBuffer.wrap; From ecb6b209b4ea179afc65957fa2e742437743e6b8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:06:09 +0200 Subject: [PATCH 1165/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/IntegerConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index 8cc8ef64a..88eee41c5 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -63,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Integer actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertThat(actual).isEqualTo((Integer) BYTE_VALUE.intValue()); + assertThat(actual).isEqualTo(INTEGER_VALUE); } @Test From 047c394152440def70cad91a781a61b174e5387c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:06:32 +0200 Subject: [PATCH 1166/1786] Update bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java Co-authored-by: Matteo Mirk --- .../beans/conversion/processor/impl/IntegerConversionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index 88eee41c5..e0ae7bff1 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -94,7 +94,7 @@ public void testConvertShortShouldReturnProperResult() { Integer actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertThat(actual).isEqualTo((Integer) SHORT_VALUE.intValue()); + assertThat(actual).isEqualTo(INTEGER_VALUE); } @Test From 2254fa50b8efebc3c40dfc62e7332677ee4578f9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:13:10 +0200 Subject: [PATCH 1167/1786] Apply suggestions from code review Co-authored-by: Matteo Mirk --- .../processor/impl/IntegerConversionTest.java | 14 +++++++------- .../processor/impl/LongConversionTest.java | 18 +++++++++--------- .../processor/impl/ShortConversionTest.java | 16 ++++++++-------- .../processor/impl/StringConversionTest.java | 10 +++++----- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index e0ae7bff1..9d7be2a8e 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -116,7 +116,7 @@ public void testConvertLongShouldReturnProperResult() { Integer actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertThat(actual).isEqualTo((Integer) LONG_VALUE.intValue()); + assertThat(actual).isEqualTo(INTEGER_VALUE); } @Test @@ -127,7 +127,7 @@ public void testConvertFloatShouldReturnProperResult() { Integer actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertThat(actual).isEqualTo((Integer) FLOAT_VALUE.intValue()); + assertThat(actual).isEqualTo(INTEGER_VALUE); } @Test @@ -138,7 +138,7 @@ public void testConvertDoubleShouldReturnProperResult() { Integer actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertThat(actual).isEqualTo((Integer) DOUBLE_VALUE.intValue()); + assertThat(actual).isEqualTo(INTEGER_VALUE); } @Test @@ -149,7 +149,7 @@ public void testConvertCharacterShouldReturnProperResult() { Integer actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertThat(actual).isEqualTo((Integer) getNumericValue(CHAR_VALUE)); + assertThat(actual).isOne(); } /** @@ -189,7 +189,7 @@ public void testConvertStringShouldReturnProperResult() { Integer actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); + assertThat(actual).isEqualTo(INTEGER_VALUE); } @Test @@ -201,7 +201,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { int actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } @Test @@ -213,6 +213,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { int actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java index db34d1307..7ee030404 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java @@ -63,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Long actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertThat(actual).isEqualTo((Long) BYTE_VALUE.longValue()); + assertThat(actual).isEqualTo(LONG_VALUE); } @Test @@ -94,7 +94,7 @@ public void testConvertShortShouldReturnProperResult() { Long actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertThat(actual).isEqualTo((Long) SHORT_VALUE.longValue()); + assertThat(actual).isEqualTo(LONG_VALUE); } @Test @@ -105,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { Long actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertThat(actual).isEqualTo((Long) INTEGER_VALUE.longValue()); + assertThat(actual).isEqualTo(LONG_VALUE); } @Test @@ -127,7 +127,7 @@ public void testConvertFloatShouldReturnProperResult() { Long actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertThat(actual).isEqualTo((Long) FLOAT_VALUE.longValue()); + assertThat(actual).isEqualTo(LONG_VALUE); } @Test @@ -138,7 +138,7 @@ public void testConvertDoubleShouldReturnProperResult() { Long actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertThat(actual).isEqualTo((Long) DOUBLE_VALUE.longValue()); + assertThat(actual).isEqualTo(LONG_VALUE); } @Test @@ -149,7 +149,7 @@ public void testConvertCharacterShouldReturnProperResult() { Long actual = underTest.convertCharacter().apply(CHAR_VALUE); // THEN - assertThat(actual).isEqualTo(valueOf(getNumericValue(CHAR_VALUE))); + assertThat(actual).isOne(); } /** @@ -189,7 +189,7 @@ public void testConvertStringShouldReturnProperResult() { Long actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); + assertThat(actual).isEqualTo(LONG_VALUE); } @Test @@ -201,7 +201,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { long actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } @Test @@ -213,6 +213,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { long actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java index 7ad948b6f..335b61033 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java @@ -63,7 +63,7 @@ public void testConvertByteShouldReturnProperResult() { Short actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertThat(actual).isEqualTo((Short) BYTE_VALUE.shortValue()); + assertThat(actual).isEqualTo(SHORT_VALUE); } @Test @@ -105,7 +105,7 @@ public void testConvertIntegerShouldReturnProperResult() { Short actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertThat(actual).isEqualTo((Short) INTEGER_VALUE.shortValue()); + assertThat(actual).isEqualTo(SHORT_VALUE); } @Test @@ -116,7 +116,7 @@ public void testConvertLongShouldReturnProperResult() { Short actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertThat(actual).isEqualTo((Short) LONG_VALUE.shortValue()); + assertThat(actual).isEqualTo(SHORT_VALUE); } @Test @@ -127,7 +127,7 @@ public void testConvertFloatShouldReturnProperResult() { Short actual = underTest.convertFloat().apply(FLOAT_VALUE); // THEN - assertThat(actual).isEqualTo((Short) FLOAT_VALUE.shortValue()); + assertThat(actual).isEqualTo(SHORT_VALUE); } @Test @@ -138,7 +138,7 @@ public void testConvertDoubleShouldReturnProperResult() { Short actual = underTest.convertDouble().apply(DOUBLE_VALUE); // THEN - assertThat(actual).isEqualTo((Short) DOUBLE_VALUE.shortValue()); + assertThat(actual).isEqualTo(SHORT_VALUE); } @Test @@ -189,7 +189,7 @@ public void testConvertStringShouldReturnProperResult() { Short actual = underTest.convertString().apply(STRING_VALUE); // THEN - assertThat(actual).isEqualTo(valueOf(STRING_VALUE)); + assertThat(actual).isEqualTo(SHORT_VALUE); } @Test @@ -201,7 +201,7 @@ public void testConvertBigIntegerShouldReturnProperResult() { short actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } @Test @@ -213,6 +213,6 @@ public void testConvertBigDecimalShouldReturnProperResult() { short actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } } diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java index fbfdd7d00..7fdc2b1a0 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java @@ -56,7 +56,7 @@ public void testConvertByteShouldReturnProperResult() { String actual = underTest.convertByte().apply(BYTE_VALUE); // THEN - assertThat(actual).isEqualTo(BYTE_VALUE.toString()); + assertThat(actual).isEqualTo(STRING_VALUE); } @Test @@ -79,7 +79,7 @@ public void testConvertShortShouldReturnProperResult() { String actual = underTest.convertShort().apply(SHORT_VALUE); // THEN - assertThat(actual).isEqualTo(SHORT_VALUE.toString()); + assertThat(actual).isEqualTo(STRING_VALUE); } @Test @@ -90,7 +90,7 @@ public void testConvertIntegerShouldReturnProperResult() { String actual = underTest.convertInteger().apply(INTEGER_VALUE); // THEN - assertThat(actual).isEqualTo(INTEGER_VALUE.toString()); + assertThat(actual).isEqualTo(STRING_VALUE); } @Test @@ -101,7 +101,7 @@ public void testConvertLongShouldReturnProperResult() { String actual = underTest.convertLong().apply(LONG_VALUE); // THEN - assertThat(actual).isEqualTo(LONG_VALUE.toString()); + assertThat(actual).isEqualTo(STRING_VALUE); } @Test @@ -145,7 +145,7 @@ public void testConvertBooleanShouldReturnProperResult() { String actual = underTest.convertBoolean().apply(BOOLEAN_VALUE); // THEN - assertThat(actual).isEqualTo(BOOLEAN_VALUE.toString()); + assertThat(actual).isEqualTo(TRUE_AS_STRING); } @Test From f39d14b8ae81f31649a36c7965e4092bbc4bd9fa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:13:18 +0200 Subject: [PATCH 1168/1786] Changes as per PR --- .../beans/conversion/processor/impl/IntegerConversionTest.java | 2 -- .../beans/conversion/processor/impl/LongConversionTest.java | 2 -- .../beans/conversion/processor/impl/ShortConversionTest.java | 2 -- 3 files changed, 6 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index 8cc8ef64a..76f346d03 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -195,7 +195,6 @@ public void testConvertStringShouldReturnProperResult() { @Test public void testConvertBigIntegerShouldReturnProperResult() { // GIVEN - int expectedValue = BigInteger.ZERO.intValue(); // WHEN int actual = underTest.convertBigInteger().apply(BigInteger.ZERO); @@ -207,7 +206,6 @@ public void testConvertBigIntegerShouldReturnProperResult() { @Test public void testConvertBigDecimalShouldReturnProperResult() { // GIVEN - int expectedValue = BigDecimal.ZERO.intValue(); // WHEN int actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java index db34d1307..d98545679 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java @@ -195,7 +195,6 @@ public void testConvertStringShouldReturnProperResult() { @Test public void testConvertBigIntegerShouldReturnProperResult() { // GIVEN - long expectedValue = BigInteger.ZERO.longValue(); // WHEN long actual = underTest.convertBigInteger().apply(BigInteger.ZERO); @@ -207,7 +206,6 @@ public void testConvertBigIntegerShouldReturnProperResult() { @Test public void testConvertBigDecimalShouldReturnProperResult() { // GIVEN - long expectedValue = BigDecimal.ZERO.longValue(); // WHEN long actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java index 7ad948b6f..73ab40326 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java @@ -195,7 +195,6 @@ public void testConvertStringShouldReturnProperResult() { @Test public void testConvertBigIntegerShouldReturnProperResult() { // GIVEN - short expectedValue = BigInteger.ZERO.shortValue(); // WHEN short actual = underTest.convertBigInteger().apply(BigInteger.ZERO); @@ -207,7 +206,6 @@ public void testConvertBigIntegerShouldReturnProperResult() { @Test public void testConvertBigDecimalShouldReturnProperResult() { // GIVEN - short expectedValue = BigDecimal.ZERO.shortValue(); // WHEN short actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); From f22d82b4c8117cc589a938c84533d4399d2057a9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 27 Jun 2020 16:17:32 +0200 Subject: [PATCH 1169/1786] Changes as per PR --- .../processor/impl/IntegerConversionTest.java | 2 -- .../processor/impl/LongConversionTest.java | 2 -- .../map/transformer/MapTransformerTest.java | 27 +++++++++---------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index c6b0c726a..791431cc8 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -16,8 +16,6 @@ package com.hotels.beans.conversion.processor.impl; -import static java.lang.Character.getNumericValue; -import static java.lang.Integer.valueOf; import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java index 1f56cc2b9..8c49d1a0c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java @@ -16,8 +16,6 @@ package com.hotels.beans.conversion.processor.impl; -import static java.lang.Character.getNumericValue; -import static java.lang.Long.valueOf; import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index bc971117f..9300b482e 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -18,9 +18,11 @@ import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; -import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static org.assertj.core.util.Lists.list; +import static org.assertj.core.util.Maps.newHashMap; import static org.mockito.MockitoAnnotations.initMocks; import java.math.BigInteger; @@ -152,10 +154,10 @@ public void testTransformWorksProperlyWithKeyMapping() { Map actual = underTest.transform(sourceMap); //THEN - assertThat(actual).isNotNull(); - assertThat(actual.size()).isEqualTo(sourceMap.size()); - assertThat(actual.get(MAP_KEY_1)).isEqualTo(sourceMap.get(MAP_KEY_1)); - assertThat(actual.get(MAP_KEY_2)).isEqualTo(sourceMap.get(MAP_KEY_1)); + assertThat(actual).containsOnly( + entry(MAP_KEY_1, ZERO), + entry(MAP_KEY_2, ZERO) + ); underTest.resetFieldsMapping(); } @@ -217,22 +219,19 @@ public void testTransformWorksProperlyWithTargetKeyAndElemType() { * Test that the given map is correctly transformed and the elements are correctly transformed if the Map contains a List. */ @Test + @SuppressWarnings("unchecked") public void testTransformWorksProperlyWithMapContainingList() { //GIVEN - List sampleList = singletonList(ITEM_1); - Map> sourceMap = new HashMap<>(); - sourceMap.put(fromFooSimple, sampleList); + Map> sourceMap = newHashMap(fromFooSimple, list(ITEM_1)); //WHEN Map actual = underTest.transform(sourceMap, MutableToFooSimple.class, List.class); //THEN - assertThat(actual).isNotNull(); - assertThat(actual.size()).isEqualTo(sourceMap.size()); - for (Map.Entry entry : actual.entrySet()) { - assertThat(entry.getKey().getClass()).isEqualTo(MutableToFooSimple.class); - assertThat(entry.getValue()).isEqualTo(sampleList); - } + assertThat(actual).allSatisfy((key, value) -> { + assertThat(key).isInstanceOf(MutableToFooSimple.class); + assertThat(value).containsOnly(ITEM_1); + }); } /** From 20e87e684facdf3cbacf81aab184b0aa2f67b362 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Jun 2020 08:50:30 +0200 Subject: [PATCH 1170/1786] Changes as per PR --- .../transformer/BeanTransformerTest.java | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 5a0d79eb2..93bc81746 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -20,6 +20,8 @@ import static java.util.Optional.empty; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; @@ -33,6 +35,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Parameter; +import org.assertj.core.api.ThrowableAssert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -194,19 +197,12 @@ public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined getSourceFieldValueMethod.setAccessible(true); //WHEN - Exception raisedException = null; - Object actual = null; - try { - actual = getSourceFieldValueMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME, field, true); - } catch (final Exception e) { - raisedException = e; - } + ThrowableAssert.ThrowingCallable actual = () -> getSourceFieldValueMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME, field, true); //THEN + assertThatCode(actual).doesNotThrowAnyException(); verify(reflectionUtilsMock).getFieldValue(FromFooSimple.class, AGE_FIELD_NAME, fieldType); verify(field).getType(); - assertThat(raisedException).isNull(); - assertThat(actual).isNull(); restoreUnderTestObject(); } @@ -326,20 +322,14 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception getSourceFieldTypeMethod.setAccessible(true); //WHEN - Exception raisedException = null; - try { - getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); - } catch (final Exception e) { - raisedException = e; - } + ThrowableAssert.ThrowingCallable code = () -> getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); //THEN + assertThatThrownBy(code).hasCauseInstanceOf(MissingFieldException.class); verify(cacheManager).getFromCache(anyString(), any(Class.class)); verify(reflectionUtilsMock).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); verify(classUtils).isPrimitiveType(FromFooSimple.class); verify(settings).isSetDefaultValueForMissingField(); - assertThat(raisedException).isNotNull(); - assertThat(raisedException.getCause().getClass()).isEqualTo(MissingFieldException.class); restoreUnderTestObject(); } From cc013412dbb5019c5208b707c01034b877578c2d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Jun 2020 08:54:59 +0200 Subject: [PATCH 1171/1786] Minor improvements --- .../beans/transformer/BeanTransformerTest.java | 4 ++-- .../ImmutableObjectTransformationTest.java | 4 ++-- .../MutableObjectTransformationTest.java | 4 ++-- .../transformer/utils/ReflectionUtilsTest.java | 13 ++++++------- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 93bc81746..0a42f0355 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -322,10 +322,10 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception getSourceFieldTypeMethod.setAccessible(true); //WHEN - ThrowableAssert.ThrowingCallable code = () -> getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); + ThrowableAssert.ThrowingCallable actual = () -> getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); //THEN - assertThatThrownBy(code).hasCauseInstanceOf(MissingFieldException.class); + assertThatThrownBy(actual).hasCauseInstanceOf(MissingFieldException.class); verify(cacheManager).getFromCache(anyString(), any(Class.class)); verify(reflectionUtilsMock).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); verify(classUtils).isPrimitiveType(FromFooSimple.class); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 4c189d8ff..125d73957 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -414,10 +414,10 @@ public void testTransformationReturnsAMeaningfulException() { format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getName()); //WHEN - ThrowableAssert.ThrowingCallable code = () -> underTest.transform(fromFooSimple, targetClass); + ThrowableAssert.ThrowingCallable actual = () -> underTest.transform(fromFooSimple, targetClass); //THEN - assertThatThrownBy(code).isInstanceOf(InvalidBeanException.class) + assertThatThrownBy(actual).isInstanceOf(InvalidBeanException.class) .hasMessage(expectedExceptionMessage); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index c0361debf..1a1b8cbed 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -245,10 +245,10 @@ public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeCo underTest.setPrimitiveTypeConversionEnabled(true); //WHEN - ThrowableAssert.ThrowingCallable code = () -> underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); + ThrowableAssert.ThrowingCallable actual = () -> underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); //THEN - assertThatThrownBy(code).hasCauseInstanceOf(MissingFieldException.class); + assertThatThrownBy(actual).hasCauseInstanceOf(MissingFieldException.class); underTest.setPrimitiveTypeConversionEnabled(false); } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index fa321b4df..1d996a939 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -460,7 +460,6 @@ public void testInvokeMethodWorksProperly() throws Exception { /** * Tests that the method {@code getSetterMethodForField} raises an {@link InvocationTargetException} if the argument is wrong. - * @throws Exception if something goes wrong. */ @Test public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong() { @@ -470,12 +469,12 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong // WHEN - ThrowableAssert.ThrowingCallable code = () -> + ThrowableAssert.ThrowingCallable actual = () -> getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) .invoke(underTest, idSetterMethod, mutableToFoo, new Object[]{ONE}); // THEN - assertThatThrownBy(code).hasCauseInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(actual).hasCauseInstanceOf(IllegalArgumentException.class); } /** @@ -683,11 +682,11 @@ public void testGetGetterMethodThrowsExceptionIfTheMethodDoesNotExists() throws Method methodUnderTest = getMethod(underTest.getClass(), GET_GETTER_METHOD_NAME, true, Class.class, String.class, Class.class); // WHEN - ThrowableAssert.ThrowingCallable code = () -> + ThrowableAssert.ThrowingCallable actual = () -> methodUnderTest.invoke(underTest, FromFooSimpleNoGetters.class, ID_FIELD_NAME, BigInteger.class); // THEN - assertThatThrownBy(code).hasCauseInstanceOf(MissingFieldException.class); + assertThatThrownBy(actual).hasCauseInstanceOf(MissingFieldException.class); } /** @@ -761,11 +760,11 @@ public void testInvokeMethodCorrectlyHandlesExceptions(final String testCaseDesc Method setMethodToInvoke = getMethod(targetObject.getClass(), methodNameToInvoke, isAccessible, String.class); // WHEN - ThrowableAssert.ThrowingCallable code = () -> + ThrowableAssert.ThrowingCallable actual = () -> underTest.invokeMethod(setMethodToInvoke, targetObject, methodArg); // THEN - assertThatThrownBy(code).isInstanceOf(expectedException); + assertThatThrownBy(actual).isInstanceOf(expectedException); } /** From 7a1bb1dfa2f9e16c19170c744b4ca0cf2e2e1eef Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Jun 2020 09:15:57 +0200 Subject: [PATCH 1172/1786] minor improvements --- .../hotels/beans/transformer/AbstractBeanTransformerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index 3c998cb4f..79e667746 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -44,7 +44,7 @@ public abstract class AbstractBeanTransformerTest extends AbstractTransformerTes * Initializes the arguments and objects. */ @BeforeClass - public void beforeClass() { + void beforeClass() { initObjects(); } @@ -52,7 +52,7 @@ public void beforeClass() { * Initialized mocks. */ @BeforeMethod - public void beforeMethod() { + void beforeMethod() { initMocks(this); } } From 23363826b51781f1e385c8a9e8b85339367b8dda Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Jun 2020 11:35:50 +0200 Subject: [PATCH 1173/1786] Removes not needed Suppression and Exceptions not thrown in the javadoc --- .../java/com/hotels/beans/populator/PopulatorFactoryTest.java | 2 +- .../beans/transformer/ImmutableObjectTransformationTest.java | 1 - .../java/com/hotels/transformer/AbstractTransformerTest.java | 2 +- .../java/com/hotels/transformer/utils/ReflectionUtilsTest.java | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index 4ffd68e94..f8bcce8ab 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -79,7 +79,7 @@ public Object[][] dataProvider() { * @param expectedResult the expected populator */ @Test(dataProvider = "dataProvider") - @SuppressWarnings({"unchecked", "OptionalGetWithoutIsPresent"}) + @SuppressWarnings({"unchecked"}) public void testGetPopulatorReturnsTheExpectedResult(final Class type, final Class expectedResult) { // GIVEN diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 125d73957..20eddf1fa 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -154,7 +154,6 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { * @param expectedId the expected id * @param expectedPhoneNumbers the expected phone number */ - @SuppressWarnings("unchecked") @Test(dataProvider = "dataCompositeFieldNameTesting") public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(final String testCaseDescription, final Object sourceObject, final String expectedName, final BigInteger expectedId, final int[] expectedPhoneNumbers) { diff --git a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java index edf865be2..57daa0252 100644 --- a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java @@ -44,9 +44,9 @@ * Unit test for {@link com.hotels.transformer.Transformer}. */ public abstract class AbstractTransformerTest { - public static FromFoo fromFoo; protected static final BigInteger ID = new BigInteger("1234"); protected static final String NAME = "Goofy"; + protected static FromFoo fromFoo; protected static FromFoo fromFooWithNullProperties; protected static FromFooSimple fromFooSimple; protected static FromFooWithPrimitiveFields fromFooWithPrimitiveFields; diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 1d996a939..bf3a0a4ab 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -496,7 +496,6 @@ public void testGetDeclaredFieldWorksProperly(final String testCaseDescription, /** * Test that the method: {@code getClassDeclaredField} throws the right exception. - * @throws Exception if the invoke method fails */ @Test public void testGetClassDeclaredFieldThrowsTheRightException() { From 5fc15271ba04ac9b44711c09c288f1a079de333d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Jun 2020 11:45:28 +0200 Subject: [PATCH 1174/1786] updates the assertj site link --- docs/site/markdown/transformer/bean/testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/site/markdown/transformer/bean/testing.md b/docs/site/markdown/transformer/bean/testing.md index 3d05df29c..aa93f4800 100644 --- a/docs/site/markdown/transformer/bean/testing.md +++ b/docs/site/markdown/transformer/bean/testing.md @@ -14,7 +14,7 @@ extent to which the component or system under test: * can be installed and run in its intended environments * achieves the general result its stakeholders desire. -This page will show how to test BULL into a simple project. All the examples utilize [JUnit](https://github.com/junit-team), [Mockito](https://site.mockito.org/) and [AssertJ](http://joel-costigliola.github.io/assertj/) +This page will show how to test BULL into a simple project. All the examples utilize [JUnit](https://github.com/junit-team), [Mockito](https://site.mockito.org/) and [AssertJ](https://assertj.github.io/doc/) The Java Bean transformation function can be tested in two different ways that depends on the following scenarios: From c0f6c816bf7f772a55cc85f26f5097c5cd41bb3f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Jun 2020 16:26:09 +0200 Subject: [PATCH 1175/1786] Removes not needed spring boot version --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index f62564cc2..31f9f306f 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,6 @@ 11 ${jdk.version} ${jdk.version} - 2.3.1.RELEASE 1.18.12 3.10 1.3.0 From 8b5adf58ae5dd13caa47cce5bd56adfa0bdbaf7d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Jun 2020 16:36:02 +0200 Subject: [PATCH 1176/1786] Increase jacoco thresholds --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 31f9f306f..7e7256655 100644 --- a/pom.xml +++ b/pom.xml @@ -66,11 +66,11 @@ 0.8.5 1.0 - 0.90 + 0.98 1.0 - 0.87 - 0.90 - 0.90 + 0.89 + 0.91 + 0.98 **/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* 2.3.1 From 3ec7cca322e975f12aa550e31aa6198f96758542 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 28 Jun 2020 21:58:04 +0200 Subject: [PATCH 1177/1786] Minor improvements --- .../java/com/hotels/beans/BeanUtilsTest.java | 8 +++----- .../beans/populator/ArrayPopulatorTest.java | 17 ++++++++--------- .../beans/transformer/BeanTransformerTest.java | 6 +++--- .../ImmutableObjectTransformationTest.java | 4 ++-- .../MutableObjectTransformationTest.java | 4 ++-- .../transformer/utils/ReflectionUtilsTest.java | 8 ++++---- .../map/transformer/MapTransformerTest.java | 6 ++---- 7 files changed, 24 insertions(+), 29 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java index 76d2fbe97..187f36d52 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.IntStream; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; @@ -104,10 +103,9 @@ public void testGetTransformerFunctionWorksProperly(final String testCaseDescrip //THEN assertThat(transformerFunction).isNotNull(); - IntStream.range(0, actual.size()) - .forEach(i -> assertThat(actual.get(i)) - .isEqualToComparingFieldByField(fromFooSimpleList.get(i)) - .usingRecursiveComparison()); + assertThat(actual).usingRecursiveComparison() + .ignoringAllOverriddenEquals() + .isEqualTo(fromFooSimpleList); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 70f47c48c..634487f31 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -69,15 +69,14 @@ public void beforeClass() { * Tests that the method {@code getPopulatedObject} works as expected. * @param genericFieldType the field to be populated class * @param array the source object from which extract the values - * @param nestedGenericClass the nested generic object class. */ @Test(dataProvider = "dataProvider") - public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, final Object array, final Class nestedGenericClass) { + public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, final Object array) { // GIVEN when(transformer.transform(any(), eq(MixedToFooStaticField.class))).thenReturn(MIXED_TO_FOO_STATIC_FIELDS_OBJECTS); // WHEN - Object actual = underTest.getPopulatedObject(null, genericFieldType, array, nestedGenericClass); + Object actual = underTest.getPopulatedObject(null, genericFieldType, array, null); // THEN if (genericFieldType == Character.class) { @@ -91,7 +90,7 @@ public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, .usingElementComparatorOnFields(NORMAL_FIELD) .isEqualTo(array); } else { - assertThat((Object[]) actual).isEqualTo(array); + assertThat(actual).isEqualTo(array); } } @@ -102,11 +101,11 @@ public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, @DataProvider public Object[][] dataProvider() { return new Object[][]{ - {String.class, STRING_ARRAY, null}, - {Character.class, CHAR_ARRAY, null}, - {Integer.class, INT_ARRAY, null}, - {MixedToFooStaticField.class, createMixedToFooArray(), null}, - {Object.class, createBooleanArray(), null} + {String.class, STRING_ARRAY}, + {Character.class, CHAR_ARRAY}, + {Integer.class, INT_ARRAY}, + {MixedToFooStaticField.class, createMixedToFooArray()}, + {Object.class, createBooleanArray()} }; } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 0a42f0355..b2a928b3d 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -35,7 +35,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Parameter; -import org.assertj.core.api.ThrowableAssert; +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -197,7 +197,7 @@ public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined getSourceFieldValueMethod.setAccessible(true); //WHEN - ThrowableAssert.ThrowingCallable actual = () -> getSourceFieldValueMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME, field, true); + ThrowingCallable actual = () -> getSourceFieldValueMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME, field, true); //THEN assertThatCode(actual).doesNotThrowAnyException(); @@ -322,7 +322,7 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception getSourceFieldTypeMethod.setAccessible(true); //WHEN - ThrowableAssert.ThrowingCallable actual = () -> getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); + ThrowingCallable actual = () -> getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); //THEN assertThatThrownBy(actual).hasCauseInstanceOf(MissingFieldException.class); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 20eddf1fa..fe556a48f 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -31,7 +31,7 @@ import java.util.Locale; import java.util.Optional; -import org.assertj.core.api.ThrowableAssert; +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.testng.annotations.AfterMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -413,7 +413,7 @@ public void testTransformationReturnsAMeaningfulException() { format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getName()); //WHEN - ThrowableAssert.ThrowingCallable actual = () -> underTest.transform(fromFooSimple, targetClass); + ThrowingCallable actual = () -> underTest.transform(fromFooSimple, targetClass); //THEN assertThatThrownBy(actual).isInstanceOf(InvalidBeanException.class) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 1a1b8cbed..240020fb6 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -31,7 +31,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Parameter; -import org.assertj.core.api.ThrowableAssert; +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -245,7 +245,7 @@ public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeCo underTest.setPrimitiveTypeConversionEnabled(true); //WHEN - ThrowableAssert.ThrowingCallable actual = () -> underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); + ThrowingCallable actual = () -> underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); //THEN assertThatThrownBy(actual).hasCauseInstanceOf(MissingFieldException.class); diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index bf3a0a4ab..9cbfc60b1 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -48,7 +48,7 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import org.assertj.core.api.ThrowableAssert; +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.mockito.InjectMocks; import org.mockito.Mockito; import org.testng.annotations.BeforeClass; @@ -469,7 +469,7 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong // WHEN - ThrowableAssert.ThrowingCallable actual = () -> + ThrowingCallable actual = () -> getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) .invoke(underTest, idSetterMethod, mutableToFoo, new Object[]{ONE}); @@ -681,7 +681,7 @@ public void testGetGetterMethodThrowsExceptionIfTheMethodDoesNotExists() throws Method methodUnderTest = getMethod(underTest.getClass(), GET_GETTER_METHOD_NAME, true, Class.class, String.class, Class.class); // WHEN - ThrowableAssert.ThrowingCallable actual = () -> + ThrowingCallable actual = () -> methodUnderTest.invoke(underTest, FromFooSimpleNoGetters.class, ID_FIELD_NAME, BigInteger.class); // THEN @@ -759,7 +759,7 @@ public void testInvokeMethodCorrectlyHandlesExceptions(final String testCaseDesc Method setMethodToInvoke = getMethod(targetObject.getClass(), methodNameToInvoke, isAccessible, String.class); // WHEN - ThrowableAssert.ThrowingCallable actual = () -> + ThrowingCallable actual = () -> underTest.invokeMethod(setMethodToInvoke, targetObject, methodArg); // THEN diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 9300b482e..87aa99fb6 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -209,10 +209,8 @@ public void testTransformWorksProperlyWithTargetKeyAndElemType() { assertThat(actual).isNotNull(); assertThat(actual.size()).isEqualTo(EXTREME_COMPLEX_MAP.size()); // check that the element has been converted - for (Map.Entry entry : actual.entrySet()) { - assertThat(entry.getKey().getClass()) - .isEqualTo(MutableToFooSimple.class); - } + assertThat(actual).allSatisfy((key, value) -> + assertThat(key).isInstanceOf(MutableToFooSimple.class)); } /** From a61fec72bd8c38651594c62b5c681d62ea4cc296 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 29 Jun 2020 07:11:21 +0200 Subject: [PATCH 1178/1786] Minor improvements --- .../java/com/hotels/beans/conversion/ConverterTest.java | 7 +++---- .../conversion/processor/impl/FloatConversionTest.java | 6 ++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index dd783290c..f75512334 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -19,7 +19,6 @@ import static java.lang.Character.getNumericValue; import static java.math.BigInteger.ZERO; import static java.nio.ByteBuffer.wrap; -import static java.util.Optional.empty; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.initMocks; @@ -89,7 +88,7 @@ public void testGetConversionFunctionReturnsAnEmptyOptional(final String testCas Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN - assertThat(actual).isEqualTo(empty()); + assertThat(actual).isEmpty(); } /** @@ -113,6 +112,7 @@ private Object[][] dataGetConversionFunctionEmptyCaseTesting() { * @param destinationFieldType the destination field class * @param expectedConversionFunction the expected {@link com.hotels.beans.conversion.processor.ConversionProcessor} instance */ + @SuppressWarnings("unchecked") @Test(dataProvider = "dataGetConversionFunctionTesting") public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final String testCaseDescription, final Class sourceFieldType, final Class destinationFieldType, final Function expectedConversionFunction) { @@ -122,8 +122,7 @@ public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final Optional> actual = underTest.getConversionFunction(sourceFieldType, destinationFieldType); // THEN - assertThat(actual.isPresent()).isTrue(); - assertThat(actual.get()).isEqualTo(expectedConversionFunction); + assertThat(actual).contains((Function) expectedConversionFunction); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 1a5482315..7323a35e4 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -195,24 +195,22 @@ public void testConvertStringShouldReturnProperResult() { @Test public void testConvertBigIntegerShouldReturnProperResult() { // GIVEN - double expectedValue = BigInteger.ZERO.floatValue(); // WHEN double actual = underTest.convertBigInteger().apply(BigInteger.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } @Test public void testConvertBigDecimalShouldReturnProperResult() { // GIVEN - float expectedValue = BigDecimal.ZERO.floatValue(); // WHEN float actual = underTest.convertBigDecimal().apply(BigDecimal.ZERO); // THEN - assertThat(actual).isEqualTo(expectedValue); + assertThat(actual).isZero(); } } From 9b93c9e083331f815d860bee939a648f062536a3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 29 Jun 2020 15:43:03 +0200 Subject: [PATCH 1179/1786] Removes duplicated slf4j-api dependency --- pom.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pom.xml b/pom.xml index 7e7256655..a25085b08 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,6 @@ 3.3.3 7.1.0 3.16.1 - 1.7.30 2.0.1.Final 6.1.5.Final @@ -167,12 +166,6 @@ ${assertj-core.version} test - - org.slf4j - slf4j-api - ${slf4j-api.version} - test - From 2843f83324c919b4cd87c9b0ef163732925ed93e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2020 02:18:43 +0000 Subject: [PATCH 1180/1786] Bump mockito-core from 3.3.3 to 3.4.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.3.3 to 3.4.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.3.3...v3.4.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a25085b08..e07d2f2ec 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.10 1.3.0 - 3.3.3 + 3.4.0 7.1.0 3.16.1 From 543493324e68b03c82c033b3e481ee4c3c1e1e92 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2020 02:14:35 +0000 Subject: [PATCH 1181/1786] Bump mockito-core from 3.4.0 to 3.4.2 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.4.0 to 3.4.2. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.4.0...v3.4.2) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e07d2f2ec..4b9a2df5b 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.10 1.3.0 - 3.4.0 + 3.4.2 7.1.0 3.16.1 From db0ed51e19fb263b761fd11ac53927a76fab391d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2020 05:12:56 +0000 Subject: [PATCH 1182/1786] Bump commons-lang3 from 3.10 to 3.11 Bumps commons-lang3 from 3.10 to 3.11. Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4b9a2df5b..262805044 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ ${jdk.version} ${jdk.version} 1.18.12 - 3.10 + 3.11 1.3.0 3.4.2 From 7976c05993e54904b558209394665375bdabd62c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2020 02:19:49 +0000 Subject: [PATCH 1183/1786] Bump mockito-core from 3.4.2 to 3.4.4 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.4.2 to 3.4.4. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.4.2...v3.4.4) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 262805044..947ae897b 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.4.2 + 3.4.4 7.1.0 3.16.1 From fffc236df29b31faadcafd8364d0e349d5160b20 Mon Sep 17 00:00:00 2001 From: fborriello Date: Tue, 21 Jul 2020 17:08:39 +0200 Subject: [PATCH 1184/1786] Trigger notification From cc8e57b1bafc2f09455b884f1dbd477acd4470f8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 30 Jul 2020 02:24:21 +0000 Subject: [PATCH 1185/1786] Bump mockito-core from 3.4.4 to 3.4.6 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.4.4 to 3.4.6. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.4.4...v3.4.6) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 947ae897b..be3fd2321 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.4.4 + 3.4.6 7.1.0 3.16.1 From edd5f8e68681a81fc93eeaaeca57282f1d69e768 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 30 Jul 2020 14:56:43 +0200 Subject: [PATCH 1186/1786] Provides a documentation on how to use the library within Kotlin projects --- README.md | 1 + docs/site/markdown/transformer/bean/kotlin.md | 41 +++++++++++++++++++ docs/site/site.xml | 1 + 3 files changed, 43 insertions(+) create mode 100644 docs/site/markdown/transformer/bean/kotlin.md diff --git a/README.md b/README.md index 19e964a3b..aaead3693 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ mvnw.cmd clean install -P relaxed * [Primitive Type conversion](https://github.com/HotelsDotCom/bull#primitive-type-object-converter) * [Map Transformation](https://hotelsdotcom.github.io/bull/transformer/map/samples.html) * [Supported Builder Pattern](https://hotelsdotcom.github.io/bull/transformer/bean/builder.html) +* [How to use it in Kotlin](https://hotelsdotcom.github.io/bull/transformer/bean/kotlin.html) ## Bean transformation samples diff --git a/docs/site/markdown/transformer/bean/kotlin.md b/docs/site/markdown/transformer/bean/kotlin.md new file mode 100644 index 000000000..fd3721513 --- /dev/null +++ b/docs/site/markdown/transformer/bean/kotlin.md @@ -0,0 +1,41 @@ + + Kotlin project integration + + +# Kotlin project integration + +This page shows how to use BULL inside a Kotlin project. + +## Step 1 + +Add the project dependency into your `pom.xml` file: + +```xml + + com.hotels.beans + bull-bean-transformer + x.y.z + +``` + +## Step 2 + +Given the following source object: + +```kotlin +data class FromBean(val name: String) +``` + +and the following destination one: + +```kotlin +data class ToBean(val name: String) +``` + +To transform the one into the other: + +```kotlin +val fromBean = FromBean("Goofy") +BeanUtils().transformer.transform(fromBean, ToBean::class.java) +``` + diff --git a/docs/site/site.xml b/docs/site/site.xml index 017b989e7..53c84f6f9 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -43,6 +43,7 @@ + From e3f6f633349fabc1a9bc5a94af8a0d5e6354ea4a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 30 Jul 2020 14:58:54 +0200 Subject: [PATCH 1187/1786] minor change --- docs/site/site.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/site/site.xml b/docs/site/site.xml index 53c84f6f9..c0de7ea5f 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -43,7 +43,7 @@ - + From a1c43eb7f4b570fd717cbfea1e9bf8dd3a9fcde6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 30 Jul 2020 15:13:46 +0200 Subject: [PATCH 1188/1786] Moves the kotlin page outside the "transformer" subpage as it refers to all features --- CHANGELOG.md | 3 +++ README.md | 2 +- docs/site/markdown/{transformer/bean => }/kotlin.md | 1 + docs/site/site.xml | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) rename docs/site/markdown/{transformer/bean => }/kotlin.md (86%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01225ff03..99d042f19 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +### [1.7.4] 2020.07.30 +* Provides a guide on how to use it within Kotlin project + ### [1.7.3] 2020.06.09 #### Changed * Removes the deprecated method: `setDefaultValueSetEnabled` diff --git a/README.md b/README.md index aaead3693..bfc75c8e1 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ mvnw.cmd clean install -P relaxed * [Primitive Type conversion](https://github.com/HotelsDotCom/bull#primitive-type-object-converter) * [Map Transformation](https://hotelsdotcom.github.io/bull/transformer/map/samples.html) * [Supported Builder Pattern](https://hotelsdotcom.github.io/bull/transformer/bean/builder.html) -* [How to use it in Kotlin](https://hotelsdotcom.github.io/bull/transformer/bean/kotlin.html) +* [How to use it in Kotlin](https://hotelsdotcom.github.io/bull/kotlin.html) ## Bean transformation samples diff --git a/docs/site/markdown/transformer/bean/kotlin.md b/docs/site/markdown/kotlin.md similarity index 86% rename from docs/site/markdown/transformer/bean/kotlin.md rename to docs/site/markdown/kotlin.md index fd3721513..b2a2e0d2b 100644 --- a/docs/site/markdown/transformer/bean/kotlin.md +++ b/docs/site/markdown/kotlin.md @@ -5,6 +5,7 @@ # Kotlin project integration This page shows how to use BULL inside a Kotlin project. +It takes as example the Bean transformation, but the same approach can be used for all the other features. ## Step 1 diff --git a/docs/site/site.xml b/docs/site/site.xml index c0de7ea5f..77a0aa585 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -36,6 +36,7 @@ + @@ -43,7 +44,6 @@ - From bfd682cbe70f387921e9aa5f9055e4ab9add9354 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 30 Jul 2020 15:16:04 +0200 Subject: [PATCH 1189/1786] Changes the release version --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99d042f19..91cb99f57 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.7.4] 2020.07.30 +### [1.7.3.1] 2020.07.30 * Provides a guide on how to use it within Kotlin project ### [1.7.3] 2020.06.09 From 360285eb867622eb9cf2683b181babcd405fe1b1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 30 Jul 2020 15:19:20 +0200 Subject: [PATCH 1190/1786] [maven-release-plugin] prepare release 1.7.3.1 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 9424c7691..dc064d0f9 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.4-SNAPSHOT + 1.7.3.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index bec8c8f56..d1a90ec84 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.4-SNAPSHOT + 1.7.3.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 1cb027a46..e7900a1f8 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.4-SNAPSHOT + 1.7.3.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index a61160e60..d1ecd69c8 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.4-SNAPSHOT + 1.7.3.1 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index e8fbbc799..76dbb509c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.4-SNAPSHOT + 1.7.3.1 diff --git a/pom.xml b/pom.xml index be3fd2321..2201aee25 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.4-SNAPSHOT + 1.7.3.1 pom 2019 @@ -94,7 +94,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.7.3.1 From 64155c28ac711339671abf7ae467c1529bd8075a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 30 Jul 2020 15:19:34 +0200 Subject: [PATCH 1191/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index dc064d0f9..9424c7691 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3.1 + 1.7.4-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index d1a90ec84..bec8c8f56 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3.1 + 1.7.4-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index e7900a1f8..1cb027a46 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.3.1 + 1.7.4-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index d1ecd69c8..a61160e60 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.3.1 + 1.7.4-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 76dbb509c..e8fbbc799 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.3.1 + 1.7.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index 2201aee25..be3fd2321 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.3.1 + 1.7.4-SNAPSHOT pom 2019 @@ -94,7 +94,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.3.1 + HEAD From 4bad08c8576c39c3741129d8f1ca3f1f8aaa50f9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 30 Jul 2020 15:36:58 +0200 Subject: [PATCH 1192/1786] Removes not released version --- CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91cb99f57..01225ff03 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,6 @@ All notable changes to this project will be documented in this file. -### [1.7.3.1] 2020.07.30 -* Provides a guide on how to use it within Kotlin project - ### [1.7.3] 2020.06.09 #### Changed * Removes the deprecated method: `setDefaultValueSetEnabled` From 3070ef947dc0eafe4ec75da006c9e509534df566 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2020 02:19:53 +0000 Subject: [PATCH 1193/1786] Bump testng from 7.1.0 to 7.3.0 Bumps [testng](https://github.com/cbeust/testng) from 7.1.0 to 7.3.0. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/commits) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be3fd2321..2c20face4 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 1.3.0 3.4.6 - 7.1.0 + 7.3.0 3.16.1 2.0.1.Final From e94cfeb50d25d12450cda1c6ef5bcb7a7c3f6c7a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 3 Aug 2020 09:54:00 +0200 Subject: [PATCH 1194/1786] Replaces the Mockito deprecated method `initMocks` with the new one: `openMocks` --- .../test/java/com/hotels/beans/BeanUtilsTest.java | 4 ++-- .../hotels/beans/performance/PerformanceTest.java | 4 ++-- .../hotels/beans/populator/ArrayPopulatorTest.java | 4 ++-- .../hotels/beans/populator/PopulatorFactoryTest.java | 4 ++-- .../transformer/AbstractBeanTransformerTest.java | 4 ++-- .../transformer/cache/CacheManagerFactoryTest.java | 4 ++-- .../com/hotels/transformer/utils/ClassUtilsTest.java | 4 ++-- .../transformer/utils/ReflectionUtilsTest.java | 4 ++-- .../hotels/transformer/validator/ValidatorTest.java | 4 ++-- .../com/hotels/beans/conversion/ConverterTest.java | 4 ++-- .../conversion/analyzer/ConversionAnalyzerTest.java | 4 ++-- .../processor/ConversionProcessorFactoryTest.java | 4 ++-- .../processor/impl/BigDecimalConversionTest.java | 4 ++-- .../processor/impl/BigIntegerConversionTest.java | 4 ++-- .../processor/impl/BooleanConversionTest.java | 4 ++-- .../processor/impl/ByteArrayConversionTest.java | 4 ++-- .../processor/impl/ByteConversionTest.java | 4 ++-- .../processor/impl/CharacterConversionTest.java | 4 ++-- .../processor/impl/DoubleConversionTest.java | 4 ++-- .../processor/impl/FloatConversionTest.java | 4 ++-- .../processor/impl/IntegerConversionTest.java | 4 ++-- .../processor/impl/LongConversionTest.java | 4 ++-- .../processor/impl/ShortConversionTest.java | 4 ++-- .../processor/impl/StringConversionTest.java | 4 ++-- .../src/test/java/com/hotels/map/MapUtilsTest.java | 4 ++-- .../hotels/map/transformer/MapTransformerTest.java | 4 ++-- docs/site/markdown/transformer/bean/testing.md | 12 ++++++------ 27 files changed, 58 insertions(+), 58 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java index 187f36d52..b7ca066ad 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -17,7 +17,7 @@ package com.hotels.beans; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigInteger; import java.util.Arrays; @@ -57,7 +57,7 @@ public class BeanUtilsTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java index 2483a2415..03825280f 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -22,7 +22,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -95,7 +95,7 @@ public class PerformanceTest { @BeforeClass public void beforeClass() { initObjects(); - initMocks(this); + openMocks(this); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 634487f31..4d8512124 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -23,7 +23,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import org.mockito.InjectMocks; import org.mockito.Mock; @@ -62,7 +62,7 @@ public class ArrayPopulatorTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index f8bcce8ab..a30c3bc22 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -19,7 +19,7 @@ import static java.util.Objects.nonNull; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.util.List; import java.util.Map; @@ -55,7 +55,7 @@ public class PopulatorFactoryTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index 79e667746..f1f211359 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -16,7 +16,7 @@ package com.hotels.beans.transformer; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; @@ -53,6 +53,6 @@ void beforeClass() { */ @BeforeMethod void beforeMethod() { - initMocks(this); + openMocks(this); } } diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java index 2d87f8f13..53299ee42 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java @@ -17,7 +17,7 @@ package com.hotels.transformer.cache; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; @@ -43,7 +43,7 @@ public class CacheManagerFactoryTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 767ebe56f..f00f883d7 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import static com.hotels.transformer.utils.ClassUtils.BUILD_METHOD_NAME; @@ -122,7 +122,7 @@ public class ClassUtilsTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 9cbfc60b1..befe8828c 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -29,7 +29,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import static com.hotels.transformer.constant.MethodPrefix.GET; import static com.hotels.transformer.constant.MethodPrefix.IS; @@ -109,7 +109,7 @@ public class ReflectionUtilsTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java index fd5565be3..e7e47adb3 100644 --- a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java @@ -20,7 +20,7 @@ import static java.math.BigInteger.ZERO; import static java.util.Objects.nonNull; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import static org.testng.Assert.assertEquals; import java.math.BigInteger; @@ -70,7 +70,7 @@ public class ValidatorTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index f75512334..61ec835ee 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -21,7 +21,7 @@ import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -70,7 +70,7 @@ public class ConverterTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index b9a488f58..e742d26b5 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -17,7 +17,7 @@ package com.hotels.beans.conversion.analyzer; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -57,7 +57,7 @@ public class ConversionAnalyzerTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index 340d27c85..6e9d9b49d 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -17,7 +17,7 @@ package com.hotels.beans.conversion.processor; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -57,7 +57,7 @@ public class ConversionProcessorFactoryTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java index cc08756ac..dd114fd37 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java @@ -21,7 +21,7 @@ import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -49,7 +49,7 @@ public class BigDecimalConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java index 9bb4f4ea5..9e3c46e74 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java @@ -21,7 +21,7 @@ import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -49,7 +49,7 @@ public class BigIntegerConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java index 49fb9f359..ce41568d4 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java @@ -17,7 +17,7 @@ package com.hotels.beans.conversion.processor.impl; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -44,7 +44,7 @@ public class BooleanConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java index 3257b1f36..249ea6563 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java @@ -17,7 +17,7 @@ package com.hotels.beans.conversion.processor.impl; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -47,7 +47,7 @@ public class ByteArrayConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java index 4e7c495e9..dadcf255a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java @@ -17,7 +17,7 @@ package com.hotels.beans.conversion.processor.impl; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -47,7 +47,7 @@ public class ByteConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java index 6adbfbaf7..d2b4dbd76 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java @@ -19,7 +19,7 @@ import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -50,7 +50,7 @@ public class CharacterConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index 4205aafea..a8553dafd 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -20,7 +20,7 @@ import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -51,7 +51,7 @@ public class DoubleConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 7323a35e4..6f2c30d10 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -20,7 +20,7 @@ import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -51,7 +51,7 @@ public class FloatConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index 791431cc8..f84c8aec3 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -19,7 +19,7 @@ import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -50,7 +50,7 @@ public class IntegerConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java index 8c49d1a0c..0bf97dfbe 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java @@ -19,7 +19,7 @@ import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -50,7 +50,7 @@ public class LongConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java index b62490fc5..fb6b8837a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java @@ -21,7 +21,7 @@ import static java.nio.ByteBuffer.wrap; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -52,7 +52,7 @@ public class ShortConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java index 7fdc2b1a0..f0ed37fd2 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java @@ -19,7 +19,7 @@ import static java.lang.String.valueOf; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; import java.math.BigInteger; @@ -45,7 +45,7 @@ public class StringConversionTest extends AbstractConversionTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } @Test diff --git a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java index 71fa0dc7d..c846096be 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java @@ -17,7 +17,7 @@ package com.hotels.map; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; @@ -40,7 +40,7 @@ public class MapUtilsTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); } /** diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 87aa99fb6..7241b1d9f 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -23,7 +23,7 @@ import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.util.Lists.list; import static org.assertj.core.util.Maps.newHashMap; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigInteger; import java.util.HashMap; @@ -66,7 +66,7 @@ public class MapTransformerTest extends AbstractTransformerTest { */ @BeforeClass public void beforeClass() { - initMocks(this); + openMocks(this); initObjects(); } diff --git a/docs/site/markdown/transformer/bean/testing.md b/docs/site/markdown/transformer/bean/testing.md index aa93f4800..578e7fdcc 100644 --- a/docs/site/markdown/transformer/bean/testing.md +++ b/docs/site/markdown/transformer/bean/testing.md @@ -71,7 +71,7 @@ public class SampleClass { The test class will be: ```java import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import static org.mockito.Mockito.when; import static org.mockito.Mockito.mock; @@ -102,7 +102,7 @@ public class SampleClassTest { */ @Before public void beforeMethod() { - initMocks(this); + openMocks(this); } /** @@ -187,7 +187,7 @@ public class SampleClass { The test class will be: ```java import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import static org.mockito.Mockito.when; import static org.mockito.Mockito.mock; import static org.mockito.ArgumentMatchers.any; @@ -219,7 +219,7 @@ public class SampleClassTest { */ @Before public void beforeMethod() { - initMocks(this); + openMocks(this); } /** @@ -307,7 +307,7 @@ public class SampleClass { The test class will be: ```java import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.MockitoAnnotations.openMocks; import java.lang.reflect.Field; @@ -333,7 +333,7 @@ public class SampleClassTest { */ @Before public void beforeMethod() { - initMocks(this); + openMocks(this); // injects a real BeanUtils instance into the test class setFieldValue(underTest, "beanUtils", new BeanUtils()); } From c92c451b1ba2d209d923af17a1f7ee7e35226cdf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 4 Aug 2020 09:40:07 +0200 Subject: [PATCH 1195/1786] Minor improvements on the testing bean --- .../beans/sample/immutable/ImmutableToFoo.java | 7 ++----- .../immutable/ImmutableToFooSubClass.java | 7 ++----- .../hotels/beans/sample/mixed/MixedToFoo.java | 7 ++----- .../MixedToFooMissingAllArgsConstructor.java | 18 ++++-------------- .../mixed/MixedToFooMissingConstructor.java | 6 ++---- .../beans/sample/mutable/MutableToFoo.java | 7 ++----- .../sample/mutable/MutableToFooInvalid.java | 7 ++----- .../sample/mutable/MutableToFooSubClass.java | 7 ++----- 8 files changed, 18 insertions(+), 48 deletions(-) diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java index c93a3021a..45b2286ce 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java @@ -23,12 +23,14 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.ToString; /** * Sample immutable object. */ @AllArgsConstructor @Getter +@ToString public class ImmutableToFoo { private final String name; @NotNull @@ -39,9 +41,4 @@ public class ImmutableToFoo { private final List nestedObjectList; @NotNull private final ImmutableToSubFoo nestedObject; - - @Override - public String toString() { - return "ImmutableToFoo"; - } } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java index 4fbcfe3c0..086dbe60b 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java @@ -23,11 +23,13 @@ import javax.validation.constraints.NotNull; import lombok.Getter; +import lombok.ToString; /** * Sample immutable object extending a class. */ @Getter +@ToString public class ImmutableToFooSubClass extends ImmutableToFoo { @NotNull private final String surname; @@ -50,9 +52,4 @@ public ImmutableToFooSubClass(final String name, final BigInteger id, final List this.check = check; this.amount = amount; } - - @Override - public String toString() { - return "ImmutableToFooSubClass"; - } } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java index 15126bb70..04d055138 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java @@ -26,6 +26,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import lombok.ToString; /** * Sample mixed object. @@ -33,6 +34,7 @@ @AllArgsConstructor @Getter @Setter +@ToString public class MixedToFoo { @NotNull public BigInteger id; @@ -40,9 +42,4 @@ public class MixedToFoo { private final List list; private final List nestedObjectList; private ImmutableToSubFoo nestedObject; - - @Override - public String toString() { - return "MixedToFoo"; - } } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java index c7f4d6da3..88db639a3 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java @@ -24,13 +24,17 @@ import com.hotels.beans.sample.immutable.ImmutableToSubFoo; import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.Setter; +import lombok.ToString; /** * Sample mixed object with a constructor containing the final fields only. */ @Getter @Setter +@RequiredArgsConstructor +@ToString public class MixedToFooMissingAllArgsConstructor { @NotNull public BigInteger id; @@ -38,18 +42,4 @@ public class MixedToFooMissingAllArgsConstructor { private final List list; private final List nestedObjectList; private ImmutableToSubFoo nestedObject; - - /** - * Constructor for final fields only. - */ - public MixedToFooMissingAllArgsConstructor(final String name, final List list, final List nestedObjectList) { - this.name = name; - this.list = list; - this.nestedObjectList = nestedObjectList; - } - - @Override - public String toString() { - return "MixedToFooMissingAllArgsConstructor"; - } } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java index 18b6224d9..5f5d7f1f6 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -21,6 +21,7 @@ import javax.validation.constraints.NotNull; import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.ToString; /** @@ -28,12 +29,9 @@ */ @Getter @ToString +@RequiredArgsConstructor public class MixedToFooMissingConstructor { @NotNull public BigInteger id; private final String name; - - public MixedToFooMissingConstructor(final String name) { - this.name = name; - } } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java index 6185da239..00fdde8cf 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java @@ -21,21 +21,18 @@ import lombok.Getter; import lombok.Setter; +import lombok.ToString; /** * Sample mutable object. */ @Getter @Setter +@ToString public class MutableToFoo { private String name; private BigInteger id; private List list; private List nestedObjectList; private MutableToSubFoo nestedObject; - - @Override - public String toString() { - return "MutableToFoo"; - } } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java index 056d7fb92..17b6e18a8 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java @@ -22,6 +22,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import lombok.ToString; /** * Sample mutable object. @@ -29,15 +30,11 @@ @Getter @Setter @AllArgsConstructor +@ToString public class MutableToFooInvalid { private String name; private BigInteger id; private List list; private List nestedObjectList; private MutableToSubFoo nestedObject; - - @Override - public String toString() { - return "MutableToFooInvalid"; - } } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java index d18ec081b..5b9966b26 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java @@ -20,20 +20,17 @@ import lombok.Getter; import lombok.Setter; +import lombok.ToString; /** * Sample mutable object extending a class. */ @Getter @Setter +@ToString public class MutableToFooSubClass extends MutableToFoo { private String surname; private int phone; private boolean check; private BigDecimal amount; - - @Override - public String toString() { - return "MutableToFooSubClass"; - } } From 3cfff189213eca6f9eec82ee20c3dd3867c2baec Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 02:24:31 +0000 Subject: [PATCH 1196/1786] Bump mockito-core from 3.4.6 to 3.5.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.4.6 to 3.5.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.4.6...v3.5.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2c20face4..2476d3bbd 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.4.6 + 3.5.0 7.3.0 3.16.1 From 8f7b12925204244cd7afdec91b42bb9468cbcf13 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 17 Aug 2020 09:33:30 +0200 Subject: [PATCH 1197/1786] Modifies the test using the Mockito spy function as per the new version requirements --- .../beans/transformer/ImmutableObjectTransformationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index fe556a48f..663531854 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -158,7 +158,7 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(final String testCaseDescription, final Object sourceObject, final String expectedName, final BigInteger expectedId, final int[] expectedPhoneNumbers) { //GIVEN - TransformerImpl underTestMock = spy(TransformerImpl.class); + TransformerImpl underTestMock = spy(new TransformerImpl()); Constructor beanAllArgsConstructor = new ClassUtils().getAllArgsConstructor(ImmutableFlatToFoo.class); when(underTestMock.canBeInjectedByConstructorParams(beanAllArgsConstructor)).thenReturn(false); FieldMapping phoneNumbersMapping = new FieldMapping<>(PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME, PHONE_NUMBER_DEST_FIELD_NAME); From 9594302d52d373746bdd9b8c2db8e8ee8a6fd5d8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 19 Aug 2020 02:16:26 +0000 Subject: [PATCH 1198/1786] Bump mockito-core from 3.5.0 to 3.5.2 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.0 to 3.5.2. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.0...v3.5.2) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2476d3bbd..db044e8d7 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.0 + 3.5.2 7.3.0 3.16.1 From eae280481a9dd0887cabc4220249b88978ca4a0b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 22 Aug 2020 15:45:35 +0200 Subject: [PATCH 1199/1786] Centralizes the code to retrieve the class getter and setter methods --- .../hotels/transformer/utils/ClassUtils.java | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index b66d3eb57..e89f434a5 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -748,45 +748,43 @@ public ClassType getClassType(final Class clazz) { /** * Retrieves all the setters method for the given class. - * @param clazz the clazz containing the methods. + * @param clazz the class containing the methods. * @return all the class setter methods */ - @SuppressWarnings("unchecked") public List getSetterMethods(final Class clazz) { - notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "SetterMethods-" + clazz.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, List.class).orElseGet(() -> { - final List setterMethods = new LinkedList<>(); - if (hasSuperclass(clazz.getSuperclass())) { - setterMethods.addAll(getSetterMethods(clazz.getSuperclass())); - } - setterMethods.addAll(stream(getDeclaredMethods(clazz)) - .filter(reflectionUtils::isSetter) - .collect(toList())); - CACHE_MANAGER.cacheObject(cacheKey, setterMethods); - return setterMethods; - }); + return getMethods(clazz, "SetterMethods", reflectionUtils::isSetter); } /** - * Retrieves all the setters method for the given class. - * @param clazz the clazz containing the methods. - * @return all the class setter methods + * Retrieves all the getters method for the given class. + * @param clazz the class containing the methods. + * @return all the class getter methods */ - @SuppressWarnings("unchecked") public List getGetterMethods(final Class clazz) { + return getMethods(clazz, "GetterMethods", reflectionUtils::isGetter); + } + + /** + * Retrieves all the class methods matching to the the given filter. + * @param clazz the class containing the methods. + * @param cacheKeyPrefix the prefix to adopt for the cache key + * @param methodFilter the filter to apply to the retrieved methods + * @return the class methods matching the filter + */ + @SuppressWarnings("unchecked") + private List getMethods(final Class clazz, final String cacheKeyPrefix, final Predicate methodFilter) { notNull(clazz, CLAZZ_CANNOT_BE_NULL); - final String cacheKey = "GetterMethods-" + clazz.getName(); + final String cacheKey = cacheKeyPrefix + "-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, List.class).orElseGet(() -> { - final List setterMethods = new LinkedList<>(); + final List methods = new LinkedList<>(); if (hasSuperclass(clazz.getSuperclass())) { - setterMethods.addAll(getGetterMethods(clazz.getSuperclass())); + methods.addAll(getMethods(clazz.getSuperclass(), cacheKeyPrefix, methodFilter)); } - setterMethods.addAll(stream(getDeclaredMethods(clazz)) - .filter(reflectionUtils::isGetter) + methods.addAll(stream(getDeclaredMethods(clazz)) + .filter(methodFilter) .collect(toList())); - CACHE_MANAGER.cacheObject(cacheKey, setterMethods); - return setterMethods; + CACHE_MANAGER.cacheObject(cacheKey, methods); + return methods; }); } From 88277a9ad9c7d0c9226cdc231de74c0aba9c85e6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 22 Aug 2020 16:07:06 +0200 Subject: [PATCH 1200/1786] Removes an unnecessary dependency --- bull-map-transformer/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index a61160e60..a1ddb91ab 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -13,11 +13,6 @@ - - com.hotels.beans - bull-common - ${project.version} - com.hotels.beans bull-bean-transformer From f36e0cc53ee47f4b8090133c836a05222cf1e5a9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2020 02:20:17 +0000 Subject: [PATCH 1201/1786] Bump assertj-core from 3.16.1 to 3.17.0 Bumps [assertj-core](https://github.com/joel-costigliola/assertj-core) from 3.16.1 to 3.17.0. - [Release notes](https://github.com/joel-costigliola/assertj-core/releases) - [Commits](https://github.com/joel-costigliola/assertj-core/compare/assertj-core-3.16.1...assertj-core-3.17.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index db044e8d7..78263d751 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.5.2 7.3.0 - 3.16.1 + 3.17.0 2.0.1.Final 6.1.5.Final From 5c24167ea78b15c2f9e41d2dfaeae96a841dc352 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2020 04:17:54 +0000 Subject: [PATCH 1202/1786] Bump mockito-core from 3.5.2 to 3.5.5 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.2 to 3.5.5. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.2...v3.5.5) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 78263d751..196b3448a 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.2 + 3.5.5 7.3.0 3.17.0 From 2021d66205e48457ff6a799f2e378cdf54c2cb3e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 08:58:27 +0200 Subject: [PATCH 1203/1786] Temporary disables builds with jdk12 and 13 as travis raise an exception --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac05810b5..edcf1d702 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,8 @@ env: # Testing compatibility with newer jdk(s) jdk: - openjdk11 - - openjdk12 - - openjdk13 +# - openjdk12 +# - openjdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From 80c3809ff3c44375c46d10e53135e09331253264 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 09:00:02 +0200 Subject: [PATCH 1204/1786] Restores the travis config --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index edcf1d702..ac05810b5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,8 @@ env: # Testing compatibility with newer jdk(s) jdk: - openjdk11 -# - openjdk12 -# - openjdk13 + - openjdk12 + - openjdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From 56770093cb50420d38b970d87d94ba2e79fcf365 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 09:13:46 +0200 Subject: [PATCH 1205/1786] Temporary removes the build with jdk 12 and 13 as travis is not working --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac05810b5..c1a2acdf3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,6 @@ env: # Testing compatibility with newer jdk(s) jdk: - openjdk11 - - openjdk12 - - openjdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From 5a7f90deb1c8b60946a8549ef00eec9413664285 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 09:15:45 +0200 Subject: [PATCH 1206/1786] Temporary removes the build with jdk 12 and 13 as travis is not working --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c1a2acdf3..d81a188b2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,8 +12,7 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: - - openjdk11 +jdk: openjdk11 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From 0bd52b642cda8f31860c088582daf8962cbadfd1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 09:17:58 +0200 Subject: [PATCH 1207/1786] Restores the jdk 12 and 13 build --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d81a188b2..ac05810b5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,10 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: openjdk11 +jdk: + - openjdk11 + - openjdk12 + - openjdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From dc5930c636d7352314a37a49e9a3ca63bdfdb04b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:02:50 +0200 Subject: [PATCH 1208/1786] Removes the build with multiple jdks as travis is having issues --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac05810b5..df33086c3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,11 +11,6 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -# Testing compatibility with newer jdk(s) -jdk: - - openjdk11 - - openjdk12 - - openjdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From 3dfb529206a25a15ebf4fff262e670d9c51c4d35 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:04:56 +0200 Subject: [PATCH 1209/1786] Adds a jdk --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index df33086c3..0cfad2206 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: java cache: directories: - $HOME/.m2 +jdk: openjdk11 env: global: # HCOM OSS Sonatype jira info From 3546651ffc73460f5bff1e081dcc301a679ff855 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:05:29 +0200 Subject: [PATCH 1210/1786] Adds a jdk --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0cfad2206..46e85289b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,8 @@ language: java cache: directories: - $HOME/.m2 -jdk: openjdk11 +jdk: + - openjdk11 env: global: # HCOM OSS Sonatype jira info From 0bdaef2873df9886176dfd0e95e5baae7ac048a5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:09:19 +0200 Subject: [PATCH 1211/1786] Adds a jdk --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 46e85289b..82caf446e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,6 @@ language: java cache: directories: - $HOME/.m2 -jdk: - - openjdk11 env: global: # HCOM OSS Sonatype jira info @@ -13,6 +11,11 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= +# Testing compatibility with newer jdk(s) +jdk: + - openjdk11 + - oraclejdk12 + - oraclejdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From 8bb8d28ba2b773134c0fe4e4d24da2dc0d6c0de4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:13:08 +0200 Subject: [PATCH 1212/1786] Adds a jdk --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 82caf446e..ac05810b5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,8 @@ env: # Testing compatibility with newer jdk(s) jdk: - openjdk11 - - oraclejdk12 - - oraclejdk13 + - openjdk12 + - openjdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From b2cb69ea9505188a947ece28850feedd1a4eb003 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:15:15 +0200 Subject: [PATCH 1213/1786] Adds a jdk --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ac05810b5..ed9e5b656 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,6 @@ env: # Testing compatibility with newer jdk(s) jdk: - openjdk11 - - openjdk12 - openjdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip From 5fdc5bc27cb11d3b13d7528cd6e3527a94b6bf4e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:15:49 +0200 Subject: [PATCH 1214/1786] Adds a jdk --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ed9e5b656..c1a2acdf3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,6 @@ env: # Testing compatibility with newer jdk(s) jdk: - openjdk11 - - openjdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From 5b07b9c7766106c3d97f66866c2712fdfff85356 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:17:46 +0200 Subject: [PATCH 1215/1786] Adds a jdk --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c1a2acdf3..bd526e515 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,8 +12,7 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: - - openjdk11 +jdk: openjdk11 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: @@ -27,7 +26,6 @@ jobs: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" - jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -44,7 +42,6 @@ jobs: ### JDK11 release - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" - jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: From 6bbd88fddd8f62593d5398473ded7158c3681063 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:24:03 +0200 Subject: [PATCH 1216/1786] Switch jdk --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bd526e515..d23c13116 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: openjdk11 +jdk: oraclejdk11 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: @@ -26,6 +26,7 @@ jobs: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" + jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: @@ -42,6 +43,7 @@ jobs: ### JDK11 release - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" + jdk: openjdk11 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: From f15f5018c2b82ed651f9f07d9aeb8ee73fe9f1ee Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:25:08 +0200 Subject: [PATCH 1217/1786] Switch jdk --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d23c13116..ae1786fdd 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,9 +12,8 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: oraclejdk11 +jdk: openjdk11 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode -install: skip jobs: include: ### JDK8 build From bd03c1ba3e3390d6ab8fec221255f06c26aae053 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:30:29 +0200 Subject: [PATCH 1218/1786] Removes build with jdk12 --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ae1786fdd..ed9e5b656 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,8 +12,11 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: openjdk11 +jdk: + - openjdk11 + - openjdk13 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode +install: skip jobs: include: ### JDK8 build From cc374556448051ae6551c5d4b92b2dafaca0258c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:41:34 +0200 Subject: [PATCH 1219/1786] Adds the build with jdk14 --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac05810b5..03167e7d7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,7 @@ env: # Testing compatibility with newer jdk(s) jdk: - openjdk11 - - openjdk12 - - openjdk13 + - openjdk14 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From 4f792c6fadd28c6de03e294b7ba4c21e85dfbf7e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:43:42 +0200 Subject: [PATCH 1220/1786] Adds the build with jdk14 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ed9e5b656..6ba39cfe3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ env: # Testing compatibility with newer jdk(s) jdk: - openjdk11 - - openjdk13 + - oraclejdk14 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From fcad1506dec36fc6eb398cf4f85ce94ed465abec Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:48:32 +0200 Subject: [PATCH 1221/1786] Removes the multiple jdk build due to the travis issue --- .travis.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6ba39cfe3..73d5f0e31 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,13 +12,16 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: - - openjdk11 - - oraclejdk14 -script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode +jdk: openjdk11 install: skip jobs: include: + ### Project build + - stage: "JDK11 Build" + name: "JDK11 Build and Test" + jdk: openjdk11 + script: + - travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" From 393309dff5ea7fb1037d5ec1ae73c93da330cf4f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:52:38 +0200 Subject: [PATCH 1222/1786] Restores the multiple jdk build waiting gor the travis issue fix --- .travis.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 73d5f0e31..ac05810b5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,16 +12,14 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: openjdk11 +jdk: + - openjdk11 + - openjdk12 + - openjdk13 +script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: include: - ### Project build - - stage: "JDK11 Build" - name: "JDK11 Build and Test" - jdk: openjdk11 - script: - - travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" From f5e23151081f28176dfc2dc1bf671ea6ff1325ba Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:54:24 +0200 Subject: [PATCH 1223/1786] Removes travis multiple jdk build --- .travis.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac05810b5..73d5f0e31 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,14 +12,16 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: - - openjdk11 - - openjdk12 - - openjdk13 -script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode +jdk: openjdk11 install: skip jobs: include: + ### Project build + - stage: "JDK11 Build" + name: "JDK11 Build and Test" + jdk: openjdk11 + script: + - travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" From 401669f0be84965a21c7251fa099a46cd76d53ad Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 24 Aug 2020 11:56:47 +0200 Subject: [PATCH 1224/1786] Restores travis multiple jdks build --- .travis.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 73d5f0e31..ac05810b5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,16 +12,14 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= # Testing compatibility with newer jdk(s) -jdk: openjdk11 +jdk: + - openjdk11 + - openjdk12 + - openjdk13 +script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: include: - ### Project build - - stage: "JDK11 Build" - name: "JDK11 Build and Test" - jdk: openjdk11 - script: - - travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" From be00f33c1389e85b454507b908e8bf78468bea56 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2020 02:16:02 +0000 Subject: [PATCH 1225/1786] Bump mockito-core from 3.5.5 to 3.5.6 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.5 to 3.5.6. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.5...v3.5.6) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 196b3448a..90e5fee22 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.5 + 3.5.6 7.3.0 3.17.0 From 9c4f48025ae379eab924895e06212c920297f30f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2020 02:16:33 +0000 Subject: [PATCH 1226/1786] Bump mockito-core from 3.5.6 to 3.5.7 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.6 to 3.5.7. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.6...v3.5.7) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 90e5fee22..3362c5ab3 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.6 + 3.5.7 7.3.0 3.17.0 From 255e3ea39f0097df4111376b2515bd1c48d80e00 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 30 Aug 2020 11:19:34 +0200 Subject: [PATCH 1227/1786] Minor improvements --- .../java/com/hotels/beans/populator/ArrayPopulatorTest.java | 4 ++-- .../hotels/beans/sample/immutable/ImmutableToFooSimple.java | 2 +- pom.xml | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 4d8512124..3584f8d80 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -80,9 +80,9 @@ public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, // THEN if (genericFieldType == Character.class) { - assertThat((char[]) actual).isEqualTo((char[]) array); + assertThat((char[]) actual).isEqualTo(array); } else if (genericFieldType == Integer.class) { - assertThat((int[]) actual).isEqualTo((int[]) array); + assertThat((int[]) actual).isEqualTo(array); } else if (genericFieldType == Object.class) { assertThat((Object[]) actual).isEqualTo(array); } else if (genericFieldType == MixedToFooStaticField.class) { diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java index d4decff9d..abd518a5b 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java @@ -33,5 +33,5 @@ public class ImmutableToFooSimple { private final String name; private final BigInteger id; - private boolean active; + private final boolean active; } diff --git a/pom.xml b/pom.xml index 3362c5ab3..8d9b498ef 100644 --- a/pom.xml +++ b/pom.xml @@ -79,6 +79,7 @@ github 3.9.1 + 1.6 3.1.1 false true From be53fc1fd1bbddfb9f41b2f45d30b49fb655823e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2020 02:22:11 +0000 Subject: [PATCH 1228/1786] Bump assertj-core from 3.17.0 to 3.17.1 Bumps [assertj-core](https://github.com/joel-costigliola/assertj-core) from 3.17.0 to 3.17.1. - [Release notes](https://github.com/joel-costigliola/assertj-core/releases) - [Commits](https://github.com/joel-costigliola/assertj-core/compare/assertj-core-3.17.0...assertj-core-3.17.1) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8d9b498ef..b262037b2 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.5.7 7.3.0 - 3.17.0 + 3.17.1 2.0.1.Final 6.1.5.Final From f8a2415f740957450d3026c7f90791ea7e5bb941 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 2 Sep 2020 02:16:52 +0000 Subject: [PATCH 1229/1786] Bump mockito-core from 3.5.7 to 3.5.9 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.7 to 3.5.9. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.7...v3.5.9) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b262037b2..5d80c7516 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.7 + 3.5.9 7.3.0 3.17.1 From cd39a18d73656744b646dcb3264606e618c41528 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 7 Sep 2020 02:19:14 +0000 Subject: [PATCH 1230/1786] Bump assertj-core from 3.17.1 to 3.17.2 Bumps [assertj-core](https://github.com/joel-costigliola/assertj-core) from 3.17.1 to 3.17.2. - [Release notes](https://github.com/joel-costigliola/assertj-core/releases) - [Commits](https://github.com/joel-costigliola/assertj-core/compare/assertj-core-3.17.1...assertj-core-3.17.2) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5d80c7516..e64fedf3b 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.5.9 7.3.0 - 3.17.1 + 3.17.2 2.0.1.Final 6.1.5.Final From 0a01ab68786adc7693057f8fdfa42079b2d5c43c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 7 Sep 2020 04:25:29 +0000 Subject: [PATCH 1231/1786] Bump mockito-core from 3.5.9 to 3.5.10 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.9 to 3.5.10. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.9...v3.5.10) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e64fedf3b..95311ba91 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.9 + 3.5.10 7.3.0 3.17.2 From 99b1aefd73df6f54f1da7fd9adeb2e68a71252ce Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2020 02:14:53 +0000 Subject: [PATCH 1232/1786] Bump jacoco-maven-plugin from 0.8.5 to 0.8.6 Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.5 to 0.8.6. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.5...v0.8.6) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 95311ba91..564f580d5 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 3.0.0 2.2.6 - 0.8.5 + 0.8.6 1.0 0.98 1.0 From fc0d79333c9741c9931ca38a41623118e0ad1414 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 16 Sep 2020 16:08:33 +0200 Subject: [PATCH 1233/1786] Trigger notification From 9c243d3c8b61ff61bc942b5366b6e676f19f230c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 16 Sep 2020 17:16:23 +0200 Subject: [PATCH 1234/1786] Trigger notification From 8f5a6bf571323a0c3dba824e343442aeabbc954f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 17 Sep 2020 10:13:00 +0200 Subject: [PATCH 1235/1786] Updates the Travis badge tp refer to Travis-ci.com --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bfc75c8e1..c64e5f534 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central&color=blue)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg?color=blue)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) -[![Build Status](https://travis-ci.org/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.org/HotelsDotCom/bull) +[![Build Status](https://travis-ci.com/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.com/HotelsDotCom/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) From 7b89952d7273b0bca528163d243f9a092c34115b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 18 Sep 2020 02:18:10 +0000 Subject: [PATCH 1236/1786] Bump mockito-core from 3.5.10 to 3.5.11 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.10 to 3.5.11. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.10...v3.5.11) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 564f580d5..9629a3490 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.10 + 3.5.11 7.3.0 3.17.2 From 84cd96e70a71643399749a9920d87ab2cf761c83 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 19 Sep 2020 14:14:26 +0200 Subject: [PATCH 1237/1786] Code owner config update --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 95dcdc0ad..c45886f01 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -5,4 +5,4 @@ * @HotelsDotCom/bull-committers # Only some members of Customer Insights can alter the CODEOWNERS file -.github/CODEOWNERS @HotelsDotCom/bull-admin \ No newline at end of file +.github/CODEOWNERS @fborriello @HotelsDotCom/bull-admin \ No newline at end of file From 1f703ac26e9fa378387e26a5e8f49eeffd797691 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 25 Sep 2020 02:16:43 +0000 Subject: [PATCH 1238/1786] Bump mockito-core from 3.5.11 to 3.5.13 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.11 to 3.5.13. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.11...v3.5.13) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9629a3490..415b30fec 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.11 + 3.5.13 7.3.0 3.17.2 From b8ea8999e1eea246387ddce7a6064accd099a094 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2020 02:19:02 +0000 Subject: [PATCH 1239/1786] Bump hibernate-validator from 6.1.5.Final to 6.1.6.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.1.5.Final to 6.1.6.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.1.6.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.1.5.Final...6.1.6.Final) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 415b30fec..fad942152 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 3.17.2 2.0.1.Final - 6.1.5.Final + 6.1.6.Final 1.7.30 3.0.0 2.2.6 From 4937f00d9caa67e4fd642a8fe5087517d9a38815 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 5 Oct 2020 11:15:30 +0200 Subject: [PATCH 1240/1786] Codeowners update --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c45886f01..a542d1ebc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,7 +2,7 @@ # These owners will be the default owners for everything on this repo. # https://github.com/HotelsDotCom/bull -* @HotelsDotCom/bull-committers +* @HotelsDotCom/bull-committers borriello.fabio@gmail.com # Only some members of Customer Insights can alter the CODEOWNERS file -.github/CODEOWNERS @fborriello @HotelsDotCom/bull-admin \ No newline at end of file +.github/CODEOWNERS borriello.fabio@gmail.com @HotelsDotCom/bull-admin \ No newline at end of file From 18af9f4be18b5e04457400024b6dd27f6a0cf458 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 7 Oct 2020 08:43:06 +0200 Subject: [PATCH 1241/1786] Updates the changelog with the new release version --- CHANGELOG-JDK8.md | 4 ++++ CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index c08644ae2..043772e3e 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.7.3-jdk8] 2020.10.07 +#### Changed +* Provides new utilities methods + ### [1.7.2-jdk8] 2020.06.09 #### Changed * Removes the deprecated method: `setDefaultValueSetEnabled` diff --git a/CHANGELOG.md b/CHANGELOG.md index 01225ff03..66d58925e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.7.4] 2020.10.07 +#### Changed +* Provides new utilities methods + ### [1.7.3] 2020.06.09 #### Changed * Removes the deprecated method: `setDefaultValueSetEnabled` From 21cd2097169d5e5f4072a6e63c7152de531e24d3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 7 Oct 2020 08:47:26 +0200 Subject: [PATCH 1242/1786] [maven-release-plugin] prepare release 1.7.4 --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 9424c7691..8274a63c5 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.4-SNAPSHOT + 1.7.4 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index bec8c8f56..34beabf6a 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.4-SNAPSHOT + 1.7.4 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 1cb027a46..1e9b6368f 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.4-SNAPSHOT + 1.7.4 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index a1ddb91ab..427e714e9 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.4-SNAPSHOT + 1.7.4 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index e8fbbc799..2671d2876 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.4-SNAPSHOT + 1.7.4 diff --git a/pom.xml b/pom.xml index fad942152..4b7d2f308 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.4-SNAPSHOT + 1.7.4 pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.7.4 From 80ead47b7293d94f26faa6ba4fd584bf48477387 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 7 Oct 2020 08:47:34 +0200 Subject: [PATCH 1243/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 8274a63c5..1794a6d67 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.4 + 1.7.5-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 34beabf6a..86d2df3e1 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.4 + 1.7.5-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 1e9b6368f..b673dad5c 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.4 + 1.7.5-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 427e714e9..ec7c9e569 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.4 + 1.7.5-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2671d2876..c4d6b74e6 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.4 + 1.7.5-SNAPSHOT diff --git a/pom.xml b/pom.xml index 4b7d2f308..6901cada3 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.4 + 1.7.5-SNAPSHOT pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.4 + HEAD From 09bdef6fab3dd6bb3fd5c1e1439991dfd34b9a6d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2020 02:16:07 +0000 Subject: [PATCH 1244/1786] Bump lombok from 1.18.12 to 1.18.14 Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.18.12 to 1.18.14. - [Release notes](https://github.com/rzwitserloot/lombok/releases) - [Changelog](https://github.com/rzwitserloot/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/rzwitserloot/lombok/compare/v1.18.12...v1.18.14) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6901cada3..84d18cf25 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 11 ${jdk.version} ${jdk.version} - 1.18.12 + 1.18.14 3.11 1.3.0 From 56d808c9c7dcc5afd00614317d044dd94b87435a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2020 02:16:31 +0000 Subject: [PATCH 1245/1786] Bump lombok from 1.18.14 to 1.18.16 Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.18.14 to 1.18.16. - [Release notes](https://github.com/rzwitserloot/lombok/releases) - [Changelog](https://github.com/rzwitserloot/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/rzwitserloot/lombok/compare/v1.18.14...v1.18.16) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 84d18cf25..6451cf34f 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 11 ${jdk.version} ${jdk.version} - 1.18.14 + 1.18.16 3.11 1.3.0 From f1201f4e5eb045fb8ff56e62c2a795b7e9325372 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2020 02:16:20 +0000 Subject: [PATCH 1246/1786] Bump mockito-core from 3.5.13 to 3.5.15 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.13 to 3.5.15. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.13...v3.5.15) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6451cf34f..6e3bad705 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.13 + 3.5.15 7.3.0 3.17.2 From 5efb1f4b91bc8e51d4a3b3df7f17a4151a0c53fd Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 26 Oct 2020 02:16:11 +0000 Subject: [PATCH 1247/1786] Bump hotels-oss-parent from 5.0.0 to 6.1.0 Bumps [hotels-oss-parent](https://github.com/HotelsDotCom/hotels-oss-parent) from 5.0.0 to 6.1.0. - [Release notes](https://github.com/HotelsDotCom/hotels-oss-parent/releases) - [Changelog](https://github.com/HotelsDotCom/hotels-oss-parent/blob/master/CHANGELOG.md) - [Commits](https://github.com/HotelsDotCom/hotels-oss-parent/compare/hotels-oss-parent-5.0.0...hotels-oss-parent-6.1.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6e3bad705..32994aeee 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ com.hotels hotels-oss-parent - 5.0.0 + 6.1.0 From 260f87aa828e1e94f486b0c63eaaf2e99bb3059a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 26 Oct 2020 06:38:31 +0000 Subject: [PATCH 1248/1786] Bump assertj-core from 3.17.2 to 3.18.0 Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.17.2 to 3.18.0. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.17.2...assertj-core-3.18.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 32994aeee..9a2c2f615 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.5.15 7.3.0 - 3.17.2 + 3.18.0 2.0.1.Final 6.1.6.Final From 7c16d57d03c0007452d7ee47e38b66d77c19b7ac Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 28 Oct 2020 02:13:54 +0000 Subject: [PATCH 1249/1786] Bump mockito-core from 3.5.15 to 3.6.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.5.15 to 3.6.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.5.15...v3.6.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9a2c2f615..e0e2c6da7 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.5.15 + 3.6.0 7.3.0 3.18.0 From a82cdab228fb646665135d7fd07c8f29cd54a235 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 31 Oct 2020 07:29:57 +0100 Subject: [PATCH 1250/1786] Fixes grammar errors onto the README.md file --- README.md | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index c64e5f534..87a19c8e7 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ ## Bean Utils Light Library -BULL is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. -It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. +BULL is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable, and incredibly fast. +It's the only library able to transform Mutable, Immutable, and Mixed bean without any custom configuration. ## Start using @@ -44,11 +44,11 @@ All BULL modules are available on Maven Central: **The project provides two different builds**, one compatible with `jdk 8` (or above) and one with `jdk 11` or above. -In case you need to integrate it in a `jdk 8` (or above project) please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) file or to [CHANGELOG](CHANGELOG.md) otherwise. +In case you need to integrate it in a `jdk 8` (or above project) please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) file or [CHANGELOG](CHANGELOG.md) otherwise. * #### Suggestions -Some jdk versions removes the Java Bean constructor's argument names from the compiled code and this may cause problems to the library. +Some jdk versions remove the Java Bean constructor's argument names from the compiled code and this may cause problems to the library. On top of that, it's suggested to configure the `maven-compiler-plugin`, inside your project, as follow: ```xml @@ -110,7 +110,7 @@ mvnw.cmd clean install -P relaxed * support copy of beans with different field's name. * support lambda function field transformation. * support copy of java bean built through Builder. -* easy usage, declarative way to define the property mapping (in case of different names) or simply adding the Lombok annotations. +* easy usage, declarative way to define the property mapping (in case of different names), or simply adding the Lombok annotations. * allows setting the default value for all objects not existing in the source object. * allows skipping transformation for a given set of fields. * supports the retrieval of the value from getters if a field does not exist in the source object. @@ -182,7 +182,7 @@ And one line code as: beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class); ``` -### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: +### Mapping destination fields with correspondent fields contained inside one of the nested objects in the source object: Assuming that the object `FromSubBean` is declared as follow: ```java @@ -326,7 +326,7 @@ ToBean toBean = beanUtils.getTransformer() .setDefaultValueForMissingPrimitiveField(false).transform(fromBean, ToBean.class); ``` -in this case the field `id` after the transformation will be `null` +in this case, the field `id` after the transformation will be `null` ### Applying a transformation function in case of missing fields in the source object: @@ -353,7 +353,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on a field contained in a nested object: -This example shows of a lambda transformation function can be applied on a nested object field. +This example shows off a lambda transformation function that can be applied to a nested object field. Given: @@ -405,7 +405,7 @@ public class ToSubBean { // all args constructor } // getters... ``` -Assuming that the value `x` should be mapped into field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as +Assuming that the value `x` should be mapped into the field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as follow: ```java ToBean toBean = beanUtils.getTransformer() @@ -414,7 +414,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on all fields matching with the given one: -This example shows how a lambda transformation function can be applied on all fields matching with the given one independently from their position. +This example shows how a lambda transformation function can be applied to all fields matching with the given one independently from their position. Given: @@ -538,7 +538,7 @@ beanUtils.getTransformer() where `nestedObject` is the name of the field in the destination object. -This feature allows to **transform an object keeping the data from different sources**. +This feature allows us to **transform an object keeping the data from different sources**. To better explain this function let's assume that the `ToBean` (defined above) should be transformed as follow: - `name` field value has been taken from the `FromBean` object @@ -592,8 +592,8 @@ public class FromBean { public class ToBean ``` as, by default the primitive type conversion is disabled, to get the above object converted we should have -implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically from enabling the -functionality described above. +implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically by enabling the +the functionality described above. ```java Transformer transformer = beanUtils.getTransformer() @@ -603,7 +603,7 @@ ToBean toBean = transformer.transform(fromBean, ToBean.class); ``` **IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function defined on a specific field. -This means that the once the `FieldTransformer` function will be executed the field value has already been transformed. +This means that once the `FieldTransformer` function will be executed the field value has already been transformed. ## Builder supported patterns @@ -709,7 +709,7 @@ ToBean toBean = new BeanTransformer() More sample beans can be found in the test package: `com.hotels.beans.sample` -## Third party library comparison +## Third-party library comparison Following a comparison between the BULL functionalities and the following Third-Party libraries: @@ -737,12 +737,12 @@ Following a comparison between the BULL functionalities and the following Third- | Annotation field validation | X | - | X | - | _[*] Immutable types are not supported by Dozer. When a type doesn't have a no-arg constructor and all fields are final, Dozer can't perform the mapping. - Workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ + A workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ _[+] Requires a custom configuration_ ## Performance -Let's have a look to the performance library performance. The test has been executed on the following objects: +Let's have a look at the performance library performance. The test has been executed on the following objects: * Mutable objects * Mutable objects extending another mutable object @@ -873,9 +873,9 @@ Converter converter = new BeanUtils().getPrimitiveTypeConverter(); int indexNumber = converter.convertValue(indexNumber, int.class); ``` -### Obtain a conversion function that convert from char to byte: +### Obtain a conversion function that converts from char to byte: -It's possible to obtain a type conversion function, reusable several time in different places. +It's possible to obtain a type conversion function, reusable several times in different places. Assuming that the required conversion is from `char` to `byte ```java @@ -891,15 +891,15 @@ byte converted = conversionFunction.map(processor -> processor.apply(c)).orElse( ``` * in case the conversion is not needed as the primitive type and the destination type are the same it will return an empty `Optional` -* in case the conversion function is unavailable or no not possible the method throws a : `TypeConversionException` +* in case the conversion function is unavailable or no not possible the method throws a: `TypeConversionException` ## `Map` transformation samples -Samples on how to transform a `Map` and all others function applicable on it can be viewed [here](https://hotelsdotcom.github.io/bull/transformer/mapTransformer.html) +Samples on how to transform a `Map` and all others function applicable to it can be viewed [here](https://hotelsdotcom.github.io/bull/transformer/mapTransformer.html) ## Documentation -A detailed project documentation is available [here](https://hotelsdotcom.github.io/bull), including some samples for [testing the library](https://hotelsdotcom.github.io/bull/transformer/testing.html) inside your project. +Detailed project documentation is available [here](https://hotelsdotcom.github.io/bull), including some samples for [testing the library](https://hotelsdotcom.github.io/bull/transformer/testing.html) inside your project. An article that explains how it works, with suggestion and examples is available on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) @@ -908,7 +908,7 @@ An article that explains how it works, with suggestion and examples is available Created by: [Fabio Borriello](https://github.com/fborriello) with the contribution of: [Patrizio Munzi](https://github.com/patriziomunzi), [Andrea Marsiglia](https://github.com/AndreaMars94), [Giorgio Delle Grottaglie](https://github.com/geordie--) & the Hotels.com's Checkout team in Rome. -The application's logo has been designed by: Rob Light. +The application's logo has been designed by Rob Light. ## Related articles @@ -917,7 +917,7 @@ The application's logo has been designed by: Rob Light. ## Release -All the instructions for releasing a new version are available at: [RELEASES.md](RELEASE.md) +All the instructions for releasing a new version are available at [RELEASES.md](RELEASE.md) ## Badge your project @@ -933,7 +933,7 @@ Add the following snippet in your Markdown file: [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) -For any question, proposal or help, please refer to the slack channel: [#bull](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk). +For any question, proposal, or help, please refer to the slack channel: [#bull](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk). ## Legal From 073ef7383e87f41172245abdaa615c9ad888396f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 31 Oct 2020 11:02:43 +0100 Subject: [PATCH 1251/1786] Fixes grammar errors onto all documentation files --- CONTRIBUTING.md | 13 ++++++------ PULL_REQUEST_TEMPLATE.md | 2 +- RELEASE.md | 18 ++++++++--------- code-of-conduct.md | 10 +++++----- docs/site/markdown/converter/samples.md | 8 ++++---- docs/site/markdown/index.md | 6 +++--- .../site/markdown/transformer/bean/testing.md | 20 +++++++++---------- .../bean/thirdPartyLibComparison.md | 4 ++-- .../markdown/transformer/beanTransformer.md | 4 ++-- 9 files changed, 42 insertions(+), 43 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c4a41c373..ed2d5c7c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,6 @@ Contributing [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/dwyl/esta/issues) ============ -If you want to contribute to the project and make it better, your help is very welcome. Contributing is also a great way to learn more about social coding on Github, new -technologies and their ecosystems and how to make constructive, helpful bug reports, feature requests and the noblest of all contributions: a good, clean pull request. +If you want to contribute to the project and make it better, your help is very welcome. Contributing is also a great way to learn more about social coding on Github, new technologies and their ecosystems, and how to make constructive, helpful bug reports, feature requests, and the noblest of all contributions: a good, clean pull request. ### How to make a clean pull request @@ -9,7 +8,7 @@ technologies and their ecosystems and how to make constructive, helpful bug repo - Clone the fork on your local machine. Your remote repo on Github is called `origin`. - Add the original repository as a remote called `upstream`. - If you created your fork a while ago be sure to pull upstream changes into your local repository. -- Create a new branch to work on! Branch from `develop` if it exists, else from `master`. +- Create a new branch to work on! A branch from `develop` if it exists, else from `master`. - **The branch name should follow the best practices naming convention:** 1. Use grouping tokens (words) at the beginning of your branch names. * `feature`: Feature I'm adding or expanding @@ -19,7 +18,7 @@ technologies and their ecosystems and how to make constructive, helpful bug repo 3. Use slashes to separate parts of your branch names. 4. Do not use bare numbers as leading parts. 5. Avoid long descriptive names for long-lived branches. -- Implement/fix your feature, comment your code. +- Implement/fix your feature, comment on your code. - Follow the code style of the project, including indentation. - If the project has tests run them! - Write or adapt tests as needed. @@ -37,6 +36,6 @@ did to the code. - The new code should be tested enough to meet the expected coverage - The default libraries for testing implementations are: -    1. AssertJ for the assertion -    2. Mockito for the object mocking -    3. Testng for testing annotations and data provider \ No newline at end of file + 1. AssertJ for the assertion + 2. Mockito for the object mocking + 3. Testng for testing annotations and data provider diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 19d669c52..e78e3bfd0 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -18,7 +18,7 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] The branch follows the best practices naming convention: - Use grouping tokens (words) at the beginning of your branch names. * `feature`: Feature I'm adding or expanding - * `bug`: Bug fix or experiment + * `bug`: Bugfix or experiment * `wip`: Work in progress; stuff I know won't be finished soon - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code diff --git a/RELEASE.md b/RELEASE.md index b11dac62a..8531d5353 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -2,7 +2,7 @@ ## Explanation of the process sequence -Assumption that the current state of *master* will constitute the release... +The assumption that the current state of *master* will constitute the release... #### 1. Pre-release checks @@ -30,7 +30,7 @@ e.g. if the new release version would be `X.Y.Z` then the `jdk8` correspondent o #### Update the change log -The changes, that are going to be released, needs to be specified in the `CHANGELOG` file. +The changes, that are going to be released, need to be specified in the `CHANGELOG` file. Ensure it mentions any noteworthy changes since the previous release. Make the following check before performing a release: @@ -44,9 +44,9 @@ the same changes must be reported in [CHANGELOG-JDK8.md](CHANGELOG-JDK8.md) #### 3. Prepare the jdk8 release -All the changes implemented needs to be reported to a `jdk8` compatible version. +All the changes implemented need to be reported to a `jdk8` compatible version. -The BULL code for the `jdk8` is slightly different so all the changes needs to be reported on the other version starting +The BULL code for the `jdk8` is slightly different so all the changes need to be reported on the other version starting from it's latest release tag. The first thing to do is to create a branch (that would have the same name as the `jdk11` one plus the suffix: `-jdk8`) @@ -66,7 +66,7 @@ $ git checkout -b feature/my-new-feature-jdk8 1.7.0-jdk8 **IMPORTANT:** In the new branch, apply only the changes introduced comparing the code with the `jdk11` branch. When completed, commit your code and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. -## Example of release process sequence +## Example of a release process sequence The following examples assume that your local repository is: @@ -96,9 +96,9 @@ nothing to commit, working directory clean Assuming that: -* the latest release for `jdk8` was: `A.B.C-jdk8` +* The latest release for `jdk8` was: `A.B.C-jdk8` * your new feature branch is: `feature/my-new-feature` -* the new release version is: `X.Y.Z-jdk8` +* The new release version is: `X.Y.Z-jdk8` the release branch would be: `release/my-new-feature-jdk8` @@ -154,9 +154,9 @@ nothing to commit, working directory clean Assuming that: -* the latest release for `jdk11` was: `A.B.C` +* The latest release for `jdk11` was: `A.B.C` * your new feature branch is: `feature/my-new-feature` -* the new release version is: `X.Y.Z` +* The new release version is: `X.Y.Z` the release branch would be: `release/my-new-feature` diff --git a/code-of-conduct.md b/code-of-conduct.md index cc089b491..f29be49b6 100644 --- a/code-of-conduct.md +++ b/code-of-conduct.md @@ -3,7 +3,7 @@ ## Our Pledge In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and +contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and @@ -48,17 +48,17 @@ threatening, offensive, or harmful. This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed +address, posting via an official social media account or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be +Instances of abusive, harassing, or otherwise, unacceptable behavior may be reported by contacting a member of the project team: [Hcom Tech Checkout Payments](https://github.com/orgs/HotelsDotCom/teams/bull-committers/members). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. +obligated to maintain confidentiality concerning the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good @@ -70,4 +70,4 @@ members of the project's leadership. This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html -[homepage]: https://www.contributor-covenant.org \ No newline at end of file +[homepage]: https://www.contributor-covenant.org diff --git a/docs/site/markdown/converter/samples.md b/docs/site/markdown/converter/samples.md index a30503298..3f30934cf 100644 --- a/docs/site/markdown/converter/samples.md +++ b/docs/site/markdown/converter/samples.md @@ -19,9 +19,9 @@ Converter converter = new BeanUtils().getPrimitiveTypeConverter(); int indexNumber = converter.convertValue(indexNumber, int.class); ``` -### Obtain a conversion function that convert from char to byte: +### Obtain a conversion function that converts from char to byte: -It's possible to obtain a type conversion function, reusable several time in different places. +It's possible to obtain a type conversion function, reusable several times in different places. Assuming that the required conversion is from `char` to `byte ```java @@ -37,7 +37,7 @@ byte converted = conversionFunction.map(processor -> processor.apply(c)).orElse( ``` * in case the conversion is not needed as the primitive type and the destination type are the same it will return an empty `Optional` -* in case the conversion function is unavailable or no not possible the method throws a : `TypeConversionException` +* in case the conversion function is unavailable or no not possible the method throws a: `TypeConversionException` **IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function defined on a specific field. -This means that the once the `FieldTransformer` function will be executed the field value has already been transformed. \ No newline at end of file +This means that once the `FieldTransformer` function will be executed the field value has already been transformed. diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 5190a0876..6792ef08d 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -10,8 +10,8 @@ This BeanUtils library is a utility library for managing Bean objects. The libra #### Bean Transformer: -is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. -It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. +is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable, and incredibly fast. +It's the only library able to transform Mutable, Immutable, and Mixed bean without any custom configuration. ##### Features: * support copy of immutable beans. @@ -29,7 +29,7 @@ It's the only library able to transform Mutable, Immutable and Mixed bean withou * support copy of beans with different field's name. * support lambda function field transformation. * support copy of java bean built through Builder. -* easy usage, declarative way to define the property mapping (in case of different names) or simply adding the Lombok annotations. +* easy usage, declarative way to define the property mapping (in case of different names), or simply adding the Lombok annotations. * allows setting the default value for all objects not existing in the source object. * allows skipping transformation for a given set of fields. * supports the retrieval of the value from getters if a field does not exist in the source object. diff --git a/docs/site/markdown/transformer/bean/testing.md b/docs/site/markdown/transformer/bean/testing.md index 578e7fdcc..d50e35bd2 100644 --- a/docs/site/markdown/transformer/bean/testing.md +++ b/docs/site/markdown/transformer/bean/testing.md @@ -4,29 +4,29 @@ # Overview -Software testing plays a fundamental role in the software development because we can evaluate one or more properties of interest. In general, these properties indicate the -extent to which the component or system under test: +Software testing plays a fundamental role in software development because we can evaluate one or more properties of interest. In general, these properties indicate the +the extent to which the component or system under test: -* meets the requirements that guided its design and development, +* Meets the requirements that guided its design and development, * responds correctly to all kinds of inputs, * performs its functions within an acceptable time, * it is sufficiently usable, -* can be installed and run in its intended environments -* achieves the general result its stakeholders desire. +* Can be installed and run in its intended environments +* achieves the general result of its stakeholder's desire. This page will show how to test BULL into a simple project. All the examples utilize [JUnit](https://github.com/junit-team), [Mockito](https://site.mockito.org/) and [AssertJ](https://assertj.github.io/doc/) -The Java Bean transformation function can be tested in two different ways that depends on the following scenarios: +The Java Bean transformation function can be tested in two different ways that depend on the following scenarios: 1. The destination object does not require a special configuration to get transformed -2. The destination object requires a special configuration, but you are confident that the configuration is working fine as it doesn't includes any special action +2. The destination object requires a special configuration, but you are confident that the configuration is working fine as it doesn't include any special action 3. The destination object requires a special configuration that needs to be tested as we are not confident that it would work -For both scenarios: 1 and 2 we can use a mocked version the `BeanUtils` object. +For both scenarios: 1 and 2 we can use a mocked version of the `BeanUtils` object. ### Before start -As BULL contains final methods that needs to be mocked and, as Mockito requires a special configuration in order to mock final classes/methods, an extension needs +As BULL contains final methods that need to be mocked and, as Mockito requires a special configuration in order to mock final classes/methods, an extension needs to be added to the test resource folder. This file is available [here](https://github.com/HotelsDotCom/bull/tree/master/src/test/resources/mockito-extensions). All the examples will be based on the following source object and destination object: @@ -156,7 +156,7 @@ public class SampleClassTest { ### Second scenario: -#####The destination object requires a special configuration, but you are confident that the configuration is working fine as it doesn't includes any particular instruction. +#####The destination object requires a special configuration, but you are confident that the configuration is working fine as it doesn't include any particular instruction. Given the following service class: ```java diff --git a/docs/site/markdown/transformer/bean/thirdPartyLibComparison.md b/docs/site/markdown/transformer/bean/thirdPartyLibComparison.md index 256756e22..65dae5992 100644 --- a/docs/site/markdown/transformer/bean/thirdPartyLibComparison.md +++ b/docs/site/markdown/transformer/bean/thirdPartyLibComparison.md @@ -2,7 +2,7 @@ Third Party Library comparison -# Third Party Libraries comparison +# Third-Party Libraries comparison This page compares the Transformer functionalities with the following Third-Party libraries: @@ -32,5 +32,5 @@ This page compares the Transformer functionalities with the following Third-Part | Annotation field validation | X | - | X | - | _[*] Immutable types are not supported by Dozer. When a type doesn't have a no-arg constructor and all fields are final, Dozer can't perform the mapping. - Workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ +The workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ _[+] Requires a custom configuration_ diff --git a/docs/site/markdown/transformer/beanTransformer.md b/docs/site/markdown/transformer/beanTransformer.md index f1d626021..4ef03dacc 100644 --- a/docs/site/markdown/transformer/beanTransformer.md +++ b/docs/site/markdown/transformer/beanTransformer.md @@ -4,5 +4,5 @@ # Bean Transformer -is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable and incredibly fast. -It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. +is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable, and incredibly fast. +It's the only library able to transform Mutable, Immutable, and Mixed bean without any custom configuration. From 9f3334090ec0ce9f614b28442e36afcbffd9c7af Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 5 Nov 2020 02:14:31 +0000 Subject: [PATCH 1252/1786] Bump hotels-oss-parent from 6.1.0 to 6.2.0 Bumps [hotels-oss-parent](https://github.com/HotelsDotCom/hotels-oss-parent) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/HotelsDotCom/hotels-oss-parent/releases) - [Changelog](https://github.com/HotelsDotCom/hotels-oss-parent/blob/master/CHANGELOG.md) - [Commits](https://github.com/HotelsDotCom/hotels-oss-parent/compare/hotels-oss-parent-6.1.0...hotels-oss-parent-6.2.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e0e2c6da7..8a42e0d16 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ com.hotels hotels-oss-parent - 6.1.0 + 6.2.0 From f0e1214a151e7dd1fe7c16d2ad13fba9acf3058e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 12 Nov 2020 02:13:33 +0000 Subject: [PATCH 1253/1786] Bump assertj-core from 3.18.0 to 3.18.1 Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.18.0 to 3.18.1. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.18.0...assertj-core-3.18.1) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8a42e0d16..501e06cdb 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.6.0 7.3.0 - 3.18.0 + 3.18.1 2.0.1.Final 6.1.6.Final From 69591913b6258167127bf36e79c2936b4424de09 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 26 Nov 2020 02:23:21 +0000 Subject: [PATCH 1254/1786] Bump mockito-core from 3.6.0 to 3.6.28 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.6.0 to 3.6.28. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.6.0...v3.6.28) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 501e06cdb..30284140d 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.6.0 + 3.6.28 7.3.0 3.18.1 From 3e4e0f1e9ad639e7c7710bef996e0a47dc12f32c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Nov 2020 02:17:35 +0000 Subject: [PATCH 1255/1786] Bump wagon-ssh from 3.4.0 to 3.4.2 Bumps wagon-ssh from 3.4.0 to 3.4.2. Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 30284140d..9dc9397b4 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ 2.3.1 - 3.4.0 + 3.4.2 0.12 github 3.9.1 From 490f2502ba29fadd77a2769f92e7fe2232797a69 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 17 Dec 2020 02:13:13 +0000 Subject: [PATCH 1256/1786] Bump hibernate-validator from 6.1.6.Final to 6.1.7.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.1.6.Final to 6.1.7.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.1.7.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.1.6.Final...6.1.7.Final) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9dc9397b4..63607e258 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 3.18.1 2.0.1.Final - 6.1.6.Final + 6.1.7.Final 1.7.30 3.0.0 2.2.6 From f1b86bc884aa8bfdeeca90327ef486901584a800 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 24 Dec 2020 02:14:19 +0000 Subject: [PATCH 1257/1786] Bump hibernate-validator from 6.1.7.Final to 7.0.0.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.1.7.Final to 7.0.0.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/master/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.1.7.Final...7.0.0.Final) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 63607e258..cea915533 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 3.18.1 2.0.1.Final - 6.1.7.Final + 7.0.0.Final 1.7.30 3.0.0 2.2.6 From 96c5d29ad78b15926d038489e712ea34f89e7d20 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Dec 2020 11:16:52 +0100 Subject: [PATCH 1258/1786] Replaces the validator from javax to jakarta --- bull-common/pom.xml | 19 +++++--------- .../transformer/validator/Validator.java | 2 +- .../transformer/validator/ValidatorImpl.java | 10 ++++---- .../sample/immutable/ImmutableToFoo.java | 2 +- .../ImmutableToFooCustomAnnotation.java | 2 +- .../immutable/ImmutableToFooDiffFields.java | 2 +- ...ImmutableToFooMissingCustomAnnotation.java | 2 +- .../immutable/ImmutableToFooSubClass.java | 2 +- .../ImmutableToSubFooCustomAnnotation.java | 2 +- .../hotels/beans/sample/mixed/MixedToFoo.java | 2 +- .../MixedToFooMissingAllArgsConstructor.java | 2 +- .../mixed/MixedToFooMissingConstructor.java | 2 +- .../transformer/utils/ClassUtilsTest.java | 2 +- .../utils/ReflectionUtilsTest.java | 4 +-- config/checkstyle/rules.xml | 4 +-- pom.xml | 25 ++++++------------- 16 files changed, 33 insertions(+), 51 deletions(-) diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 86d2df3e1..60ad0c0f0 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 BULL - Common bull-common @@ -18,22 +19,14 @@ commons-lang3 - - javax.validation - validation-api - - - javax.el - javax.el-api - - - org.glassfish.web - javax.el - org.hibernate.validator hibernate-validator + + org.glassfish + jakarta.el + diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java b/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java index d18b0c789..2c5760897 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Set; -import javax.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolation; /** * Java Bean validation class. diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java index 6661a659e..bb90296a5 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java @@ -19,7 +19,7 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; -import static javax.validation.Validation.buildDefaultValidatorFactory; +import static jakarta.validation.Validation.buildDefaultValidatorFactory; import static org.apache.commons.lang3.StringUtils.SPACE; @@ -31,7 +31,7 @@ import java.util.Set; import java.util.function.Function; -import javax.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolation; import com.hotels.transformer.cache.CacheManager; import com.hotels.transformer.error.InvalidBeanException; @@ -101,11 +101,11 @@ private Function, String> getConstraintViolationMess * Creates the validator. * @return a {@link javax.validation.Validator} instance. */ - private javax.validation.Validator getValidator() { + private jakarta.validation.Validator getValidator() { String cacheKey = "BeanValidator"; - return cacheManager.getFromCache(cacheKey, javax.validation.Validator.class) + return cacheManager.getFromCache(cacheKey, jakarta.validation.Validator.class) .orElseGet(() -> { - javax.validation.Validator validator = buildDefaultValidatorFactory().getValidator(); + jakarta.validation.Validator validator = buildDefaultValidatorFactory().getValidator(); cacheManager.cacheObject(cacheKey, validator); return validator; }); diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java index 45b2286ce..cee257eed 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java @@ -19,7 +19,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java index 7a54e1403..aa9ae97f1 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -19,7 +19,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.hotels.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java index 9ab0e1d9b..bb7abd95e 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java @@ -19,7 +19,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java index e094bd951..9fd50a3d2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -16,7 +16,7 @@ package com.hotels.beans.sample.immutable; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.hotels.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java index 086dbe60b..e65e099cb 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java @@ -20,7 +20,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.ToString; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java index 51af1f845..ea981dfac 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -19,7 +19,7 @@ import java.util.List; import java.util.Map; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.hotels.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java index 04d055138..0ce9e79eb 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java @@ -19,7 +19,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.hotels.beans.sample.immutable.ImmutableToSubFoo; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java index 88db639a3..89ab89ee2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java @@ -19,7 +19,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.hotels.beans.sample.immutable.ImmutableToSubFoo; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java index 5f5d7f1f6..276c31e92 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -18,7 +18,7 @@ import java.math.BigInteger; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index f00f883d7..2cd2abfcf 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -44,7 +44,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index befe8828c..87d4d978d 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -45,8 +45,8 @@ import java.util.Map; import java.util.Optional; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.mockito.InjectMocks; diff --git a/config/checkstyle/rules.xml b/config/checkstyle/rules.xml index 27de1383e..c1ff34307 100644 --- a/config/checkstyle/rules.xml +++ b/config/checkstyle/rules.xml @@ -110,11 +110,11 @@ - + - + diff --git a/pom.xml b/pom.xml index cea915533..e125d6875 100644 --- a/pom.xml +++ b/pom.xml @@ -60,8 +60,7 @@ 2.0.1.Final 7.0.0.Final 1.7.30 - 3.0.0 - 2.2.6 + 4.0.0 0.8.6 1.0 @@ -86,7 +85,7 @@ false true false - \#java,\#javax,\#org,\#,\#com,,\#lombok,java,javax,org,,com,,lombok + \#java,\#javax,\#jakarta,\#org,\#,\#com,,\#lombok,java,javax,jakarta,org,,com,,lombok false @@ -112,26 +111,16 @@ ${apache.commons-lang3.version} - - javax.validation - validation-api - ${validation-api.version} - - - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish.web - javax.el - ${glassfish.javax.el.version} - org.hibernate.validator hibernate-validator ${hibernate-validator.version} + + org.glassfish + jakarta.el + ${glassfish.jakarta.el.version} + org.slf4j From 0055a5165da204392c8e710106c13f834ef3a29d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 25 Dec 2020 02:12:57 +0000 Subject: [PATCH 1259/1786] Bump jakarta.el from 4.0.0 to 4.0.1 Bumps [jakarta.el](https://github.com/eclipse-ee4j/el-ri) from 4.0.0 to 4.0.1. - [Release notes](https://github.com/eclipse-ee4j/el-ri/releases) - [Commits](https://github.com/eclipse-ee4j/el-ri/commits) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e125d6875..f9bf6b5f8 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 2.0.1.Final 7.0.0.Final 1.7.30 - 4.0.0 + 4.0.1 0.8.6 1.0 From eb60a8bc06ae14844db3648c8f15dbf9dd52f897 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 6 Jan 2021 02:14:44 +0000 Subject: [PATCH 1260/1786] Bump mockito-core from 3.6.28 to 3.7.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.6.28 to 3.7.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.6.28...v3.7.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f9bf6b5f8..ac3e21e71 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.11 1.3.0 - 3.6.28 + 3.7.0 7.3.0 3.18.1 From 90bc01d8920cf33fb0759051b4f711c58268accd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 08:58:36 +0100 Subject: [PATCH 1261/1786] Adds the BOM module --- CHANGELOG-JDK8.md | 5 +++++ CHANGELOG.md | 4 ++++ README.md | 12 ++++++++++++ bull-bom/pom.xml | 35 +++++++++++++++++++++++++++++++++++ pom.xml | 1 + 5 files changed, 57 insertions(+) create mode 100644 bull-bom/pom.xml diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 043772e3e..8ea4c6482 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +### [1.7.4-jdk8] 2021.01.11 +#### Added +* Provides new module `bull-bom` that includes all the project modules + + ### [1.7.3-jdk8] 2020.10.07 #### Changed * Provides new utilities methods diff --git a/CHANGELOG.md b/CHANGELOG.md index 66d58925e..ce5c59abc 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [1.7.5] 2021.01.11 +#### Added +* Provides new module `bull-bom` that includes all the project modules + ### [1.7.4] 2020.10.07 #### Changed * Provides new utilities methods diff --git a/README.md b/README.md index 87a19c8e7..576737047 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,18 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho All BULL modules are available on Maven Central: +* ### Bean BOM + +It contains all the modules available in the project + +```xml + + com.hotels.beans + bull-bom + x.y.z + +``` + * ### Bean Transformer ```xml diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml new file mode 100644 index 000000000..763ecc97e --- /dev/null +++ b/bull-bom/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + BULL - BOM + bull-bom + jar + Contains all the modules available in the BULL project + + + com.hotels.beans + bean-utils-library-parent + 1.7.5-SNAPSHOT + + + + + com.hotels.beans + bull-bean-transformer + ${project.version} + + + com.hotels.beans + bull-map-transformer + ${project.version} + + + com.hotels.beans + bull-converter + ${project.version} + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index ac3e21e71..61bc68686 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ bull-bean-transformer bull-converter bull-report + bull-bom From 787b7e3ba941ed08602877f4232e05e684e1d43d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 09:13:08 +0100 Subject: [PATCH 1262/1786] minor: blank line removal --- CHANGELOG-JDK8.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 8ea4c6482..9bee30649 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -6,7 +6,6 @@ All notable changes to this project will be documented in this file. #### Added * Provides new module `bull-bom` that includes all the project modules - ### [1.7.3-jdk8] 2020.10.07 #### Changed * Provides new utilities methods From 1c782434bb2498228b35cfef3d3c099300d368f8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 09:14:48 +0100 Subject: [PATCH 1263/1786] [maven-release-plugin] prepare release 1.7.5 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 6 ++---- bull-common/pom.xml | 5 ++--- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 13 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 1794a6d67..c7c96ccb2 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 763ecc97e..bd6c93498 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 BULL - BOM bull-bom @@ -11,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 60ad0c0f0..4a73902c1 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -1,6 +1,5 @@ - + 4.0.0 BULL - Common bull-common @@ -10,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index b673dad5c..d4e20ac5c 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index ec7c9e569..73ed19527 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index c4d6b74e6..b84a50e39 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/pom.xml b/pom.xml index 61bc68686..ab68b2ee7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.5-SNAPSHOT + 1.7.5 pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.7.5 From fee48e78178ca144bb0b128ab2744234be3ffe09 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 09:16:22 +0100 Subject: [PATCH 1264/1786] prepares the release --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c7c96ccb2..1794a6d67 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5 + 1.7.5-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index bd6c93498..6ac20586a 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5 + 1.7.5-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 4a73902c1..ced02f5a8 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5 + 1.7.5-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index d4e20ac5c..b673dad5c 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5 + 1.7.5-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 73ed19527..ec7c9e569 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5 + 1.7.5-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index b84a50e39..c4d6b74e6 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5 + 1.7.5-SNAPSHOT diff --git a/pom.xml b/pom.xml index ab68b2ee7..5b1677359 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.5 + 1.7.5-SNAPSHOT pom 2019 From f534f7d567cbc1a7674717df719d71f6dcbb8b52 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 09:17:25 +0100 Subject: [PATCH 1265/1786] [maven-release-plugin] prepare release 1.7.5 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 1794a6d67..c7c96ccb2 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 6ac20586a..bd6c93498 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index ced02f5a8..4a73902c1 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index b673dad5c..d4e20ac5c 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index ec7c9e569..73ed19527 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index c4d6b74e6..b84a50e39 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5-SNAPSHOT + 1.7.5 diff --git a/pom.xml b/pom.xml index 5b1677359..ab68b2ee7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.5-SNAPSHOT + 1.7.5 pom 2019 From 519115b366fd337fc6ea0e752b608269aee07458 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 09:17:34 +0100 Subject: [PATCH 1266/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c7c96ccb2..14540bf89 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5 + 1.7.6-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index bd6c93498..c63365350 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5 + 1.7.6-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 4a73902c1..25b8e3129 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5 + 1.7.6-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index d4e20ac5c..c6791cbf8 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5 + 1.7.6-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 73ed19527..700cc4db5 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5 + 1.7.6-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index b84a50e39..3ee922b91 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5 + 1.7.6-SNAPSHOT diff --git a/pom.xml b/pom.xml index ab68b2ee7..c6ad6ee46 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.5 + 1.7.6-SNAPSHOT pom 2019 From e2745861e9186d53d8b9b6d93d7cb6a192ed74d8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 09:27:09 +0100 Subject: [PATCH 1267/1786] updates the changelog --- CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 9bee30649..9eaa4011c 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.7.4-jdk8] 2021.01.11 +### [1.7.5-jdk8] 2021.01.11 #### Added * Provides new module `bull-bom` that includes all the project modules diff --git a/CHANGELOG.md b/CHANGELOG.md index ce5c59abc..727ec911c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.7.5] 2021.01.11 +### [1.7.6] 2021.01.11 #### Added * Provides new module `bull-bom` that includes all the project modules From cadea31af2e1939f36a3d4325d2874e04dfe46dd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 09:28:33 +0100 Subject: [PATCH 1268/1786] [maven-release-plugin] prepare release 1.7.6 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 14540bf89..c45ba07e5 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index c63365350..9c8aa3484 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 25b8e3129..3a992e267 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index c6791cbf8..5d11f5727 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 700cc4db5..6592ec9a4 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 3ee922b91..f8a46cf41 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/pom.xml b/pom.xml index c6ad6ee46..747a551fe 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.6-SNAPSHOT + 1.7.6 pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.5 + 1.7.6 From 91fa8ae17d6d3c0b258812b80e795109995cd6a4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 09:28:42 +0100 Subject: [PATCH 1269/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c45ba07e5..f1f585b1b 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 9c8aa3484..e6bf1c90c 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 3a992e267..e30be3edf 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 5d11f5727..f0f40ade5 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 6592ec9a4..f6760c9f7 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index f8a46cf41..8cc9da971 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/pom.xml b/pom.xml index 747a551fe..08abac9d1 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.6 + 1.7.7-SNAPSHOT pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.6 + 1.7.5 From a0062a840a4c599db85656583a17cee10c1d92f4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 09:41:20 +0100 Subject: [PATCH 1270/1786] [maven-release-plugin] rollback the release of 1.7.5-jdk8 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index f1f585b1b..a0df6132d 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.7-SNAPSHOT + 1.7.5-jdk8-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index e6bf1c90c..9caa1d91c 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.7-SNAPSHOT + 1.7.5-jdk8-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e30be3edf..325274a1e 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.7-SNAPSHOT + 1.7.5-jdk8-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index f0f40ade5..ba5a9be5a 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.7-SNAPSHOT + 1.7.5-jdk8-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f6760c9f7..0e3d58d17 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.7-SNAPSHOT + 1.7.5-jdk8-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 8cc9da971..41933ac0d 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.7-SNAPSHOT + 1.7.5-jdk8-SNAPSHOT diff --git a/pom.xml b/pom.xml index 08abac9d1..d9be20e09 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.7-SNAPSHOT + 1.7.5-jdk8-SNAPSHOT pom 2019 @@ -47,7 +47,7 @@ UTF-8 UTF-8 - 11 + 1.8 ${jdk.version} ${jdk.version} 1.18.16 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.5 + HEAD From 62ffb9232049b4c53d55482c3b4aca37994dfb73 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 10:03:56 +0100 Subject: [PATCH 1271/1786] updates the changelog --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 +++- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index a0df6132d..14540bf89 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-jdk8-SNAPSHOT + 1.7.6-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 9caa1d91c..c63365350 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-jdk8-SNAPSHOT + 1.7.6-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 325274a1e..25b8e3129 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-jdk8-SNAPSHOT + 1.7.6-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index ba5a9be5a..c6791cbf8 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.5-jdk8-SNAPSHOT + 1.7.6-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0e3d58d17..700cc4db5 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5-jdk8-SNAPSHOT + 1.7.6-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 41933ac0d..3ee922b91 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.5-jdk8-SNAPSHOT + 1.7.6-SNAPSHOT diff --git a/pom.xml b/pom.xml index d9be20e09..994f0338f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.5-jdk8-SNAPSHOT + 1.7.6-SNAPSHOT pom 2019 @@ -659,6 +659,7 @@ maven-javadoc-plugin ${javadoc.skip} + 8 @@ -706,6 +707,7 @@ org.apache.maven.plugins maven-javadoc-plugin + 8 public From 03c8c368be780e0d700c064adf93dd2d3a56bf7f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 10:05:30 +0100 Subject: [PATCH 1272/1786] [maven-release-plugin] prepare release 1.7.6 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 14540bf89..c45ba07e5 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index c63365350..9c8aa3484 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 25b8e3129..3a992e267 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index c6791cbf8..5d11f5727 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 700cc4db5..6592ec9a4 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 3ee922b91..f8a46cf41 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.6-SNAPSHOT + 1.7.6 diff --git a/pom.xml b/pom.xml index 994f0338f..9c266c481 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.6-SNAPSHOT + 1.7.6 pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 1.7.6 From 4a6bea5d2b39dcccb7ed54c2c00d08f04632dbab Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 10:05:39 +0100 Subject: [PATCH 1273/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c45ba07e5..f1f585b1b 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 9c8aa3484..e6bf1c90c 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 3a992e267..e30be3edf 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 5d11f5727..f0f40ade5 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 6592ec9a4..f6760c9f7 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index f8a46cf41..8cc9da971 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.6 + 1.7.7-SNAPSHOT diff --git a/pom.xml b/pom.xml index 9c266c481..af8e242fd 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.6 + 1.7.7-SNAPSHOT pom 2019 @@ -95,7 +95,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 1.7.6 + HEAD From 7e6d380c195dcf0bb48e6990500918521722f614 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 11 Jan 2021 10:25:32 +0100 Subject: [PATCH 1274/1786] Reverts the javadoc plugin config --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index af8e242fd..e661351a8 100644 --- a/pom.xml +++ b/pom.xml @@ -659,7 +659,6 @@ maven-javadoc-plugin ${javadoc.skip} - 8 @@ -707,7 +706,6 @@ org.apache.maven.plugins maven-javadoc-plugin - 8 public From d108ae5eb8d3a1c4fa147df87f4f68623929418a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 18 Jan 2021 02:16:54 +0000 Subject: [PATCH 1275/1786] Bump mockito-core from 3.7.0 to 3.7.7 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.7.0 to 3.7.7. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.7.0...v3.7.7) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e661351a8..92f80f806 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.11 1.3.0 - 3.7.0 + 3.7.7 7.3.0 3.18.1 From 10b20d34cc9232bd4f3731680fab94f168f1f4e3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 25 Jan 2021 02:15:25 +0000 Subject: [PATCH 1276/1786] Bump assertj-core from 3.18.1 to 3.19.0 Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.18.1 to 3.19.0. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.18.1...assertj-core-3.19.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 92f80f806..3e2876840 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 3.7.7 7.3.0 - 3.18.1 + 3.19.0 2.0.1.Final 7.0.0.Final From 480ce6dda5e47d73ceddd005eb74ad509371e7d6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 29 Jan 2021 02:13:02 +0000 Subject: [PATCH 1277/1786] Bump lombok from 1.18.16 to 1.18.18 Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.18.16 to 1.18.18. - [Release notes](https://github.com/rzwitserloot/lombok/releases) - [Changelog](https://github.com/rzwitserloot/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/rzwitserloot/lombok/compare/v1.18.16...v1.18.18) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3e2876840..c71b3fadd 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 1.8 ${jdk.version} ${jdk.version} - 1.18.16 + 1.18.18 3.11 1.3.0 From 271713c73a71b067fbbb0b080a7163fe6a39d15b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 29 Jan 2021 15:03:37 +0100 Subject: [PATCH 1278/1786] - Replaces the SizeAndTimeBasedFNATP with SizeAndTimeBasedRollingPolicy - Adds the logging of the third-party service --- .../config/logging/logback-appenders.xml | 30 +++++++++++++++---- .../src/main/resources/logback.xml | 20 +++++++++---- .../src/test/resources/logback-test.xml | 20 +++++++++---- .../config/logging/logback-appenders.xml | 30 +++++++++++++++---- .../src/test/resources/logback-test.xml | 20 +++++++++---- .../config/logging/logback-appenders.xml | 30 +++++++++++++++---- .../src/main/resources/logback.xml | 22 +++++++++----- .../test/resources/config/logback-test.xml | 20 +++++++++---- .../config/logging/logback-appenders.xml | 30 ------------------- .../config/logging/logback-properties.xml | 5 ---- 10 files changed, 143 insertions(+), 84 deletions(-) delete mode 100644 bull-map-transformer/src/test/resources/config/logging/logback-appenders.xml delete mode 100644 bull-map-transformer/src/test/resources/config/logging/logback-properties.xml diff --git a/bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml b/bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml index 570ecb4f0..0c350d67d 100644 --- a/bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml +++ b/bull-bean-transformer/src/main/resources/config/logging/logback-appenders.xml @@ -18,13 +18,31 @@ UTF-8 ${LOG_PATTERN} - - ${ROOT_LOG_DIR}/bull-bean-transformer-%d{yyyy-MM-dd}-%i.log.zip - + + ${ROOT_LOG_DIR}/bull-bean-transformer-%d{yyyy-MM-dd}-%i.log.zip + 5MB + + 500MB + + 30 + + + + + + ${ROOT_LOG_DIR}/third-party-service.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/third-party-service-%d{yyyy-MM-dd}-%i.log.zip + 5MB + + 500MB + 30 - - 5MB - \ No newline at end of file diff --git a/bull-bean-transformer/src/main/resources/logback.xml b/bull-bean-transformer/src/main/resources/logback.xml index 8d4f400ab..25d935bb3 100644 --- a/bull-bean-transformer/src/main/resources/logback.xml +++ b/bull-bean-transformer/src/main/resources/logback.xml @@ -1,5 +1,5 @@ - - - - + + + + + + + + + + + + - + diff --git a/bull-bean-transformer/src/test/resources/logback-test.xml b/bull-bean-transformer/src/test/resources/logback-test.xml index 8d4f400ab..bb3a219f1 100644 --- a/bull-bean-transformer/src/test/resources/logback-test.xml +++ b/bull-bean-transformer/src/test/resources/logback-test.xml @@ -1,5 +1,5 @@ - - - - + + + + + + + + + + + + @@ -29,8 +37,8 @@ - + \ No newline at end of file diff --git a/bull-common/src/test/resources/config/logging/logback-appenders.xml b/bull-common/src/test/resources/config/logging/logback-appenders.xml index d677974af..b21bae556 100644 --- a/bull-common/src/test/resources/config/logging/logback-appenders.xml +++ b/bull-common/src/test/resources/config/logging/logback-appenders.xml @@ -18,13 +18,31 @@ UTF-8 ${LOG_PATTERN} - - ${ROOT_LOG_DIR}/bull-common-%d{yyyy-MM-dd}-%i.log.zip - + + ${ROOT_LOG_DIR}/bull-common-%d{yyyy-MM-dd}-%i.log.zip + 5MB + + 500MB + + 30 + + + + + + ${ROOT_LOG_DIR}/third-party-service.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/third-party-service-%d{yyyy-MM-dd}-%i.log.zip + 5MB + + 500MB + 30 - - 5MB - \ No newline at end of file diff --git a/bull-common/src/test/resources/logback-test.xml b/bull-common/src/test/resources/logback-test.xml index 645872622..bed93a3ed 100644 --- a/bull-common/src/test/resources/logback-test.xml +++ b/bull-common/src/test/resources/logback-test.xml @@ -1,5 +1,5 @@ - - - - + + + + + + + + + + + + - + diff --git a/bull-map-transformer/src/main/resources/config/logging/logback-appenders.xml b/bull-map-transformer/src/main/resources/config/logging/logback-appenders.xml index b8fab1514..c00ea8710 100644 --- a/bull-map-transformer/src/main/resources/config/logging/logback-appenders.xml +++ b/bull-map-transformer/src/main/resources/config/logging/logback-appenders.xml @@ -18,13 +18,31 @@ UTF-8 ${LOG_PATTERN} - - ${ROOT_LOG_DIR}/bull-map-transformer-%d{yyyy-MM-dd}-%i.log.zip - + + ${ROOT_LOG_DIR}/bull-map-transformer-%d{yyyy-MM-dd}-%i.log.zip + 5MB + + 500MB + + 30 + + + + + + ${ROOT_LOG_DIR}/third-party-service.log + true + + UTF-8 + ${LOG_PATTERN} + + + ${ROOT_LOG_DIR}/third-party-service-%d{yyyy-MM-dd}-%i.log.zip + 5MB + + 500MB + 30 - - 5MB - \ No newline at end of file diff --git a/bull-map-transformer/src/main/resources/logback.xml b/bull-map-transformer/src/main/resources/logback.xml index aee2b56d3..26f67b0c5 100644 --- a/bull-map-transformer/src/main/resources/logback.xml +++ b/bull-map-transformer/src/main/resources/logback.xml @@ -1,5 +1,5 @@ - - - - + + + + + + + + + + + + - + - + \ No newline at end of file diff --git a/bull-map-transformer/src/test/resources/config/logback-test.xml b/bull-map-transformer/src/test/resources/config/logback-test.xml index aee2b56d3..3ab1d694f 100644 --- a/bull-map-transformer/src/test/resources/config/logback-test.xml +++ b/bull-map-transformer/src/test/resources/config/logback-test.xml @@ -18,19 +18,27 @@ - - - - + + + + + + + + + + + + - + - + \ No newline at end of file diff --git a/bull-map-transformer/src/test/resources/config/logging/logback-appenders.xml b/bull-map-transformer/src/test/resources/config/logging/logback-appenders.xml deleted file mode 100644 index b8fab1514..000000000 --- a/bull-map-transformer/src/test/resources/config/logging/logback-appenders.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - ${LOG_PATTERN} - - - - - - ${ROOT_LOG_DIR}/bull-map-transformer.log - true - - UTF-8 - ${LOG_PATTERN} - - - ${ROOT_LOG_DIR}/bull-map-transformer-%d{yyyy-MM-dd}-%i.log.zip - - 30 - - 5MB - - - - \ No newline at end of file diff --git a/bull-map-transformer/src/test/resources/config/logging/logback-properties.xml b/bull-map-transformer/src/test/resources/config/logging/logback-properties.xml deleted file mode 100644 index 934b4e88b..000000000 --- a/bull-map-transformer/src/test/resources/config/logging/logback-properties.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - From 2245b33af8384f9cc710ad98d8be9407c517e698 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 02:16:16 +0000 Subject: [PATCH 1279/1786] Bump maven-checkstyle-plugin from 3.1.1 to 3.1.2 Bumps [maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.1.1 to 3.1.2. - [Release notes](https://github.com/apache/maven-checkstyle-plugin/releases) - [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.1.1...maven-checkstyle-plugin-3.1.2) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c71b3fadd..0eae6bff5 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ 3.9.1 1.6 - 3.1.1 + 3.1.2 false true false From a71e941d04746938b9c2b84c5aa154a949c692be Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 8 Feb 2021 02:18:05 +0000 Subject: [PATCH 1280/1786] Bump hibernate-validator from 7.0.0.Final to 7.0.1.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 7.0.0.Final to 7.0.1.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/master/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/7.0.0.Final...7.0.1.Final) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0eae6bff5..0f45779ec 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 3.19.0 2.0.1.Final - 7.0.0.Final + 7.0.1.Final 1.7.30 4.0.1 From b053faad9709a65197e000547398c04e03f2656c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 17 Feb 2021 02:13:31 +0000 Subject: [PATCH 1281/1786] Bump hotels-oss-parent from 6.2.0 to 6.2.1 Bumps [hotels-oss-parent](https://github.com/HotelsDotCom/hotels-oss-parent) from 6.2.0 to 6.2.1. - [Release notes](https://github.com/HotelsDotCom/hotels-oss-parent/releases) - [Changelog](https://github.com/HotelsDotCom/hotels-oss-parent/blob/main/CHANGELOG.md) - [Commits](https://github.com/HotelsDotCom/hotels-oss-parent/compare/hotels-oss-parent-6.2.0...hotels-oss-parent-6.2.1) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0f45779ec..5e6e141c9 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ com.hotels hotels-oss-parent - 6.2.0 + 6.2.1 From d30bef16a9110e0333433887a0f2c20c0fbf796f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 18 Feb 2021 21:24:56 +0100 Subject: [PATCH 1282/1786] Fixes the checkstyle error --- .../src/main/java/com/hotels/beans/BeanUtils.java | 2 +- .../src/main/java/com/hotels/beans/package-info.java | 2 +- .../main/java/com/hotels/beans/populator/ArrayPopulator.java | 2 +- .../java/com/hotels/beans/populator/CollectionPopulator.java | 2 +- .../java/com/hotels/beans/populator/ICollectionPopulator.java | 2 +- .../main/java/com/hotels/beans/populator/MapPopulator.java | 2 +- .../java/com/hotels/beans/populator/OptionalPopulator.java | 2 +- .../src/main/java/com/hotels/beans/populator/Populator.java | 2 +- .../java/com/hotels/beans/populator/PopulatorFactory.java | 2 +- .../main/java/com/hotels/beans/populator/package-info.java | 2 +- .../com/hotels/beans/transformer/AbstractBeanTransformer.java | 2 +- .../java/com/hotels/beans/transformer/BeanTransformer.java | 2 +- .../main/java/com/hotels/beans/transformer/package-info.java | 2 +- .../src/test/java/com/hotels/beans/BeanUtilsTest.java | 2 +- .../src/test/java/com/hotels/beans/package-info.java | 2 +- .../java/com/hotels/beans/performance/PerformanceTest.java | 2 +- .../test/java/com/hotels/beans/performance/package-info.java | 2 +- .../java/com/hotels/beans/populator/ArrayPopulatorTest.java | 2 +- .../java/com/hotels/beans/populator/PopulatorFactoryTest.java | 2 +- .../test/java/com/hotels/beans/populator/package-info.java | 2 +- .../hotels/beans/transformer/AbstractBeanTransformerTest.java | 2 +- .../com/hotels/beans/transformer/BeanTransformerTest.java | 2 +- .../beans/transformer/BuilderObjectTransformationTest.java | 2 +- .../beans/transformer/MixedObjectTransformationTest.java | 2 +- .../beans/transformer/MutableObjectTransformationTest.java | 2 +- .../test/java/com/hotels/beans/transformer/package-info.java | 2 +- .../main/java/com/hotels/transformer/AbstractTransformer.java | 2 +- .../src/main/java/com/hotels/transformer/Transformer.java | 2 +- .../com/hotels/transformer/annotation/ConstructorArg.java | 2 +- .../java/com/hotels/transformer/annotation/package-info.java | 2 +- .../src/main/java/com/hotels/transformer/base/Defaults.java | 2 +- .../main/java/com/hotels/transformer/base/package-info.java | 2 +- .../main/java/com/hotels/transformer/cache/CacheManager.java | 2 +- .../com/hotels/transformer/cache/CacheManagerFactory.java | 2 +- .../main/java/com/hotels/transformer/cache/package-info.java | 2 +- .../main/java/com/hotels/transformer/constant/ClassType.java | 2 +- .../main/java/com/hotels/transformer/constant/Filters.java | 2 +- .../java/com/hotels/transformer/constant/MethodPrefix.java | 2 +- .../java/com/hotels/transformer/constant/Punctuation.java | 2 +- .../java/com/hotels/transformer/constant/package-info.java | 2 +- .../hotels/transformer/error/InstanceCreationException.java | 2 +- .../com/hotels/transformer/error/InvalidBeanException.java | 2 +- .../hotels/transformer/error/InvalidFunctionException.java | 2 +- .../com/hotels/transformer/error/MissingFieldException.java | 2 +- .../com/hotels/transformer/error/MissingMethodException.java | 2 +- .../main/java/com/hotels/transformer/error/package-info.java | 2 +- .../main/java/com/hotels/transformer/model/EmptyValue.java | 2 +- .../main/java/com/hotels/transformer/model/FieldMapping.java | 2 +- .../java/com/hotels/transformer/model/FieldTransformer.java | 2 +- .../src/main/java/com/hotels/transformer/model/ItemType.java | 2 +- .../main/java/com/hotels/transformer/model/MapElemType.java | 2 +- .../src/main/java/com/hotels/transformer/model/MapType.java | 2 +- .../com/hotels/transformer/model/TransformerSettings.java | 2 +- .../main/java/com/hotels/transformer/model/package-info.java | 2 +- .../src/main/java/com/hotels/transformer/package-info.java | 2 +- .../main/java/com/hotels/transformer/utils/ClassUtils.java | 2 +- .../java/com/hotels/transformer/utils/ReflectionUtils.java | 2 +- .../main/java/com/hotels/transformer/utils/package-info.java | 2 +- .../main/java/com/hotels/transformer/validator/Validator.java | 2 +- .../java/com/hotels/transformer/validator/ValidatorImpl.java | 2 +- .../java/com/hotels/transformer/validator/package-info.java | 2 +- bull-common/src/test/java/com/hotels/beans/package-info.java | 2 +- .../src/test/java/com/hotels/beans/sample/AbstractClass.java | 2 +- .../src/test/java/com/hotels/beans/sample/FromFoo.java | 2 +- .../test/java/com/hotels/beans/sample/FromFooAdvFields.java | 2 +- .../src/test/java/com/hotels/beans/sample/FromFooMap.java | 2 +- .../src/test/java/com/hotels/beans/sample/FromFooNoField.java | 2 +- .../com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java | 2 +- .../src/test/java/com/hotels/beans/sample/FromFooSimple.java | 2 +- .../com/hotels/beans/sample/FromFooSimpleBooleanField.java | 2 +- .../java/com/hotels/beans/sample/FromFooSimpleNoGetters.java | 2 +- .../test/java/com/hotels/beans/sample/FromFooSubClass.java | 2 +- .../com/hotels/beans/sample/FromFooWithPrimitiveFields.java | 2 +- .../src/test/java/com/hotels/beans/sample/FromSubFoo.java | 2 +- .../src/test/java/com/hotels/beans/sample/ISubClass.java | 2 +- .../com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java | 2 +- .../com/hotels/beans/sample/immutable/ImmutableToFoo.java | 2 +- .../beans/sample/immutable/ImmutableToFooAdvFields.java | 2 +- .../sample/immutable/ImmutableToFooCustomAnnotation.java | 2 +- .../beans/sample/immutable/ImmutableToFooDiffFields.java | 2 +- .../beans/sample/immutable/ImmutableToFooDiffTypesFields.java | 2 +- .../com/hotels/beans/sample/immutable/ImmutableToFooMap.java | 2 +- .../immutable/ImmutableToFooMissingCustomAnnotation.java | 2 +- .../beans/sample/immutable/ImmutableToFooNoConstructors.java | 2 +- .../sample/immutable/ImmutableToFooNotExistingFields.java | 2 +- .../hotels/beans/sample/immutable/ImmutableToFooSimple.java | 2 +- .../beans/sample/immutable/ImmutableToFooSimpleBoolean.java | 2 +- .../sample/immutable/ImmutableToFooSimpleWrongTypes.java | 2 +- .../hotels/beans/sample/immutable/ImmutableToFooSubClass.java | 2 +- .../beans/sample/immutable/ImmutableToFooWithBuilder.java | 2 +- .../com/hotels/beans/sample/immutable/ImmutableToSubFoo.java | 2 +- .../sample/immutable/ImmutableToSubFooCustomAnnotation.java | 2 +- .../java/com/hotels/beans/sample/immutable/package-info.java | 2 +- .../test/java/com/hotels/beans/sample/mixed/MixedToFoo.java | 2 +- .../com/hotels/beans/sample/mixed/MixedToFooDiffFields.java | 2 +- .../sample/mixed/MixedToFooMissingAllArgsConstructor.java | 2 +- .../beans/sample/mixed/MixedToFooMissingConstructor.java | 2 +- .../com/hotels/beans/sample/mixed/MixedToFooMissingField.java | 2 +- .../beans/sample/mixed/MixedToFooNotExistingFields.java | 2 +- .../com/hotels/beans/sample/mixed/MixedToFooStaticField.java | 2 +- .../com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java | 2 +- .../beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java | 2 +- .../test/java/com/hotels/beans/sample/mixed/package-info.java | 2 +- .../java/com/hotels/beans/sample/mutable/MutableToFoo.java | 2 +- .../hotels/beans/sample/mutable/MutableToFooAdvFields.java | 2 +- .../com/hotels/beans/sample/mutable/MutableToFooInvalid.java | 2 +- .../beans/sample/mutable/MutableToFooNotExistingFields.java | 2 +- .../com/hotels/beans/sample/mutable/MutableToFooSimple.java | 2 +- .../beans/sample/mutable/MutableToFooSimpleNoSetters.java | 2 +- .../com/hotels/beans/sample/mutable/MutableToFooSubClass.java | 2 +- .../hotels/beans/sample/mutable/MutableToFooWithBuilder.java | 2 +- .../mutable/MutableToFooWithBuilderMultipleConstructor.java | 2 +- .../beans/sample/mutable/MutableToFooWithWrongBuilder.java | 2 +- .../java/com/hotels/beans/sample/mutable/MutableToSubFoo.java | 2 +- .../java/com/hotels/beans/sample/mutable/package-info.java | 2 +- .../src/test/java/com/hotels/beans/sample/package-info.java | 2 +- .../java/com/hotels/transformer/AbstractTransformerTest.java | 2 +- .../test/java/com/hotels/transformer/base/DefaultsTest.java | 2 +- .../test/java/com/hotels/transformer/base/package-info.java | 2 +- .../com/hotels/transformer/cache/CacheManagerFactoryTest.java | 2 +- .../java/com/hotels/transformer/cache/CacheManagerTest.java | 2 +- .../test/java/com/hotels/transformer/cache/package-info.java | 2 +- .../src/test/java/com/hotels/transformer/package-info.java | 2 +- .../test/java/com/hotels/transformer/utils/package-info.java | 2 +- .../java/com/hotels/transformer/validator/ValidatorTest.java | 2 +- .../java/com/hotels/transformer/validator/package-info.java | 2 +- .../src/main/java/com/hotels/beans/conversion/Converter.java | 2 +- .../main/java/com/hotels/beans/conversion/ConverterImpl.java | 2 +- .../hotels/beans/conversion/analyzer/ConversionAnalyzer.java | 2 +- .../com/hotels/beans/conversion/analyzer/package-info.java | 4 ++-- .../beans/conversion/error/TypeConversionException.java | 2 +- .../java/com/hotels/beans/conversion/error/package-info.java | 4 ++-- .../main/java/com/hotels/beans/conversion/package-info.java | 4 ++-- .../beans/conversion/processor/ConversionProcessor.java | 2 +- .../conversion/processor/ConversionProcessorFactory.java | 2 +- .../processor/impl/BigDecimalConversionProcessor.java | 2 +- .../processor/impl/BigIntegerConversionProcessor.java | 2 +- .../conversion/processor/impl/BooleanConversionProcessor.java | 2 +- .../processor/impl/ByteArrayConversionProcessor.java | 2 +- .../conversion/processor/impl/ByteConversionProcessor.java | 2 +- .../processor/impl/CharacterConversionProcessor.java | 2 +- .../conversion/processor/impl/DoubleConversionProcessor.java | 2 +- .../conversion/processor/impl/FloatConversionProcessor.java | 2 +- .../conversion/processor/impl/IntegerConversionProcessor.java | 2 +- .../conversion/processor/impl/LongConversionProcessor.java | 2 +- .../conversion/processor/impl/ShortConversionProcessor.java | 2 +- .../conversion/processor/impl/StringConversionProcessor.java | 2 +- .../hotels/beans/conversion/processor/impl/package-info.java | 4 ++-- .../com/hotels/beans/conversion/processor/package-info.java | 4 ++-- .../com/hotels/beans/conversion/AbstractConversionTest.java | 2 +- .../test/java/com/hotels/beans/conversion/ConverterTest.java | 2 +- .../beans/conversion/analyzer/ConversionAnalyzerTest.java | 2 +- .../com/hotels/beans/conversion/analyzer/package-info.java | 4 ++-- .../test/java/com/hotels/beans/conversion/package-info.java | 4 ++-- .../conversion/processor/ConversionProcessorFactoryTest.java | 2 +- .../conversion/processor/impl/BigDecimalConversionTest.java | 2 +- .../conversion/processor/impl/BigIntegerConversionTest.java | 2 +- .../conversion/processor/impl/BooleanConversionTest.java | 2 +- .../conversion/processor/impl/ByteArrayConversionTest.java | 2 +- .../beans/conversion/processor/impl/ByteConversionTest.java | 2 +- .../conversion/processor/impl/CharacterConversionTest.java | 2 +- .../beans/conversion/processor/impl/DoubleConversionTest.java | 2 +- .../beans/conversion/processor/impl/FloatConversionTest.java | 2 +- .../conversion/processor/impl/IntegerConversionTest.java | 2 +- .../beans/conversion/processor/impl/LongConversionTest.java | 2 +- .../beans/conversion/processor/impl/ShortConversionTest.java | 2 +- .../beans/conversion/processor/impl/StringConversionTest.java | 2 +- .../hotels/beans/conversion/processor/impl/package-info.java | 4 ++-- .../com/hotels/beans/conversion/processor/package-info.java | 4 ++-- .../src/main/java/com/hotels/map/MapUtils.java | 2 +- .../src/main/java/com/hotels/map/package-info.java | 2 +- .../com/hotels/map/transformer/AbstractMapTransformer.java | 2 +- .../main/java/com/hotels/map/transformer/MapTransformer.java | 2 +- .../java/com/hotels/map/transformer/MapTransformerImpl.java | 2 +- .../hotels/map/transformer/model/MapTransformerSettings.java | 2 +- .../java/com/hotels/map/transformer/model/package-info.java | 2 +- .../main/java/com/hotels/map/transformer/package-info.java | 2 +- .../src/test/java/com/hotels/map/MapUtilsTest.java | 2 +- .../src/test/java/com/hotels/map/package-info.java | 2 +- .../java/com/hotels/map/transformer/MapTransformerTest.java | 2 +- .../test/java/com/hotels/map/transformer/package-info.java | 2 +- 181 files changed, 190 insertions(+), 190 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java index 52644b9de..1b1e91de5 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java index c7c2d386a..078358878 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index f0d7cc5e6..da7628473 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index 842bf8247..7f8de6675 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java index 2384c45fd..167ee9425 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java index f3ab5bbab..8c6831a5a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index 1c7a37c17..41f92e083 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java index d4561687b..5fa7b3f9a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java index f5fa41be5..02f3b4f96 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java index 945a99b9e..79c16659a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java index 7b7702130..10d844d40 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index 0ce51d879..d746a27fb 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java index a0504eb73..511fb57d3 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java index b7ca066ad..b51459478 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java index 6bd167ddb..295f62dc8 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java index 03825280f..b491f1ff6 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java index 794d6d216..38f70be95 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 3584f8d80..0eeda4ae9 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index a30c3bc22..a5b4f6e71 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java index 945a99b9e..79c16659a 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index f1f211359..adbfcda47 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index b2a928b3d..79367e868 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 2ce02da02..383a8e590 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index bdf463efa..c2654497e 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 240020fb6..cce7d09e8 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java index a0504eb73..511fb57d3 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java index 22d94a018..eafb58cb0 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/Transformer.java b/bull-common/src/main/java/com/hotels/transformer/Transformer.java index de9542003..004b1b533 100644 --- a/bull-common/src/main/java/com/hotels/transformer/Transformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/Transformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java b/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java index 9372ce0ca..22e13bbee 100644 --- a/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java +++ b/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java b/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java index 3c4a87009..947308d3b 100644 --- a/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java index 6cf3da3f4..21e70faf1 100644 --- a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java +++ b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/base/package-info.java b/bull-common/src/main/java/com/hotels/transformer/base/package-info.java index 94b343d58..931b36920 100644 --- a/bull-common/src/main/java/com/hotels/transformer/base/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/base/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java index a8321498a..06c9b32f9 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java index 7970ca06a..5c1549e18 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java b/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java index 2f290c7f6..80273558c 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java b/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java index 66630b30a..8474c0bc9 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java index 3b9a3bb94..9820956e2 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java b/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java index cc771f697..5770303e8 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java b/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java index 3f3d951a1..7f91098c5 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java b/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java index 4ac5d25de..851addde5 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java b/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java index 748223b52..aa8584ebf 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java index 06af95436..1fc6e58e0 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java b/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java index 29ab885c1..7619cfde5 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java b/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java index 071031a9d..9d1e547f0 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java b/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java index 6ea0920be..24233179c 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/package-info.java b/bull-common/src/main/java/com/hotels/transformer/error/package-info.java index c8c4873b2..8d62fe251 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java b/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java index 623616680..e9f05bb88 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java index e184f1ff5..f608f17dc 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java index 60c99e48c..95916c714 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java b/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java index 260f65cee..3611d82b7 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java b/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java index 24c840649..8a37cbbb5 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/MapType.java b/bull-common/src/main/java/com/hotels/transformer/model/MapType.java index 17bfd5df3..f5fa1eeca 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/MapType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/MapType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java index d65b2148b..db6400529 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/package-info.java b/bull-common/src/main/java/com/hotels/transformer/model/package-info.java index bb57e9520..61b2861f7 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/package-info.java b/bull-common/src/main/java/com/hotels/transformer/package-info.java index efcfedebd..5619e1280 100644 --- a/bull-common/src/main/java/com/hotels/transformer/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index e89f434a5..84751f5ab 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index bcfe1b5d2..1295931b8 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java b/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java index 057676c91..9be80f50a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java b/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java index 2c5760897..a2041738f 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java index bb90296a5..79dec5935 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java b/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java index 513e26ce4..f5265310e 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/package-info.java b/bull-common/src/test/java/com/hotels/beans/package-info.java index f646495a7..a6f258ad3 100644 --- a/bull-common/src/test/java/com/hotels/beans/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java b/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java index f154f18bf..0c113a742 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java index 079a177ef..a69fe8f3f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java index 8948d2265..9f93abca4 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java index 658a2d36f..97ed9121e 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java index b08f1075e..9c6bec1d5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java index 6a4e20cd6..e95cae482 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java index 7c3d909f6..cccefec85 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java index 539ea28de..4523d70cf 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java index a16758782..fd1d8b98a 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java index 82bac3b73..ca6bcbeb0 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java index ffbe5da7e..508d6651b 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java index 8dd181e90..8ff5e789f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java index 7abe8ae5c..e90fa860c 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java index 4f54a9456..4277c9eb7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java index cee257eed..51a7f93ed 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java index 0b159d25a..4acf687d7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java index aa9ae97f1..4fee78c0b 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java index bb7abd95e..2d90dcdc9 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java index a8f2ea074..456b68848 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java index 15a5b490f..c4f718ffa 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java index 9fd50a3d2..ea83919c8 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java index 8d368dbef..f1781ef29 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java index 6c25658ef..f5022eef0 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java index abd518a5b..e4066eba4 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java index ceba62576..2ad53a202 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java index 255020e76..9ef6281f0 100755 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java index e65e099cb..cab7f63e9 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java index 7eb0bf095..b18620391 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java index 1c1f4a3ab..d236ed7a2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java index ea981dfac..4d01722c4 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java index 16cbe580a..c177cd51f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java index 0ce9e79eb..d1459b0c6 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java index 18ab6781c..329d571e7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java index 89ab89ee2..2ca4bd97d 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java index 276c31e92..d774cbc0c 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java index add9e1d87..ca78cbc1c 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java index 481bee0c2..1feabdf0e 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java index 778d7505d..84ff98f9d 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java index 699b68b42..0eef23564 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java index e3207dfdf..a305f17a5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java index c828112d9..3d8f3a40f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java index 00fdde8cf..b4ab32e9a 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java index 4c019e5fb..8e8fca0b8 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java index 17b6e18a8..7a332a711 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java index 7f226b032..6a42ca692 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java index 3fc333993..42eaf39c5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java index 137932f3e..2c46cd585 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java index 5b9966b26..5b25c5337 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java index e553729d0..f341bff68 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java index 32d18dd5f..8fb735f4f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java index 8a9697b86..0639e538d 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java index ef3f5f2c7..46a808594 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java index ed3d8a767..0738d9d76 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/package-info.java index e76dc196c..01bc755c7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java index 57daa0252..6d98645aa 100644 --- a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java b/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java index 9b405c9bf..c16966da3 100644 --- a/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/base/package-info.java b/bull-common/src/test/java/com/hotels/transformer/base/package-info.java index ca5ee29a2..7ae3c6cc3 100644 --- a/bull-common/src/test/java/com/hotels/transformer/base/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/base/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java index 53299ee42..6b8a604af 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java index 30b8bc159..05329e344 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java b/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java index 2f290c7f6..80273558c 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/package-info.java b/bull-common/src/test/java/com/hotels/transformer/package-info.java index 1a72b9c3c..b44ccaf6b 100644 --- a/bull-common/src/test/java/com/hotels/transformer/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java b/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java index 057676c91..9be80f50a 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java index e7e47adb3..6981186f6 100644 --- a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java b/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java index 44d4949e6..31716ce2b 100644 --- a/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java index 9c611f0e8..80b1a664e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java index 3f4ac6928..987b6be3a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index a6115a047..103915f67 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java index 8b2342dd0..8f9fd9119 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * Type conversion Analyzer package. */ + package com.hotels.beans.conversion.analyzer; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java b/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java index a6194e7af..d9a202671 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java index d6ff4a2b4..af594889f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * Converter module exceptions. */ + package com.hotels.beans.conversion.error; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java index b6726e972..a2b31371e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * Type Conversion package. */ + package com.hotels.beans.conversion; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index 62d733172..036216bac 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index a665d37df..3ae7b18c3 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java index 8065d86f9..8d93d7351 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java index c9a7566ad..c9dea45ef 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java index adc7b3f18..f3576c318 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java index 22eb0bb8a..348c9e327 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index c81616dc0..070a1dfce 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java index 0da7d3a71..3a6df995b 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index 868cb9b0e..b7ee49fee 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index b1a823eb1..10304f5aa 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index f217006e7..476fb20d1 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index 0bc6b1852..ec88c40a4 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index 85c794114..123d65d3c 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index 324dec229..def1c0be2 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java index 9da8ca013..ded39b1d4 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * Implementations of processors package. */ + package com.hotels.beans.conversion.processor.impl; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java index 91ac162d6..76f67d75a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * Type conversion processor package. */ + package com.hotels.beans.conversion.processor; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java index 1b1df558a..90959fb60 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 61ec835ee..94357973a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index e742d26b5..5a8c6c980 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java index 044f6e582..39e791365 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * Type conversion Analyzer test package. */ + package com.hotels.beans.conversion.analyzer; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java index 74444884f..abb4d8345 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * Type conversion test package. */ + package com.hotels.beans.conversion; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index 6e9d9b49d..6c0d25104 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java index dd114fd37..a90033619 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java index 9e3c46e74..2f546ab44 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java index ce41568d4..78dff83fb 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java index 249ea6563..8a4600c43 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java index dadcf255a..da5a814e6 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java index d2b4dbd76..0e06c79d4 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index a8553dafd..12156e3bb 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 6f2c30d10..0339345ff 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index f84c8aec3..4c4c7756a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java index 0bf97dfbe..d57453682 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java index fb6b8837a..0403c88b5 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java index f0ed37fd2..9210c63e1 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java index 42cd3c107..0c6c9049c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * Type conversion processor implementation test package. */ + package com.hotels.beans.conversion.processor.impl; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java index 054fea76b..55102888d 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * Type conversion processor test package. */ + package com.hotels.beans.conversion.processor; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java b/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java index 945275eb8..f361f3ed1 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/package-info.java b/bull-map-transformer/src/main/java/com/hotels/map/package-info.java index 2dee85091..1425f5054 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/package-info.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index 0a2c688d2..c725c45bf 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index 3b3bb418a..c40a13994 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index 0130b5a32..66b97ee5d 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java index c06df6e11..5992de672 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java index ebb2ea61f..f9f3256b8 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java index 95a85b18d..6a280210a 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java index c846096be..82e6d2f09 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/test/java/com/hotels/map/package-info.java b/bull-map-transformer/src/test/java/com/hotels/map/package-info.java index 5cbabf1b4..3af4e0341 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/package-info.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 7241b1d9f..487b8d0fa 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java index 95a85b18d..6a280210a 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 9da0d995838ddcde08c4030f0ea03647b4948a83 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 24 Feb 2021 06:50:03 +0000 Subject: [PATCH 1283/1786] Bump wagon-ssh from 3.4.2 to 3.4.3 Bumps wagon-ssh from 3.4.2 to 3.4.3. Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5e6e141c9..25c98b386 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ 2.3.1 - 3.4.2 + 3.4.3 0.12 github 3.9.1 From 9ddcfb2df94f1a154476a8afb7b815b8e1ebbf40 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 24 Feb 2021 09:14:45 +0000 Subject: [PATCH 1284/1786] Bump mockito-core from 3.7.7 to 3.8.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.7.7 to 3.8.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.7.7...v3.8.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 25c98b386..eeb73cf14 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.11 1.3.0 - 3.7.7 + 3.8.0 7.3.0 3.19.0 From cfdb8c9e98250b45558736f59abce86d078ad2e0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 1 Mar 2021 02:16:58 +0000 Subject: [PATCH 1285/1786] Bump testng from 7.3.0 to 7.4.0 Bumps [testng](https://github.com/cbeust/testng) from 7.3.0 to 7.4.0. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/compare/7.3.0...7.4.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eeb73cf14..80dcf86ee 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 1.3.0 3.8.0 - 7.3.0 + 7.4.0 3.19.0 2.0.1.Final From d75b93a44d0ed29b469fc17320b3df0c49e211c6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 2 Mar 2021 02:16:46 +0000 Subject: [PATCH 1286/1786] Bump commons-lang3 from 3.11 to 3.12.0 Bumps commons-lang3 from 3.11 to 3.12.0. Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 80dcf86ee..55563bcf9 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ ${jdk.version} ${jdk.version} 1.18.18 - 3.11 + 3.12.0 1.3.0 3.8.0 From f0d2429a0db23016967c66500ea0d3805a167bee Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 25 Mar 2021 11:28:15 +0100 Subject: [PATCH 1287/1786] Fixes the issue with the dependency update profile --- README.md | 19 ++++++++++++++++++- pom.xml | 23 ++--------------------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 576737047..e82e7ed6c 100644 --- a/README.md +++ b/README.md @@ -89,23 +89,40 @@ On top of that, it's suggested to configure the `maven-compiler-plugin`, inside ## Maven build Full build + ```shell script ./mvnw clean install ``` or on Windows + ```shell script mvnw.cmd clean install ``` -Skip test coverage and checkstyle check +### Skip test coverage and checkstyle check + ```shell script ./mvnw clean install -P relaxed ``` + or on Windows + ```shell script mvnw.cmd clean install -P relaxed ``` +### Check for dependencies update + +``` +mvn versions:display-dependency-updates -P check-for-updates +``` + +or on Windows + +```shell script +mvnw.cmd versions:display-dependency-updates -P check-for-updates +``` + ## Features: * support copy of immutable beans. * support copy of mutable beans. diff --git a/pom.xml b/pom.xml index 55563bcf9..f4504cf0c 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,7 @@ bull-common bull-bean-transformer + bull-map-transformer bull-converter bull-report bull-bom @@ -188,21 +189,6 @@ - - default - - true - - - bull-map-transformer - - - - map-transformer - - bull-map-transformer - - relaxed @@ -213,9 +199,6 @@ fast - - bull-map-transformer - true false @@ -265,9 +248,6 @@ true - - bull-map-transformer - @@ -610,6 +590,7 @@ org.codehaus.mojo versions-maven-plugin ${maven.versions.plugin.version} + false file:///${project.basedir}/config/maven/versions-plugin-rules.xml From 962e2283f729a5a1f056362631daa20dc7e2b75a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 2 Apr 2021 02:16:54 +0000 Subject: [PATCH 1288/1786] Bump lombok from 1.18.18 to 1.18.20 Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.18.18 to 1.18.20. - [Release notes](https://github.com/rzwitserloot/lombok/releases) - [Changelog](https://github.com/rzwitserloot/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/rzwitserloot/lombok/compare/v1.18.18...v1.18.20) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f4504cf0c..6873398f0 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ 1.8 ${jdk.version} ${jdk.version} - 1.18.18 + 1.18.20 3.12.0 1.3.0 From 14369002b2b481053382bd67a53ad502b478adfc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 8 Apr 2021 02:15:58 +0000 Subject: [PATCH 1289/1786] Bump mockito-core from 3.8.0 to 3.9.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.8.0 to 3.9.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.8.0...v3.9.0) Signed-off-by: dependabot-preview[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6873398f0..985404ba2 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.12.0 1.3.0 - 3.8.0 + 3.9.0 7.4.0 3.19.0 From 9c82dcb792d548d48bcd41a1fefc00a5f666de25 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 8 Apr 2021 10:29:26 +0200 Subject: [PATCH 1290/1786] Removes the empty line between the package definition and the copyrights --- .../src/main/java/com/hotels/beans/BeanUtils.java | 1 - .../src/main/java/com/hotels/beans/package-info.java | 1 - .../java/com/hotels/beans/populator/ArrayPopulator.java | 1 - .../com/hotels/beans/populator/CollectionPopulator.java | 1 - .../com/hotels/beans/populator/ICollectionPopulator.java | 1 - .../java/com/hotels/beans/populator/MapPopulator.java | 1 - .../com/hotels/beans/populator/OptionalPopulator.java | 1 - .../main/java/com/hotels/beans/populator/Populator.java | 1 - .../com/hotels/beans/populator/PopulatorFactory.java | 1 - .../java/com/hotels/beans/populator/package-info.java | 1 - .../beans/transformer/AbstractBeanTransformer.java | 1 - .../com/hotels/beans/transformer/BeanTransformer.java | 1 - .../com/hotels/beans/transformer/TransformerImpl.java | 3 +-- .../java/com/hotels/beans/transformer/package-info.java | 1 - .../src/test/java/com/hotels/beans/BeanUtilsTest.java | 1 - .../src/test/java/com/hotels/beans/package-info.java | 1 - .../com/hotels/beans/performance/PerformanceTest.java | 1 - .../java/com/hotels/beans/performance/package-info.java | 1 - .../com/hotels/beans/populator/ArrayPopulatorTest.java | 1 - .../com/hotels/beans/populator/PopulatorFactoryTest.java | 1 - .../java/com/hotels/beans/populator/package-info.java | 1 - .../beans/transformer/AbstractBeanTransformerTest.java | 1 - .../hotels/beans/transformer/BeanTransformerTest.java | 1 - .../transformer/BuilderObjectTransformationTest.java | 1 - .../transformer/ImmutableObjectTransformationTest.java | 3 +-- .../beans/transformer/MixedObjectTransformationTest.java | 1 - .../transformer/MutableObjectTransformationTest.java | 1 - .../java/com/hotels/beans/transformer/package-info.java | 1 - .../java/com/hotels/transformer/AbstractTransformer.java | 1 - .../main/java/com/hotels/transformer/Transformer.java | 1 - .../hotels/transformer/annotation/ConstructorArg.java | 1 - .../com/hotels/transformer/annotation/package-info.java | 1 - .../main/java/com/hotels/transformer/base/Defaults.java | 1 - .../java/com/hotels/transformer/base/package-info.java | 1 - .../java/com/hotels/transformer/cache/CacheManager.java | 1 - .../hotels/transformer/cache/CacheManagerFactory.java | 1 - .../java/com/hotels/transformer/cache/package-info.java | 1 - .../java/com/hotels/transformer/constant/ClassType.java | 1 - .../java/com/hotels/transformer/constant/Filters.java | 1 - .../com/hotels/transformer/constant/MethodPrefix.java | 1 - .../com/hotels/transformer/constant/Punctuation.java | 1 - .../com/hotels/transformer/constant/package-info.java | 1 - .../transformer/error/InstanceCreationException.java | 1 - .../hotels/transformer/error/InvalidBeanException.java | 1 - .../transformer/error/InvalidFunctionException.java | 1 - .../hotels/transformer/error/MissingFieldException.java | 1 - .../hotels/transformer/error/MissingMethodException.java | 1 - .../java/com/hotels/transformer/error/package-info.java | 1 - .../java/com/hotels/transformer/model/EmptyValue.java | 1 - .../java/com/hotels/transformer/model/FieldMapping.java | 1 - .../com/hotels/transformer/model/FieldTransformer.java | 1 - .../main/java/com/hotels/transformer/model/ItemType.java | 1 - .../java/com/hotels/transformer/model/MapElemType.java | 1 - .../main/java/com/hotels/transformer/model/MapType.java | 1 - .../hotels/transformer/model/TransformerSettings.java | 1 - .../java/com/hotels/transformer/model/package-info.java | 1 - .../main/java/com/hotels/transformer/package-info.java | 1 - .../java/com/hotels/transformer/utils/ClassUtils.java | 1 - .../com/hotels/transformer/utils/ReflectionUtils.java | 1 - .../java/com/hotels/transformer/utils/package-info.java | 1 - .../java/com/hotels/transformer/validator/Validator.java | 1 - .../com/hotels/transformer/validator/ValidatorImpl.java | 1 - .../com/hotels/transformer/validator/package-info.java | 1 - .../src/test/java/com/hotels/beans/package-info.java | 1 - .../test/java/com/hotels/beans/sample/AbstractClass.java | 1 - .../src/test/java/com/hotels/beans/sample/FromFoo.java | 1 - .../java/com/hotels/beans/sample/FromFooAdvFields.java | 1 - .../test/java/com/hotels/beans/sample/FromFooMap.java | 1 - .../java/com/hotels/beans/sample/FromFooNoField.java | 1 - .../hotels/beans/sample/FromFooOnlyPrimitiveTypes.java | 1 - .../test/java/com/hotels/beans/sample/FromFooSimple.java | 1 - .../hotels/beans/sample/FromFooSimpleBooleanField.java | 1 - .../com/hotels/beans/sample/FromFooSimpleNoGetters.java | 1 - .../java/com/hotels/beans/sample/FromFooSubClass.java | 1 - .../hotels/beans/sample/FromFooWithPrimitiveFields.java | 1 - .../test/java/com/hotels/beans/sample/FromSubFoo.java | 1 - .../src/test/java/com/hotels/beans/sample/ISubClass.java | 1 - .../beans/sample/immutable/ImmutableFlatToFoo.java | 1 - .../hotels/beans/sample/immutable/ImmutableToFoo.java | 1 - .../beans/sample/immutable/ImmutableToFooAdvFields.java | 1 - .../sample/immutable/ImmutableToFooCustomAnnotation.java | 1 - .../beans/sample/immutable/ImmutableToFooDiffFields.java | 1 - .../sample/immutable/ImmutableToFooDiffTypesFields.java | 1 - .../hotels/beans/sample/immutable/ImmutableToFooMap.java | 1 - .../immutable/ImmutableToFooMissingCustomAnnotation.java | 1 - .../sample/immutable/ImmutableToFooNoConstructors.java | 1 - .../immutable/ImmutableToFooNotExistingFields.java | 1 - .../beans/sample/immutable/ImmutableToFooSimple.java | 1 - .../sample/immutable/ImmutableToFooSimpleBoolean.java | 1 - .../sample/immutable/ImmutableToFooSimpleWrongTypes.java | 1 - .../beans/sample/immutable/ImmutableToFooSubClass.java | 1 - .../sample/immutable/ImmutableToFooWithBuilder.java | 1 - .../hotels/beans/sample/immutable/ImmutableToSubFoo.java | 1 - .../immutable/ImmutableToSubFooCustomAnnotation.java | 1 - .../com/hotels/beans/sample/immutable/package-info.java | 1 - .../java/com/hotels/beans/sample/mixed/MixedToFoo.java | 1 - .../hotels/beans/sample/mixed/MixedToFooDiffFields.java | 1 - .../mixed/MixedToFooMissingAllArgsConstructor.java | 1 - .../beans/sample/mixed/MixedToFooMissingConstructor.java | 1 - .../beans/sample/mixed/MixedToFooMissingField.java | 1 - .../beans/sample/mixed/MixedToFooNotExistingFields.java | 1 - .../hotels/beans/sample/mixed/MixedToFooStaticField.java | 1 - .../hotels/beans/sample/mixed/MixedToFooWithBuilder.java | 1 - .../sample/mixed/MutableToFooOnlyPrimitiveTypes.java | 1 - .../java/com/hotels/beans/sample/mixed/package-info.java | 1 - .../com/hotels/beans/sample/mutable/MutableToFoo.java | 1 - .../beans/sample/mutable/MutableToFooAdvFields.java | 1 - .../hotels/beans/sample/mutable/MutableToFooInvalid.java | 1 - .../sample/mutable/MutableToFooNotExistingFields.java | 1 - .../hotels/beans/sample/mutable/MutableToFooSimple.java | 1 - .../sample/mutable/MutableToFooSimpleNoSetters.java | 1 - .../beans/sample/mutable/MutableToFooSubClass.java | 1 - .../beans/sample/mutable/MutableToFooWithBuilder.java | 1 - .../MutableToFooWithBuilderMultipleConstructor.java | 1 - .../sample/mutable/MutableToFooWithWrongBuilder.java | 1 - .../com/hotels/beans/sample/mutable/MutableToSubFoo.java | 1 - .../com/hotels/beans/sample/mutable/package-info.java | 1 - .../test/java/com/hotels/beans/sample/package-info.java | 1 - .../com/hotels/transformer/AbstractTransformerTest.java | 1 - .../java/com/hotels/transformer/base/DefaultsTest.java | 1 - .../java/com/hotels/transformer/base/package-info.java | 1 - .../transformer/cache/CacheManagerFactoryTest.java | 1 - .../com/hotels/transformer/cache/CacheManagerTest.java | 1 - .../java/com/hotels/transformer/cache/package-info.java | 1 - .../test/java/com/hotels/transformer/package-info.java | 1 - .../com/hotels/transformer/utils/ClassUtilsTest.java | 3 +-- .../hotels/transformer/utils/ReflectionUtilsTest.java | 3 +-- .../java/com/hotels/transformer/utils/package-info.java | 1 - .../com/hotels/transformer/validator/ValidatorTest.java | 1 - .../com/hotels/transformer/validator/package-info.java | 1 - .../main/java/com/hotels/beans/conversion/Converter.java | 1 - .../java/com/hotels/beans/conversion/ConverterImpl.java | 1 - .../beans/conversion/analyzer/ConversionAnalyzer.java | 1 - .../hotels/beans/conversion/analyzer/package-info.java | 1 - .../beans/conversion/error/TypeConversionException.java | 1 - .../com/hotels/beans/conversion/error/package-info.java | 1 - .../java/com/hotels/beans/conversion/package-info.java | 1 - .../beans/conversion/processor/ConversionProcessor.java | 1 - .../conversion/processor/ConversionProcessorFactory.java | 1 - .../processor/impl/BigDecimalConversionProcessor.java | 1 - .../processor/impl/BigIntegerConversionProcessor.java | 1 - .../processor/impl/BooleanConversionProcessor.java | 1 - .../processor/impl/ByteArrayConversionProcessor.java | 1 - .../processor/impl/ByteConversionProcessor.java | 1 - .../processor/impl/CharacterConversionProcessor.java | 1 - .../processor/impl/DoubleConversionProcessor.java | 1 - .../processor/impl/FloatConversionProcessor.java | 1 - .../processor/impl/IntegerConversionProcessor.java | 1 - .../processor/impl/LongConversionProcessor.java | 1 - .../processor/impl/ShortConversionProcessor.java | 1 - .../processor/impl/StringConversionProcessor.java | 1 - .../beans/conversion/processor/impl/package-info.java | 1 - .../hotels/beans/conversion/processor/package-info.java | 1 - .../hotels/beans/conversion/AbstractConversionTest.java | 1 - .../java/com/hotels/beans/conversion/ConverterTest.java | 1 - .../conversion/analyzer/ConversionAnalyzerTest.java | 1 - .../hotels/beans/conversion/analyzer/package-info.java | 1 - .../java/com/hotels/beans/conversion/package-info.java | 1 - .../processor/ConversionProcessorFactoryTest.java | 1 - .../processor/impl/BigDecimalConversionTest.java | 1 - .../processor/impl/BigIntegerConversionTest.java | 1 - .../conversion/processor/impl/BooleanConversionTest.java | 1 - .../processor/impl/ByteArrayConversionTest.java | 1 - .../conversion/processor/impl/ByteConversionTest.java | 1 - .../processor/impl/CharacterConversionTest.java | 1 - .../conversion/processor/impl/DoubleConversionTest.java | 1 - .../conversion/processor/impl/FloatConversionTest.java | 1 - .../conversion/processor/impl/IntegerConversionTest.java | 1 - .../conversion/processor/impl/LongConversionTest.java | 1 - .../conversion/processor/impl/ShortConversionTest.java | 1 - .../conversion/processor/impl/StringConversionTest.java | 1 - .../beans/conversion/processor/impl/package-info.java | 1 - .../hotels/beans/conversion/processor/package-info.java | 1 - .../src/main/java/com/hotels/map/MapUtils.java | 1 - .../src/main/java/com/hotels/map/package-info.java | 1 - .../hotels/map/transformer/AbstractMapTransformer.java | 1 - .../java/com/hotels/map/transformer/MapTransformer.java | 1 - .../com/hotels/map/transformer/MapTransformerImpl.java | 1 - .../map/transformer/model/MapTransformerSettings.java | 1 - .../com/hotels/map/transformer/model/package-info.java | 1 - .../java/com/hotels/map/transformer/package-info.java | 1 - .../src/test/java/com/hotels/map/MapUtilsTest.java | 1 - .../src/test/java/com/hotels/map/package-info.java | 1 - .../com/hotels/map/transformer/MapTransformerTest.java | 1 - .../java/com/hotels/map/transformer/package-info.java | 1 - config/checkstyle/rules.xml | 2 +- pom.xml | 9 +++++++++ 187 files changed, 14 insertions(+), 190 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java index 1b1e91de5..f414391a4 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans; import static com.hotels.transformer.validator.Validator.notNull; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java index 078358878..fd4196d47 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java @@ -16,5 +16,4 @@ /** * Bean transformer main package. */ - package com.hotels.beans; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java index da7628473..9e39e3c88 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.populator; import static java.util.Arrays.stream; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java index 7f8de6675..29f6d66f6 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.populator; import static java.util.Objects.isNull; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java index 167ee9425..3d0164a30 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.populator; /** diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java index 8c6831a5a..a2604e1f6 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.populator; import static java.util.stream.Collectors.toMap; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index 41f92e083..89003a2d9 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.populator; import static java.util.Optional.ofNullable; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java index 5fa7b3f9a..5e02e5e41 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.populator; import static com.hotels.beans.populator.PopulatorFactory.getPopulator; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java index 02f3b4f96..1f0f3a08e 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.populator; import static java.util.Optional.empty; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java index 79c16659a..ac5c3a4c8 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java @@ -16,5 +16,4 @@ /** * Populator objects package. */ - package com.hotels.beans.populator; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java index 10d844d40..303d7aa09 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.transformer; import static java.util.Arrays.asList; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java index d746a27fb..64effed6b 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.transformer; import com.hotels.transformer.Transformer; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 01b817682..632887e9b 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.transformer; import static java.util.Arrays.stream; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java index 511fb57d3..dec4cd967 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java @@ -16,5 +16,4 @@ /** * Bean transformer package. */ - package com.hotels.beans.transformer; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java index b51459478..26a0288b8 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java index 295f62dc8..0d9a9f245 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java @@ -16,5 +16,4 @@ /** * Test package. */ - package com.hotels.beans; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java index b491f1ff6..1bacb6a6b 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.performance; import static java.lang.String.valueOf; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java index 38f70be95..1500243ac 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java @@ -16,5 +16,4 @@ /** * Performance test package. */ - package com.hotels.beans.performance; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 0eeda4ae9..27404c0d8 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.populator; import static java.lang.Boolean.FALSE; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java index a5b4f6e71..658ad838f 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.populator; import static java.util.Objects.nonNull; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java index 79c16659a..ac5c3a4c8 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java @@ -16,5 +16,4 @@ /** * Populator objects package. */ - package com.hotels.beans.populator; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java index adbfcda47..ddfbd4869 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.transformer; import static org.mockito.MockitoAnnotations.openMocks; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 79367e868..8da5d54f2 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.transformer; import static java.math.BigInteger.ZERO; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 383a8e590..29d2e13d7 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.transformer; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 663531854..8c76ed26f 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.transformer; import static java.lang.String.format; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index c2654497e..b6f03035e 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.transformer; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index cce7d09e8..fb8b0f427 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.transformer; import static java.lang.Integer.parseInt; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java index 511fb57d3..dec4cd967 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java @@ -16,5 +16,4 @@ /** * Bean transformer package. */ - package com.hotels.beans.transformer; diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java index eafb58cb0..e4bb79172 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer; import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; diff --git a/bull-common/src/main/java/com/hotels/transformer/Transformer.java b/bull-common/src/main/java/com/hotels/transformer/Transformer.java index 004b1b533..5592e0fec 100644 --- a/bull-common/src/main/java/com/hotels/transformer/Transformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/Transformer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer; import com.hotels.transformer.model.FieldMapping; diff --git a/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java b/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java index 22e13bbee..5a7f2a966 100644 --- a/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java +++ b/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.annotation; import static java.lang.annotation.ElementType.PARAMETER; diff --git a/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java b/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java index 947308d3b..ffe302a5a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java @@ -16,5 +16,4 @@ /** * Annotations package. */ - package com.hotels.transformer.annotation; diff --git a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java index 21e70faf1..d3ec5b895 100644 --- a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java +++ b/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.base; import static java.lang.Boolean.FALSE; diff --git a/bull-common/src/main/java/com/hotels/transformer/base/package-info.java b/bull-common/src/main/java/com/hotels/transformer/base/package-info.java index 931b36920..63f078944 100644 --- a/bull-common/src/main/java/com/hotels/transformer/base/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/base/package-info.java @@ -16,5 +16,4 @@ /** * Base package. */ - package com.hotels.transformer.base; diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java index 06c9b32f9..81c75651a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.cache; import static java.util.Objects.nonNull; diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java index 5c1549e18..146f69b36 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.cache; import static com.hotels.transformer.validator.Validator.notNull; diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java b/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java index 80273558c..7c47a942f 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java @@ -16,5 +16,4 @@ /** * cache package. */ - package com.hotels.transformer.cache; diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java b/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java index 8474c0bc9..050557489 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.constant; /** diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java index 9820956e2..25374ae97 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.constant; import static java.lang.reflect.Modifier.isFinal; diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java b/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java index 5770303e8..cd207e8c7 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.constant; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java b/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java index 7f91098c5..e8b4b3c69 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.constant; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java b/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java index 851addde5..b875d2428 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java @@ -16,5 +16,4 @@ /** * Constants package. */ - package com.hotels.transformer.constant; diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java b/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java index aa8584ebf..e3c71e779 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.error; /** diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java index 1fc6e58e0..00fd6676a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.error; /** diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java b/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java index 7619cfde5..62f27796d 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.error; /** diff --git a/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java b/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java index 9d1e547f0..b9488d37a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.error; /** diff --git a/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java b/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java index 24233179c..1d6026dbd 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.error; /** diff --git a/bull-common/src/main/java/com/hotels/transformer/error/package-info.java b/bull-common/src/main/java/com/hotels/transformer/error/package-info.java index 8d62fe251..064791726 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/error/package-info.java @@ -16,5 +16,4 @@ /** * Exceptions package. */ - package com.hotels.transformer.error; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java b/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java index e9f05bb88..66c2ae32c 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.model; /** diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java index f608f17dc..1b2a8964b 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.model; import lombok.AllArgsConstructor; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java index 95916c714..037b05c53 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.model; import static java.util.Objects.nonNull; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java b/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java index 3611d82b7..4f7edc244 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.model; import lombok.Builder; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java b/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java index 8a37cbbb5..7addc2465 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.model; /** diff --git a/bull-common/src/main/java/com/hotels/transformer/model/MapType.java b/bull-common/src/main/java/com/hotels/transformer/model/MapType.java index f5fa1eeca..cf71b302f 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/MapType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/MapType.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.model; import lombok.AllArgsConstructor; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java index db6400529..f146e0bf0 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.model; import java.util.HashSet; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/package-info.java b/bull-common/src/main/java/com/hotels/transformer/model/package-info.java index 61b2861f7..ba9ebc1ed 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/package-info.java @@ -16,5 +16,4 @@ /** * Pojo package. */ - package com.hotels.transformer.model; diff --git a/bull-common/src/main/java/com/hotels/transformer/package-info.java b/bull-common/src/main/java/com/hotels/transformer/package-info.java index 5619e1280..4404a5e40 100644 --- a/bull-common/src/main/java/com/hotels/transformer/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/package-info.java @@ -16,5 +16,4 @@ /** * Transformer package. */ - package com.hotels.transformer; diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index 84751f5ab..fe86ee152 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.utils; import static java.lang.invoke.LambdaMetafactory.metafactory; diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index 1295931b8..a59395dc9 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.utils; import static java.lang.invoke.LambdaMetafactory.metafactory; diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java b/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java index 9be80f50a..ea1de7df2 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java @@ -16,5 +16,4 @@ /** * utilities package. */ - package com.hotels.transformer.utils; diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java b/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java index a2041738f..b0aa41f30 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.validator; import static java.util.Objects.isNull; diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java index 79dec5935..d1e666dbe 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.validator; import static java.util.stream.Collectors.joining; diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java b/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java index f5265310e..a9fcd3d49 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java @@ -16,5 +16,4 @@ /** * validator package. */ - package com.hotels.transformer.validator; diff --git a/bull-common/src/test/java/com/hotels/beans/package-info.java b/bull-common/src/test/java/com/hotels/beans/package-info.java index a6f258ad3..10a91859c 100644 --- a/bull-common/src/test/java/com/hotels/beans/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/package-info.java @@ -16,5 +16,4 @@ /** * Bean test package. */ - package com.hotels.beans; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java b/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java index 0c113a742..4ec294538 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java index a69fe8f3f..eb10ea959 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java index 9f93abca4..4038375be 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import java.util.Collection; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java index 97ed9121e..3370ebae7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java index 9c6bec1d5..c00dc8283 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import static java.lang.Boolean.TRUE; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java index e95cae482..e28560ccd 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import lombok.AllArgsConstructor; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java index cccefec85..0bb877ef1 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java index 4523d70cf..ba7202fb7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import lombok.AllArgsConstructor; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java index fd1d8b98a..2593b7c53 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java index ca6bcbeb0..368631a9e 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import java.math.BigDecimal; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java index 508d6651b..de100cc21 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java index 8ff5e789f..0de1ae6d1 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java index e90fa860c..cad09ce19 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample; /** diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java index 4277c9eb7..add3a1fee 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java index 51a7f93ed..b18cfe2a5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java index 4acf687d7..a489f60cd 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.util.Collection; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java index 4fee78c0b..4bdd820d2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java index 2d90dcdc9..ee9546a90 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java index 456b68848..c7ade2b4a 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java index c4f718ffa..16feda4c9 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java index ea83919c8..4b28734b0 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import jakarta.validation.constraints.NotNull; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java index f1781ef29..015ee0d21 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import lombok.AccessLevel; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java index f5022eef0..a9a276824 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java index e4066eba4..349b161c8 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java index 2ad53a202..8a8836808 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import lombok.AllArgsConstructor; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java index 9ef6281f0..e2d14d828 100755 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import lombok.AllArgsConstructor; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java index cab7f63e9..2a2110ec2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.math.BigDecimal; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java index b18620391..1ea11ae7f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java index d236ed7a2..7df9fff36 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java index 4d01722c4..7b5086781 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.immutable; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java index c177cd51f..1a7e53c33 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java @@ -16,5 +16,4 @@ /** * Immutable Bean package. */ - package com.hotels.beans.sample.immutable; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java index d1459b0c6..a065bba49 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java index 329d571e7..3e44fcd59 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java index 2ca4bd97d..3768a2f0e 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java index d774cbc0c..f5a2c77f5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java index ca78cbc1c..242b0ceb5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java index 1feabdf0e..0bd72c532 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java index 84ff98f9d..123a856f7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mixed; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java index 0eef23564..252bc50e7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java index a305f17a5..cbeb7870b 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mixed; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java index 3d8f3a40f..f97e0572c 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java @@ -16,5 +16,4 @@ /** * Mixed Bean package. */ - package com.hotels.beans.sample.mixed; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java index b4ab32e9a..564062775 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java index 8e8fca0b8..eacce38a7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.util.Collection; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java index 7a332a711..f8ab76fdd 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java index 6a42ca692..9a905a984 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java index 42eaf39c5..61ff4d2a2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java index 2c46cd585..9ca4a4265 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java index 5b25c5337..70fe6847b 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.math.BigDecimal; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java index f341bff68..3e9a99d14 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java index 8fb735f4f..4a1bd26f5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java index 0639e538d..473fe0905 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java index 46a808594..57bb7a002 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.sample.mutable; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java index 0738d9d76..fd4db2b73 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java @@ -16,5 +16,4 @@ /** * Mutable Bean package. */ - package com.hotels.beans.sample.mutable; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/package-info.java b/bull-common/src/test/java/com/hotels/beans/sample/package-info.java index 01bc755c7..b971ff916 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/package-info.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/package-info.java @@ -16,5 +16,4 @@ /** * Sample Bean object for test purpose. */ - package com.hotels.beans.sample; diff --git a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java index 6d98645aa..ddb083284 100644 --- a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer; import static java.util.Arrays.asList; diff --git a/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java b/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java index c16966da3..b77e10216 100644 --- a/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.base; import static java.lang.Boolean.FALSE; diff --git a/bull-common/src/test/java/com/hotels/transformer/base/package-info.java b/bull-common/src/test/java/com/hotels/transformer/base/package-info.java index 7ae3c6cc3..bebd35f18 100644 --- a/bull-common/src/test/java/com/hotels/transformer/base/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/base/package-info.java @@ -16,5 +16,4 @@ /** * Base item package. */ - package com.hotels.transformer.base; diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java index 6b8a604af..753876b78 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.cache; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java index 05329e344..bfe574236 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.cache; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java b/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java index 80273558c..7c47a942f 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java @@ -16,5 +16,4 @@ /** * cache package. */ - package com.hotels.transformer.cache; diff --git a/bull-common/src/test/java/com/hotels/transformer/package-info.java b/bull-common/src/test/java/com/hotels/transformer/package-info.java index b44ccaf6b..7cf32c101 100644 --- a/bull-common/src/test/java/com/hotels/transformer/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/package-info.java @@ -16,5 +16,4 @@ /** * Transformer test package. */ - package com.hotels.transformer; diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java index 2cd2abfcf..fddb05dbe 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.utils; import static java.lang.reflect.Modifier.isFinal; diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 87d4d978d..98ffb7d57 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2020 Expedia, Inc. + * Copyright (C) 2019-2021 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.utils; import static java.math.BigInteger.ONE; diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java b/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java index 9be80f50a..ea1de7df2 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java @@ -16,5 +16,4 @@ /** * utilities package. */ - package com.hotels.transformer.utils; diff --git a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java index 6981186f6..4d21d3aec 100644 --- a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.transformer.validator; import static java.math.BigInteger.ONE; diff --git a/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java b/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java index 31716ce2b..b75b0dee1 100644 --- a/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java +++ b/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java @@ -16,5 +16,4 @@ /** * validator test package. */ - package com.hotels.transformer.validator; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java index 80b1a664e..fae081373 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion; import java.util.Optional; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java index 987b6be3a..bf52709dd 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion; import static java.util.Objects.isNull; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java index 103915f67..ec578143a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.analyzer; import static java.util.Optional.empty; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java index 8f9fd9119..f1dc975b9 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java @@ -16,5 +16,4 @@ /** * Type conversion Analyzer package. */ - package com.hotels.beans.conversion.analyzer; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java b/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java index d9a202671..a918d7319 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.error; /** diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java index af594889f..229077d97 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java @@ -16,5 +16,4 @@ /** * Converter module exceptions. */ - package com.hotels.beans.conversion.error; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java index a2b31371e..080261582 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java @@ -16,5 +16,4 @@ /** * Type Conversion package. */ - package com.hotels.beans.conversion; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java index 036216bac..3162af14d 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor; import java.math.BigDecimal; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java index 3ae7b18c3..bae715b30 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor; import static java.util.Optional.empty; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java index 8d93d7351..cd5aee8cc 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java index c9dea45ef..c1a5f3546 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java index f3576c318..b7e1a7abf 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import java.math.BigDecimal; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java index 348c9e327..06e5a3980 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java index 070a1dfce..42f174fe4 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java index 3a6df995b..423d655ab 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java index b7ee49fee..34b8d6f50 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java index 10304f5aa..7b801ba05 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java index 476fb20d1..41934416f 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java index ec88c40a4..b8f550d08 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java index 123d65d3c..821397fb2 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java index def1c0be2..57a76ce7e 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import java.math.BigDecimal; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java index ded39b1d4..6981783d5 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java @@ -16,5 +16,4 @@ /** * Implementations of processors package. */ - package com.hotels.beans.conversion.processor.impl; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java index 76f67d75a..a8471c2f7 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java +++ b/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java @@ -16,5 +16,4 @@ /** * Type conversion processor package. */ - package com.hotels.beans.conversion.processor; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java index 90959fb60..3e961449b 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion; /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 94357973a..04a62665c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion; import static java.lang.Character.getNumericValue; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java index 5a8c6c980..77891c652 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.analyzer; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java index 39e791365..96aa5bc46 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java @@ -16,5 +16,4 @@ /** * Type conversion Analyzer test package. */ - package com.hotels.beans.conversion.analyzer; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java index abb4d8345..f537bdde8 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java @@ -16,5 +16,4 @@ /** * Type conversion test package. */ - package com.hotels.beans.conversion; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java index 6c0d25104..68d009307 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java index a90033619..bea3cca92 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java index 2f546ab44..63ef0a873 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java index 78dff83fb..5428ccea8 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java index 8a4600c43..5a8256d0f 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java index da5a814e6..c1e8c6c62 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java index 0e06c79d4..8c46c1dc7 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.nio.ByteBuffer.wrap; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java index 12156e3bb..92d1b35fe 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Double.valueOf; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java index 0339345ff..4a75e6714 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Float.valueOf; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java index 4c4c7756a..02f49ec44 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.nio.ByteBuffer.wrap; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java index d57453682..ce2141b54 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.nio.ByteBuffer.wrap; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java index 0403c88b5..1aadb290f 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java index 9210c63e1..423b5c171 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.beans.conversion.processor.impl; import static java.lang.String.valueOf; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java index 0c6c9049c..594861183 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java @@ -16,5 +16,4 @@ /** * Type conversion processor implementation test package. */ - package com.hotels.beans.conversion.processor.impl; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java index 55102888d..2c6cf639d 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java @@ -16,5 +16,4 @@ /** * Type conversion processor test package. */ - package com.hotels.beans.conversion.processor; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java b/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java index f361f3ed1..9880c86b1 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.map; import com.hotels.map.transformer.MapTransformer; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/package-info.java b/bull-map-transformer/src/main/java/com/hotels/map/package-info.java index 1425f5054..fdb860df0 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/package-info.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/package-info.java @@ -16,5 +16,4 @@ /** * Map transformer main package. */ - package com.hotels.map; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java index c725c45bf..9cf8a763b 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.map.transformer; import java.util.Map; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java index c40a13994..82a1e134c 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.map.transformer; import java.util.Map; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java index 66b97ee5d..dbb643906 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.map.transformer; import static java.util.Objects.nonNull; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java index 5992de672..2cf2a4123 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.map.transformer.model; import java.util.Map; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java index f9f3256b8..0dcb26136 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java @@ -16,5 +16,4 @@ /** * Pojo package. */ - package com.hotels.map.transformer.model; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java index 6a280210a..2e87cae99 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java +++ b/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java @@ -16,5 +16,4 @@ /** * Map transformer package. */ - package com.hotels.map.transformer; diff --git a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java index 82e6d2f09..e419da5ea 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.map; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-map-transformer/src/test/java/com/hotels/map/package-info.java b/bull-map-transformer/src/test/java/com/hotels/map/package-info.java index 3af4e0341..f699a513a 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/package-info.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/package-info.java @@ -16,5 +16,4 @@ /** * Map Transformer Test package. */ - package com.hotels.map; diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 487b8d0fa..ec64365db 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.hotels.map.transformer; import static java.math.BigInteger.ONE; diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java index 6a280210a..2e87cae99 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java @@ -16,5 +16,4 @@ /** * Map transformer package. */ - package com.hotels.map.transformer; diff --git a/config/checkstyle/rules.xml b/config/checkstyle/rules.xml index c1ff34307..7419229a9 100644 --- a/config/checkstyle/rules.xml +++ b/config/checkstyle/rules.xml @@ -135,7 +135,7 @@ - + diff --git a/pom.xml b/pom.xml index 985404ba2..3df3451c8 100644 --- a/pom.xml +++ b/pom.xml @@ -188,6 +188,15 @@ + + default + + true + + + true + + relaxed From ed225face21153268beeb6485c06c6b4ead2bd1d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 8 Apr 2021 10:45:57 +0200 Subject: [PATCH 1291/1786] Changes the jdk version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3df3451c8..bd04fface 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ UTF-8 UTF-8 - 1.8 + 11 ${jdk.version} ${jdk.version} 1.18.20 From beb8cf76b95e0678d8e49fadd8ab85ed9071f6c9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 28 Apr 2021 21:53:45 +0000 Subject: [PATCH 1292/1786] Upgrade to GitHub-native Dependabot --- .github/dependabot.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..f39450fdb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: +- package-ecosystem: maven + directory: "/" + schedule: + interval: daily + time: "02:00" + open-pull-requests-limit: 10 + target-branch: develop + reviewers: + - fborriello + labels: + - configuration + - update + ignore: + - dependency-name: com.hotels:hotels-oss-parent + versions: + - "> 4.3.0, < 4.4" From 4cbc309cb40a07b006ab369009d369ca51427bea Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 29 Apr 2021 12:43:24 +0200 Subject: [PATCH 1293/1786] removes the not needed exclusion from dependabot check --- .github/dependabot.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f39450fdb..298caea65 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,7 +12,7 @@ updates: labels: - configuration - update - ignore: - - dependency-name: com.hotels:hotels-oss-parent - versions: - - "> 4.3.0, < 4.4" +# ignore: +# - dependency-name: com.hotels:hotels-oss-parent +# versions: +# - "> 4.3.0, < 4.4" From 9541f79c3e0e231da570c384240c0fa0a1d27ba0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 29 Apr 2021 12:46:07 +0200 Subject: [PATCH 1294/1786] adds the dependabot configuration link --- .github/dependabot.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 298caea65..f2c64a184 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,4 @@ +# dependabot configuration available at: https://docs.github.com/en/code-security/supply-chain-security/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: maven @@ -11,8 +12,4 @@ updates: - fborriello labels: - configuration - - update -# ignore: -# - dependency-name: com.hotels:hotels-oss-parent -# versions: -# - "> 4.3.0, < 4.4" + - update \ No newline at end of file From 447ab67ca82e3bfc085b2e4bf7ec9f8c75c6a529 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 May 2021 02:00:37 +0000 Subject: [PATCH 1295/1786] Bump jacoco-maven-plugin from 0.8.6 to 0.8.7 Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.6 to 0.8.7. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.6...v0.8.7) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bd04fface..bb9048171 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ 1.7.30 4.0.1 - 0.8.6 + 0.8.7 1.0 0.98 1.0 From be542bff8548b5b2de9869694d8b124259e51718 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 May 2021 02:00:52 +0000 Subject: [PATCH 1296/1786] Bump maven-gpg-plugin from 1.6 to 3.0.1 Bumps [maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 1.6 to 3.0.1. - [Release notes](https://github.com/apache/maven-gpg-plugin/releases) - [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-1.6...maven-gpg-plugin-3.0.1) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bb9048171..1f47f2673 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ github 3.9.1 - 1.6 + 3.0.1 3.1.2 false true From 0fb9a109add40a7d7ed034aa7aef7431f893d9ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 May 2021 02:00:41 +0000 Subject: [PATCH 1297/1786] Bump mockito-core from 3.9.0 to 3.10.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.9.0 to 3.10.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.9.0...v3.10.0) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1f47f2673..d85bf4438 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.12.0 1.3.0 - 3.9.0 + 3.10.0 7.4.0 3.19.0 From c1de8f768669307af8fb4244ee3a2460f0a019bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 02:00:47 +0000 Subject: [PATCH 1298/1786] Bump mockito-core from 3.10.0 to 3.11.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.10.0 to 3.11.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.10.0...v3.11.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d85bf4438..b65a1e822 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.12.0 1.3.0 - 3.10.0 + 3.11.0 7.4.0 3.19.0 From 22b370412e56045b31ad0ceac5d6cd59c88ac423 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Jun 2021 02:00:48 +0000 Subject: [PATCH 1299/1786] Bump mockito-core from 3.11.0 to 3.11.1 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.11.0 to 3.11.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.11.0...v3.11.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b65a1e822..e9f03d516 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.12.0 1.3.0 - 3.11.0 + 3.11.1 7.4.0 3.19.0 From dd13d9e2343fdbfa164e7fd7e64d473de1e30f72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Jun 2021 02:00:32 +0000 Subject: [PATCH 1300/1786] Bump assertj-core from 3.19.0 to 3.20.0 Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.19.0 to 3.20.0. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.19.0...assertj-core-3.20.0) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9f03d516..6399b84cd 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 3.11.1 7.4.0 - 3.19.0 + 3.20.0 2.0.1.Final 7.0.1.Final From 7703096e794a277f81ecbcb7dacbe4e55c6521f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Jun 2021 02:00:59 +0000 Subject: [PATCH 1301/1786] Bump assertj-core from 3.20.0 to 3.20.1 Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.20.0 to 3.20.1. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.20.0...assertj-core-3.20.1) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6399b84cd..55fe08df8 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 3.11.1 7.4.0 - 3.20.0 + 3.20.1 2.0.1.Final 7.0.1.Final From 4a5cf3ee1e59a41058f79eb0e81383edf2c4c7b6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 10:38:35 +0200 Subject: [PATCH 1302/1786] * Increases the jdk version to 15 * Adds Changelog specific for this version * Modifies the Travis build to manage the jdk15 version --- .travis.yml | 25 +- CHANGELOG-JDK15.md | 278 ++++++++++++++++++ README.md | 20 +- .../java/com/hotels/beans/BeanUtilsTest.java | 30 +- .../beans/performance/PerformanceTest.java | 6 +- .../transformer/BeanTransformerTest.java | 84 +++--- .../BuilderObjectTransformationTest.java | 6 +- .../ImmutableObjectTransformationTest.java | 94 +++--- .../MixedObjectTransformationTest.java | 50 ++-- .../MutableObjectTransformationTest.java | 98 +++--- .../beans/sample/record/FromFooRecord.java | 26 ++ .../beans/sample/record/RecordToFoo.java | 23 ++ .../utils/ReflectionUtilsTest.java | 12 +- .../transformer/validator/ValidatorTest.java | 20 +- .../beans/conversion/ConverterTest.java | 4 +- .../java/com/hotels/map/MapUtilsTest.java | 6 +- .../map/transformer/MapTransformerTest.java | 44 +-- pom.xml | 18 +- 18 files changed, 608 insertions(+), 236 deletions(-) create mode 100755 CHANGELOG-JDK15.md create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/record/FromFooRecord.java create mode 100644 bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java diff --git a/.travis.yml b/.travis.yml index ac05810b5..3dc08e325 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,11 +11,8 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -# Testing compatibility with newer jdk(s) jdk: - - openjdk11 - - openjdk12 - - openjdk13 + - openjdk15 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: @@ -30,7 +27,7 @@ jobs: - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" jdk: openjdk11 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ AND tag =~ ^((?!-jdk15).)*$ script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn @@ -47,7 +44,23 @@ jobs: - stage: "JDK11 Release" name: "Releasing artifacts for JDK11" jdk: openjdk11 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ AND tag =~ ^((?!-jdk15).)*$ + script: skip + before_deploy: + - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d + - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + deploy: + - provider: script + script: config/travis/deploy.sh + skip_cleanup: true + on: + tags: true + ### JDK15 release + - stage: "JDK15 Release" + name: "Releasing artifacts for JDK15" + jdk: openjdk15 + if: type NOT IN (pull_request) AND tag IS present AAND tag =~ ^.*-jdk15$ script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d diff --git a/CHANGELOG-JDK15.md b/CHANGELOG-JDK15.md new file mode 100755 index 000000000..8e6924f33 --- /dev/null +++ b/CHANGELOG-JDK15.md @@ -0,0 +1,278 @@ +# BULL Change Log (`jdk 15` or above) + +All notable changes to this project will be documented in this file. + +### [1.8.0-jdk15] 2021.06.18 +#### Added +* Increase the jdk version to 15 +* Enables the [Java Record](https://blogs.oracle.com/javamagazine/records-come-to-java) transformation + +### [1.7.4] 2020.10.07 +#### Changed +* Provides new utilities methods + +### [1.7.3] 2020.06.09 +#### Changed +* Removes the deprecated method: `setDefaultValueSetEnabled` + +### [1.7.2] 2020.06.09 +#### Changed +* Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` +* Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). + +### [1.7.1] 2020.03.21 +#### Added +* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). +#### Changed +* Updated `hibernate-validator` version to `6.1.4.Final` (was `6.1.2.Final`). + +### [1.6.6] 2020.03.16 +#### Changed +* Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). +* Updated `commons-lang3` version to `3.10` (was `3.9`). + +### [1.6.5] 2020.01.21 +#### Changed +* Testing dependencies update + +### [1.6.4] 2019.12.24 +#### Added +* Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). +* Implemented transformation of a field declared with its interface. + +### [1.6.3.2] 2019.12.19 +#### Added +* Added method for retrieving the class getter methods. + +### [1.6.3.1] 2019.12.09 +#### Changed +* Testing dependencies update + +### [1.6.3] 2019.12.02 +### Added +* Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. +* Modified Travis configuration in order to test the compatibility with other JDKs versions + +### [1.6.2] 2019.11.22 +#### Changed +* Removed warning leg message in case the constructor parameter names are not available in the compiled code. +* Removed `slf4j-api` dependency from the library jar. + +### [1.6.1] 2019.11.18 +### Added +* Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. +#### Changed +* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). + +### [1.6.0.2] 2019.10.30 +### Removed +* Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` +* The following deprecated classes has been removed: + * `com.hotels.beans.model.FieldMapping` + * `com.hotels.beans.model.FieldTransformer` + * `com.hotels.beans.Transformer` +### Added +* New specific exception in case the Field Transformation function defined is not valid +* Implemented a new functionality that allows to transform also Map object applying transformation function and mappings +#### Changed +* `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` +* Updated `hibernate-validator` version to `6.1.0.Final` (was `6.0.17.Final`). + +### [1.5.1] 2019.09.02 +#### Changed +* **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** + ```xml + + com.hotels.beans + bull-bean-transformer + x.y.z + + ``` +* Module `bean-utils-library` has been relocated into `bull-bean-transformer`. +* The following classes has been deprecated, please find below the complete list and the new one to be used: + + | Deprecated | **New one** | + | :----------- | :----------- | + | `com.hotels.beans.model.FieldMapping` | `com.hotels.transformer.model.FieldMapping` | + | `com.hotels.beans.model.FieldTransformer` | `com.hotels.transformer.model.FieldTransformer` | + | `com.hotels.beans.Transformer` | `com.hotels.transformer.Transformer` | + +### [1.5.0] 2019.08.06 +#### Added +* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). +#### Changed +* Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled +* Modified Transformer initialization in order to create a `ConversionAnalyzer` instance only if the automatic conversion is enabled + +### [1.4.7.1] [1.4.7.2] [1.4.7.3] 2019.07.05 +#### Changed +* Changed sonatype credential + +### [1.4.7] 2019.07.03 +#### Added +* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/HotelsDotCom/bull/issues/73)). + +### [1.4.6] 2019.06.27 +#### Changed +* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/HotelsDotCom/bull/issues/70)). + +### [1.4.5] 2019.06.05 +#### Added +* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). +* Added check during project build in order to prevent the add different versions of the same dependency. +#### Changed +* Modified library in order to let it able to retrieve values from getters if a field does not exist (see: [Issue 66](https://github.com/HotelsDotCom/bull/issues/66)). + +### [1.4.4.1] 2019.05.29 +#### Changed +* Improved Javadoc +* Added reference to the articles published on **DZone** and **InfoQ** + +### [1.4.2] 2019.05.24 +#### Added +* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/HotelsDotCom/bull/issues/62)). +#### Fixed +* Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). + +### [1.4.1.1] 2019.05.24 +#### Changed +* Made the project multi module + +### [1.4.1] 2019.05.18 +#### Changed +* Removed deprecated method: `setValidationDisabled` +* Testing dependencies update + +### [1.4.0] 2019.05.13 +#### Changed +* **Modified project behaviour:** since this version the **"Bean Validation" is disabled by default**, to enable it, the following instruction needs to be executed: `transformer.setValidationEnabled(true);` + +### [1.3.2] 2019.05.11 +### Added +* Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/HotelsDotCom/bull/issues/57)). + +### [1.3.1] 2019.05.08 +#### Changed +* In order to improve the library performances the following Changed have been applied: + * Modified no args constructor invocation in order to use `LambdaMetafactory` + * Modified field value retrieval in order to use `LambdaMetafactory` + * Modified value retrieval/set from/to source/destination object in order to minimise the executed actions +* Updated `hotels-oss-parent` version to `4.0.1` (was `4.0.0`). + +### [1.3.0] 2019.04.28 +#### Added +* Added support for the transformation of Java Beans built through Builder + +### [1.2.7] 2019.04.18 +#### Changed +* Improved optional usage. +* Fixed a bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). + +### [1.2.6] 2019.04.06 +#### Added +* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). + +### [1.2.5] 2019.03.31 +#### Added +* Improved field value retrieval function. + +### [1.2.4] 2019.03.23 +#### Changed +* Added caching for method: `getDeclaredField` + +### [1.2.3] 2019.03.22 +#### Added +* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/HotelsDotCom/bull/issues/38)) +* Performance improvement + +### [1.2.2] 2019.03.20 +#### Changed +* Testing dependencies update + +### [1.2.1] 2019.03.05 +#### Added +* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) +* Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` + +### [1.2.0] 2019.02.25 +#### Added +* Added possibility to skip the object validation (see: [Issue 31](https://github.com/HotelsDotCom/bull/issues/31)) +* Provided documentation and samples for the above functionality +### Changed +- Updated `jdk` version to `11` (was `1.8`). +- Updated Travis configuration in order to work with java 11 +- Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created + +### [1.1.4] 2019.02.20 +#### Added +* Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/HotelsDotCom/bull/issues/27)). +* Added possibility to apply a transformation function on all fields matching with the given name without evaluating the full field path. +* Added samples and tests for the above functionality +#### Fixed +* Fixed issue that was preventing the `Set` transformation + +### [1.1.3] 2019.02.17 +#### Added +* Added static transformation functionality (see: [Issue 25](https://github.com/HotelsDotCom/bull/issues/25)). + +### [1.1.2] 2019.02 +#### Added +* Made the field name mapping more flexible adding the possibility to map destination object field with field contained into nested objects. +* Added samples and tests for the above functionality. +#### Changed +* Updated hibernate dependency: `org.hibernate.validator` (was `org.hibernate.validator`). +* Removed `parallel` execution where not needed because this could cause performance degradation. + +### [1.1.1] 2019.02.09 +#### Changed +* Improved exception messaging in order to simplify the troubleshooting process +* Improved readme file + +### [1.1.0] 2019.02.04 +#### Added +* Added dependency to: `slf4j-api` as no longer available from Spring. +- Added ValidationUtils class for raising an `IllegalArgumentException` in case any parameter is null. +#### Removed +* Removed dependency: `spring-boot-starter-validation` and imported one by one the required validation dependencies +* Removed dependency: `spring-boot-starter-cache` and imported one by one the required validation dependencies + +### [1.0.17] 2019.02.03 +#### Changed +* Improved package-info comments +#### Added +* Configured Travis in order to automatically release artifacts + +### [1.0.16] 2019.01.26 +#### Changed +* Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). +* Updated `hotels-oss-parent` version to `4.0.0` (was `2.3.5`). +#### Added +* Configured Travis in order to automatically build the application, perform a quality check and publish site. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) +* Added build, test coverage and security badge to readme file. + +### [1.0.15] 2019.01.23 +#### Added +* Added GitHub site build with maven. + +### [1.0.14] 2019.01.18 +#### Added +* Added possibility to configure the transformer in order to set the default value for all destination's object fields that are not existing in the source object. + See [README.md](https://github.com/HotelsDotCom/bull/blob/master/README.md) for more details. +#### Changed +* Jumped to version `1.0.14` in order to be consequent to the previous library version hosted on a private repo. + +### [1.0.3] 2019.01.17 +#### Added +* Added changelog file. + +### [1.0.2] 2019.01.17 +#### Changed +* Removed not needed comments + +### [1.0.1] 2019.01.17 +#### Changed +* Added maven build info to the readme file. + +### [1.0.0] 2019.01.16 +#### Added +* First `BULL` release. diff --git a/README.md b/README.md index e82e7ed6c..00c6096b9 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,10 @@ It contains all the modules available in the project **The project provides two different builds**, one compatible with `jdk 8` (or above) and one with `jdk 11` or above. -In case you need to integrate it in a `jdk 8` (or above project) please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) file or [CHANGELOG](CHANGELOG.md) otherwise. +In case you need to integrate it in a: +* `jdk 8` based project please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) +* `jdk 11` based project please refer to [CHANGELOG-JDK8](CHANGELOG.md) +* `jdk 15 or above` based project please refer to [CHANGELOG-JDK15](CHANGELOG-JDK15.md) * #### Suggestions @@ -127,6 +130,7 @@ mvnw.cmd versions:display-dependency-updates -P check-for-updates * support copy of immutable beans. * support copy of mutable beans. * support copy of hybrid beans (some fields private and some not). +* support copy of Java Records. * support copy of Java beans without getter and setter methods. * support copy with Java primitive type. * support copy with Java Collection type. e.g. `List => List` @@ -732,6 +736,20 @@ ToBean toBean = new BeanTransformer() .transform(sourceObject, ToBean.class); ``` +## Java Record transformation samples + +### Simple case: + +```java +public record FromFooRecord { public record RecordToFoo(BigInteger id, String name) { +} } +``` +And one line code as: + +```java +var toBean = beanUtils.getTransformer().transform(fromBean, RecordToFoo.class); +``` + ## Constraints: * the class's fields that have to be copied must not be static diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java index 26a0288b8..914cdfc60 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java @@ -64,12 +64,12 @@ public void beforeClass() { */ @Test public void testGetTransformerWorksProperly() { - //GIVEN + // GIVEN - //WHEN + // WHEN final BeanTransformer transformer = underTest.getTransformer(); - //THEN + // THEN assertThat(transformer).isNotNull(); } @@ -78,9 +78,9 @@ public void testGetTransformerWorksProperly() { */ @Test(expectedExceptions = IllegalArgumentException.class) public void testGetTransformerThrowsExceptionIfTheBeanTransformerIsNull() { - //GIVEN + // GIVEN - //WHEN + // WHEN underTest.getTransformer(null, ImmutableToFooSimple.class); } @@ -91,16 +91,16 @@ public void testGetTransformerThrowsExceptionIfTheBeanTransformerIsNull() { */ @Test(dataProvider = "dataStaticTransformationTesting") public void testGetTransformerFunctionWorksProperly(final String testCaseDescription, final Function transformerFunction) { - //GIVEN + // GIVEN FromFooSimple fromFooSimple = createFromFooSimple(); List fromFooSimpleList = Arrays.asList(fromFooSimple, fromFooSimple); - //WHEN + // WHEN List actual = fromFooSimpleList.stream() .map(transformerFunction) .collect(Collectors.toList()); - //THEN + // THEN assertThat(transformerFunction).isNotNull(); assertThat(actual).usingRecursiveComparison() .ignoringAllOverriddenEquals() @@ -127,11 +127,11 @@ private Object[][] dataStaticTransformationTesting() { */ @Test public void testValidateWorksProperly() { - //GIVEN + // GIVEN ImmutableToFooMissingCustomAnnotation validBean = new ImmutableToFooMissingCustomAnnotation(NAME, ID.intValue()); - //WHEN + // WHEN underTest.getValidator().validate(validBean); } @@ -140,11 +140,11 @@ public void testValidateWorksProperly() { */ @Test(expectedExceptions = InvalidBeanException.class) public void testValidateThrowsExceptionIfTheGivenBeanIsInvalid() { - //GIVEN + // GIVEN ImmutableToFoo immutableToFoo = new ImmutableToFoo(null, null, null, null, null); - //WHEN + // WHEN underTest.getValidator().validate(immutableToFoo); } @@ -153,12 +153,12 @@ public void testValidateThrowsExceptionIfTheGivenBeanIsInvalid() { */ @Test public void testGetPrimitiveTypeConverterWorksProperly() { - //GIVEN + // GIVEN - //WHEN + // WHEN Converter actual = underTest.getPrimitiveTypeConverter(); - //THEN + // THEN assertThat(actual).isNotNull(); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java index 1bacb6a6b..64e30cefb 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java @@ -109,10 +109,10 @@ public void beforeClass() { @Test(dataProvider = "dataPerformanceTest") public void testCopyPropertiesGetsCompletedInTheExpectedTime(final double totalTransformation, final int waitInterval, final Object sourceObject, final Class destObjectClass, final double maxTransformationTime) throws InterruptedException { - //GIVEN + // GIVEN warmUp(sourceObject, destObjectClass); - //WHEN + // WHEN StopWatch stopWatch = new StopWatch(); stopWatch.start(); BeanTransformer transformer = underTest.getTransformer(); @@ -125,7 +125,7 @@ public void testCopyPropertiesGetsCompletedInTheExpectedTime(final double totalT stopWatch.stop(); double avgTransformationTime = stopWatch.getTime(MILLISECONDS) / totalTransformation; - //THEN + // THEN log.info("Object: {}, Average transformation time: {} ms", destObjectClass, avgTransformationTime); assertThat(avgTransformationTime) .as("Performance degradation! Expected: %s, actual: %s", maxTransformationTime, avgTransformationTime) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java index 8da5d54f2..51112976a 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java @@ -72,14 +72,14 @@ public class BeanTransformerTest extends AbstractBeanTransformerTest { @Test @SuppressWarnings("unchecked") public void testRemoveFieldMappingWorksProperly() { - //GIVEN + // GIVEN BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); - //WHEN + // WHEN beanTransformer.removeFieldMapping(DEST_FIELD_NAME); TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - //THEN + // THEN assertThat(transformerSettings.getFieldsNameMapping()).doesNotContainKey(DEST_FIELD_NAME); } @@ -88,10 +88,10 @@ public void testRemoveFieldMappingWorksProperly() { */ @Test(expectedExceptions = IllegalArgumentException.class) public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { - //GIVEN + // GIVEN BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(SOURCE_FIELD_NAME, DEST_FIELD_NAME)); - //WHEN + // WHEN beanTransformer.removeFieldMapping(null); } @@ -101,15 +101,15 @@ public void testRemoveFieldMappingRaisesExceptionIfItsCalledWithNullParam() { @Test @SuppressWarnings("unchecked") public void testResetFieldsMappingWorksProperly() { - //GIVEN + // GIVEN BeanTransformer beanTransformer = underTest .withFieldMapping(new FieldMapping<>(SOURCE_FIELD_NAME, DEST_FIELD_NAME), new FieldMapping<>(SOURCE_FIELD_NAME_2, DEST_FIELD_NAME)); - //WHEN + // WHEN beanTransformer.resetFieldsMapping(); TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - //THEN + // THEN assertThat(transformerSettings.getFieldsNameMapping()).isEmpty(); } @@ -119,15 +119,15 @@ public void testResetFieldsMappingWorksProperly() { @Test @SuppressWarnings("unchecked") public void testResetFieldsTransformerWorksProperly() { - //GIVEN + // GIVEN BeanTransformer beanTransformer = underTest .withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val), new FieldTransformer<>(REFLECTION_UTILS_FIELD_NAME, val -> val)); - //WHEN + // WHEN beanTransformer.resetFieldsTransformer(); TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - //THEN + // THEN assertThat(transformerSettings.getFieldsTransformers()).isEmpty(); } @@ -137,14 +137,14 @@ public void testResetFieldsTransformerWorksProperly() { @Test @SuppressWarnings("unchecked") public void testRemoveFieldTransformerWorksProperly() { - //GIVEN + // GIVEN BeanTransformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - //WHEN + // WHEN beanTransformer.removeFieldTransformer(DEST_FIELD_NAME); TransformerSettings transformerSettings = (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - //THEN + // THEN assertThat(transformerSettings.getFieldsTransformers()).doesNotContainKey(DEST_FIELD_NAME); } @@ -153,10 +153,10 @@ public void testRemoveFieldTransformerWorksProperly() { */ @Test(expectedExceptions = IllegalArgumentException.class) public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() { - //GIVEN + // GIVEN BeanTransformer beanTransformer = underTest.withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val)); - //WHEN + // WHEN beanTransformer.removeFieldTransformer(null); } @@ -166,11 +166,11 @@ public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() */ @Test(expectedExceptions = Exception.class) public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() throws Exception { - //GIVEN + // GIVEN Method getSourceFieldValueMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_VALUE_METHOD_NAME, Object.class, String.class, Field.class, boolean.class); getSourceFieldValueMethod.setAccessible(true); - //WHEN + // WHEN getSourceFieldValueMethod.invoke(underTest, null, null, null, false); } @@ -182,7 +182,7 @@ public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() thro @Test @SuppressWarnings("unchecked") public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined() throws Exception { - //GIVEN + // GIVEN ReflectionUtils reflectionUtilsMock = mock(ReflectionUtils.class); Field field = mock(Field.class); Class fieldType = Integer.class; @@ -195,10 +195,10 @@ public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined Method getSourceFieldValueMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_VALUE_METHOD_NAME, Object.class, String.class, Field.class, boolean.class); getSourceFieldValueMethod.setAccessible(true); - //WHEN + // WHEN ThrowingCallable actual = () -> getSourceFieldValueMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME, field, true); - //THEN + // THEN assertThatCode(actual).doesNotThrowAnyException(); verify(reflectionUtilsMock).getFieldValue(FromFooSimple.class, AGE_FIELD_NAME, fieldType); verify(field).getType(); @@ -210,13 +210,13 @@ public void testGetSourceFieldValueThrowsNoExceptionIfAFieldTransformerIsDefined */ @Test public void testThatPrimitiveTypeConversionIsCorrectlyEnabled() { - //GIVEN + // GIVEN underTest.setPrimitiveTypeConversionEnabled(true); - //WHEN + // WHEN boolean actual = underTest.getSettings().isPrimitiveTypeConversionEnabled(); - //THEN + // THEN assertThat(actual).isTrue(); underTest.setPrimitiveTypeConversionEnabled(false); } @@ -228,7 +228,7 @@ public void testThatPrimitiveTypeConversionIsCorrectlyEnabled() { */ @Test public void testGetSourceFieldTypeReturnsTheSourceObjectClass() throws Exception { - //GIVEN + // GIVEN CacheManager cacheManager = mock(CacheManager.class); ReflectionUtils reflectionUtilsMock = mock(ReflectionUtils.class); ClassUtils classUtils = mock(ClassUtils.class); @@ -244,10 +244,10 @@ public void testGetSourceFieldTypeReturnsTheSourceObjectClass() throws Exception Method getSourceFieldTypeMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_TYPE_METHOD_NAME, Class.class, String.class); getSourceFieldTypeMethod.setAccessible(true); - //WHEN + // WHEN Class actual = (Class) getSourceFieldTypeMethod.invoke(underTest, Integer.class, AGE_FIELD_NAME); - //THEN + // THEN verify(cacheManager).getFromCache(anyString(), any(Class.class)); verify(reflectionUtilsMock).getDeclaredFieldType(AGE_FIELD_NAME, Integer.class); verify(classUtils).isPrimitiveType(Integer.class); @@ -263,7 +263,7 @@ public void testGetSourceFieldTypeReturnsTheSourceObjectClass() throws Exception */ @Test public void testGetSourceFieldTypeReturnsNull() throws Exception { - //GIVEN + // GIVEN CacheManager cacheManager = mock(CacheManager.class); ReflectionUtils reflectionUtilsMock = mock(ReflectionUtils.class); ClassUtils classUtils = mock(ClassUtils.class); @@ -282,10 +282,10 @@ public void testGetSourceFieldTypeReturnsNull() throws Exception { Method getSourceFieldTypeMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_TYPE_METHOD_NAME, Class.class, String.class); getSourceFieldTypeMethod.setAccessible(true); - //WHEN + // WHEN Class actual = (Class) getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); - //THEN + // THEN verify(cacheManager).getFromCache(anyString(), any(Class.class)); verify(reflectionUtilsMock).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); verify(classUtils).isPrimitiveType(FromFooSimple.class); @@ -301,7 +301,7 @@ public void testGetSourceFieldTypeReturnsNull() throws Exception { */ @Test public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception { - //GIVEN + // GIVEN CacheManager cacheManager = mock(CacheManager.class); ReflectionUtils reflectionUtilsMock = mock(ReflectionUtils.class); ClassUtils classUtils = mock(ClassUtils.class); @@ -320,10 +320,10 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception Method getSourceFieldTypeMethod = underTest.getClass().getDeclaredMethod(GET_SOURCE_FIELD_TYPE_METHOD_NAME, Class.class, String.class); getSourceFieldTypeMethod.setAccessible(true); - //WHEN + // WHEN ThrowingCallable actual = () -> getSourceFieldTypeMethod.invoke(underTest, FromFooSimple.class, AGE_FIELD_NAME); - //THEN + // THEN assertThatThrownBy(actual).hasCauseInstanceOf(MissingFieldException.class); verify(cacheManager).getFromCache(anyString(), any(Class.class)); verify(reflectionUtilsMock).getDeclaredFieldType(AGE_FIELD_NAME, FromFooSimple.class); @@ -347,7 +347,7 @@ public void testGetSourceFieldTypeThrowsMissingFieldException() throws Exception public void testGetTransformedValueWorksProperly(final String testCaseDescription, final String fieldName, final Object fieldValue, final FieldTransformer fieldTransformer, final boolean isPrimitiveTypeConversionEnabled, final boolean isDestinationFieldPrimitiveType, final Object expectedValue) throws Exception { - //GIVEN + // GIVEN Field field = mock(Field.class); TransformerSettings settings = mock(TransformerSettings.class); when(settings.isPrimitiveTypeConversionEnabled()).thenReturn(isPrimitiveTypeConversionEnabled); @@ -357,11 +357,11 @@ public void testGetTransformedValueWorksProperly(final String testCaseDescriptio Method getTransformerFunctionMethod = underTest.getClass().getDeclaredMethod(GET_TRANSFORMER_VALUE_METHOD_NAME, transformedValueMethodParams); getTransformerFunctionMethod.setAccessible(true); - //WHEN + // WHEN Object actual = getTransformerFunctionMethod .invoke(underTest, fieldTransformer, fieldValue, FromFooSimple.class, fieldName, field, isDestinationFieldPrimitiveType, fieldName); - //THEN + // THEN assertThat(actual).isEqualTo(expectedValue); restoreUnderTestObject(); } @@ -387,7 +387,7 @@ private Object[][] dataGetTransformerFunctionTesting() { @Test @SuppressWarnings("unchecked") public void testGetConstructorArgsValuesReturnsTheDefaultTypeIfTheDestinationFieldNameIsNull() throws Exception { - //GIVEN + // GIVEN Constructor constructor = mock(Constructor.class); ClassUtils classUtils = mock(ClassUtils.class); Parameter constructorParameter = mock(Parameter.class); @@ -405,10 +405,10 @@ public void testGetConstructorArgsValuesReturnsTheDefaultTypeIfTheDestinationFie .getDeclaredMethod(GET_CONSTRUCTOR_ARGS_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class); getConstructorArgsValuesMethod.setAccessible(true); - //WHEN + // WHEN Object[] actual = (Object[]) getConstructorArgsValuesMethod.invoke(underTest, fromFoo, MutableToFooAdvFields.class, constructor, ID_FIELD_NAME); - //THEN + // THEN verify(classUtils).getConstructorParameters(constructor); verify(constructorParameter).isNamePresent(); verify(constructorParameter, times(2)).getName(); @@ -495,7 +495,7 @@ private Object[][] dataConversionAnalyzerInitializationTesting() { @Test(dataProvider = "dataHandleInjectionExceptionTesting") public void testHandleInjectionExceptionWorksAsExpected(final String testCaseDescription, final boolean forceConstructorInjection, final Class expectedReturnType) throws Exception { - //GIVEN + // GIVEN ClassUtils classUtils = mock(ClassUtils.class); when(classUtils.areParameterNamesAvailable(any(Constructor.class))).thenReturn(false); when(classUtils.getConstructorParameters(any())).thenReturn(new Parameter[] {}); @@ -506,7 +506,7 @@ public void testHandleInjectionExceptionWorksAsExpected(final String testCaseDes Class.class, Constructor.class, String.class, Object[].class, boolean.class, Exception.class); handleInjectionExceptionMethod.setAccessible(true); - //WHEN + // WHEN Object actual; try { actual = handleInjectionExceptionMethod.invoke(underTest, fromFoo, MutableToFoo.class, null, "", null, forceConstructorInjection, new Exception()); @@ -514,7 +514,7 @@ public void testHandleInjectionExceptionWorksAsExpected(final String testCaseDes actual = e.getTargetException(); } - //THEN + // THEN assertThat(actual).isInstanceOf(expectedReturnType); restoreUnderTestObject(); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java index 29d2e13d7..02665713c 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java @@ -37,13 +37,13 @@ public class BuilderObjectTransformationTest extends AbstractBeanTransformerTest */ @Test(dataProvider = "transformationThroughBuilderTesting") public void testTransformationThroughBuilder(final String testDescription, final Object sourceObject, final Class targetObjectClass) { - //GIVEN + // GIVEN underTest.setCustomBuilderTransformationEnabled(true); - //WHEN + // WHEN Object actual = underTest.transform(sourceObject, targetObjectClass); - //THEN + // THEN assertThat(actual).usingRecursiveComparison() .isEqualTo(sourceObject); underTest.setCustomBuilderTransformationEnabled(false); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 8c76ed26f..17b949748 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -96,12 +96,12 @@ public void afterMethod() { @Test(dataProvider = "dataDefaultTransformationTesting") public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, final BeanTransformer transformer, final Object sourceObject, final Class targetObjectClass) { - //GIVEN + // GIVEN - //WHEN + // WHEN Object actual = transformer.transform(sourceObject, targetObjectClass); - //THEN + // THEN assertThat(actual).usingRecursiveComparison() .ignoringAllOverriddenEquals() .isEqualTo(sourceObject); @@ -132,13 +132,13 @@ private Object[][] dataDefaultTransformationTesting() { */ @Test public void testTransformationOnAnExistingDestinationWorksProperly() { - //GIVEN + // GIVEN ImmutableToFooSimple immutableToFoo = new ImmutableToFooSimple(null, null, false); - //WHEN + // WHEN underTest.setValidationEnabled(true).transform(fromFooSimple, immutableToFoo); - //THEN + // THEN assertThat(immutableToFoo) .usingRecursiveComparison() .isEqualTo(fromFooSimple); @@ -156,16 +156,16 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { @Test(dataProvider = "dataCompositeFieldNameTesting") public void testTransformationWithCompositeFieldNameMappingIsWorkingAsExpected(final String testCaseDescription, final Object sourceObject, final String expectedName, final BigInteger expectedId, final int[] expectedPhoneNumbers) { - //GIVEN + // GIVEN TransformerImpl underTestMock = spy(new TransformerImpl()); Constructor beanAllArgsConstructor = new ClassUtils().getAllArgsConstructor(ImmutableFlatToFoo.class); when(underTestMock.canBeInjectedByConstructorParams(beanAllArgsConstructor)).thenReturn(false); FieldMapping phoneNumbersMapping = new FieldMapping<>(PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME, PHONE_NUMBER_DEST_FIELD_NAME); - //WHEN + // WHEN ImmutableFlatToFoo actual = underTestMock.withFieldMapping(phoneNumbersMapping).transform(sourceObject, ImmutableFlatToFoo.class); - //THEN + // THEN assertThat(actual).extracting(NAME_FIELD_NAME, ID_FIELD_NAME, PHONE_NUMBER_DEST_FIELD_NAME) .containsExactly(expectedName, expectedId, expectedPhoneNumbers); } @@ -194,9 +194,9 @@ private Object[][] dataCompositeFieldNameTesting() { @Test(dataProvider = "dataConstructorErrorTesting", expectedExceptions = InvalidBeanException.class) public void testTransformThrowsExceptionIfTheConstructorInvocationThrowsException(final String testCaseDescription, final Object sourceObject, final Class targetObjectClass) { - //GIVEN + // GIVEN - //WHEN + // WHEN underTest.setValidationEnabled(false).transform(sourceObject, targetObjectClass); } @@ -218,11 +218,11 @@ private Object[][] dataConstructorErrorTesting() { */ @Test(expectedExceptions = InvalidBeanException.class) public void testTransformThrowsExceptionWhenImmutableIsInvalid() throws CloneNotSupportedException { - //GIVEN + // GIVEN FromFoo fromFooNullId = AbstractTransformerTest.fromFoo.clone(); fromFooNullId.setId(null); - //WHEN + // WHEN underTest.setValidationEnabled(true).transform(fromFooNullId, ImmutableToFoo.class); } @@ -231,10 +231,10 @@ public void testTransformThrowsExceptionWhenImmutableIsInvalid() throws CloneNot */ @Test public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotValidAndTheValidationIsDisabled() { - //GIVEN + // GIVEN fromFoo.setId(null); - //WHEN + // WHEN ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); // THEN @@ -247,13 +247,13 @@ public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotVali */ @Test public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { - //GIVEN + // GIVEN - //WHEN + // WHEN final BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); ImmutableToFooDiffFields actual = beanTransformer.transform(fromFoo, ImmutableToFooDiffFields.class); - //THEN + // THEN assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()) .usingRecursiveComparison() .ignoringFields(IDENTIFIER_FIELD_NAME) @@ -270,17 +270,17 @@ public void testImmutableBeanWithDifferentFieldNamesIsCorrectlyCopied() { @Test(dataProvider = "dataAdvancedFieldsCopyTesting") public void testImmutableBeanWithAdvancedFieldsIsCorrectlyCopied(final String testCaseDescription, final FromFooAdvFields sourceObject, final Class targetObjectClass, final boolean isNameFieldEmpty) { - //GIVEN + // GIVEN final BeanTransformer beanTransformer = underTest .withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)) .withFieldMapping(new FieldMapping<>(PRICE_FIELD_NAME, NET_PRICE_FIELD_NAME)) .withFieldMapping(new FieldMapping<>(PRICE_FIELD_NAME, GROSS_PRICE_FIELD_NAME)) .withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); - //WHEN + // WHEN ImmutableToFooAdvFields actual = (ImmutableToFooAdvFields) beanTransformer.transform(sourceObject, targetObjectClass); - //THEN + // THEN assertThat(actual).usingRecursiveComparison() .ignoringFields(AGE_FIELD_NAME, PRICE_FIELD_NAME, LOCALE_FIELD_NAME) .isEqualTo(sourceObject); @@ -309,12 +309,12 @@ private Object[][] dataAdvancedFieldsCopyTesting() throws CloneNotSupportedExcep */ @Test public void testImmutableBeanWithMissingConstructorArgIsCorrectlyCopied() { - //GIVEN + // GIVEN - //WHEN + // WHEN ImmutableToFooMissingCustomAnnotation actual = underTest.withFieldTransformer().transform(fromFooWithPrimitiveFields, ImmutableToFooMissingCustomAnnotation.class); - //THEN + // THEN assertThat(actual).isNotNull(); assertThat(actual.getName()).isEqualTo(fromFooWithPrimitiveFields.getName()); } @@ -325,7 +325,7 @@ public void testImmutableBeanWithMissingConstructorArgIsCorrectlyCopied() { */ @Test public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNotProvidedFromJVM() throws Exception { - //GIVEN + // GIVEN String declaringClassName = ImmutableToFoo.class.getName(); // Parameter mock setup Parameter constructorParameter = mock(Parameter.class); @@ -336,10 +336,10 @@ public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNot Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); getDestFieldNameMethod.setAccessible(true); - //WHEN + // WHEN String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); - //THEN + // THEN assertThat(actual).isEqualTo(DEST_FIELD_NAME); // restore modified objects @@ -352,16 +352,16 @@ public void testGetDestFieldNameIsRetrievedFromConstructorArgIfTheParamNameIsNot */ @Test public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { - //GIVEN + // GIVEN underTest.withFieldTransformer(new FieldTransformer<>(LOCALE_FIELD_NAME, Locale::forLanguageTag)); - //WHEN + // WHEN final Method getConstructorValuesFromFieldsMethod = underTest.getClass().getDeclaredMethod(GET_CONSTRUCTOR_VALUES_FROM_FIELDS_METHOD_NAME, Object.class, Class.class, String.class); getConstructorValuesFromFieldsMethod.setAccessible(true); Object[] actual = (Object[]) getConstructorValuesFromFieldsMethod.invoke(underTest, fromFooAdvFields, ImmutableToFooAdvFields.class, ""); - //THEN + // THEN assertThat(actual).isNotNull(); assertThat(actual.length).isEqualTo(TOTAL_ADV_CLASS_FIELDS); @@ -375,7 +375,7 @@ public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { */ @Test public void testGetDestFieldNameReturnsNullIfConstructorParamHasNoNameProvidedFromJVMAndNoConstructorArgIsDefined() throws Exception { - //GIVEN + // GIVEN String declaringClassName = ImmutableToFoo.class.getName(); // Parameter mock setup Parameter constructorParameter = mock(Parameter.class); @@ -386,10 +386,10 @@ public void testGetDestFieldNameReturnsNullIfConstructorParamHasNoNameProvidedFr Method getDestFieldNameMethod = underTest.getClass().getDeclaredMethod(GET_DEST_FIELD_NAME_METHOD_NAME, Parameter.class, String.class); getDestFieldNameMethod.setAccessible(true); - //WHEN + // WHEN String actual = (String) getDestFieldNameMethod.invoke(underTest, constructorParameter, declaringClassName); - //THEN + // THEN assertThat(actual).isEqualTo(DEST_FIELD_NAME); // restore modified objects @@ -401,7 +401,7 @@ public void testGetDestFieldNameReturnsNullIfConstructorParamHasNoNameProvidedFr */ @Test public void testTransformationReturnsAMeaningfulException() { - //GIVEN + // GIVEN Class targetClass = ImmutableToFooSimpleWrongTypes.class; final String expectedExceptionMessageFormat = "Constructor invoked with wrong arguments. Expected: public %s(java.lang.Integer,java.lang.String); Found: %s(java.math.BigInteger,java.lang.String). " @@ -411,10 +411,10 @@ public void testTransformationReturnsAMeaningfulException() { String expectedExceptionMessage = format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getName()); - //WHEN + // WHEN ThrowingCallable actual = () -> underTest.transform(fromFooSimple, targetClass); - //THEN + // THEN assertThatThrownBy(actual).isInstanceOf(InvalidBeanException.class) .hasMessage(expectedExceptionMessage); } @@ -424,15 +424,15 @@ public void testTransformationReturnsAMeaningfulException() { */ @Test public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { - //GIVEN + // GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, () -> AGE); - //WHEN + // WHEN underTest.withFieldTransformer(ageFieldTransformer); ImmutableToFooNotExistingFields immutableObjectBean = underTest.transform(fromFooSimple, ImmutableToFooNotExistingFields.class); - //THEN + // THEN assertThat(immutableObjectBean).hasFieldOrPropertyWithValue(AGE_FIELD_NAME, AGE); } @@ -441,13 +441,13 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor */ @Test public void testFieldTransformationSkipWorksProperly() { - //GIVEN + // GIVEN underTest.skipTransformationForField("name", "nestedObject.phoneNumbers"); - //WHEN + // WHEN ImmutableToFoo actual = underTest.transform(fromFoo, ImmutableToFoo.class); - //THEN + // THEN assertThat(actual).hasNoNullFieldsOrPropertiesExcept(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); underTest.resetFieldsTransformationSkip(); } @@ -457,17 +457,17 @@ public void testFieldTransformationSkipWorksProperly() { */ @Test public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { - //GIVEN + // GIVEN FromFooSimpleBooleanField fromFooSimpleNullFields = new FromFooSimpleBooleanField(); FieldTransformer nullToTrue = new FieldTransformer<>(WORK_FIELD_NAME, aBoolean -> aBoolean == null || aBoolean); - //WHEN + // WHEN ImmutableToFooSimpleBoolean actual = underTest .withFieldTransformer(nullToTrue) .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); - //THEN + // THEN assertThat(actual.getWork()).isTrue(); underTest.resetFieldsTransformer(); } @@ -477,12 +477,12 @@ public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { */ @Test(expectedExceptions = InvalidFunctionException.class) public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { - //GIVEN + // GIVEN FromFooSimpleBooleanField fromFooSimpleNullFields = new FromFooSimpleBooleanField(); FieldTransformer upperCase = new FieldTransformer<>(WORK_FIELD_NAME, String::toUpperCase); - //WHEN + // WHEN underTest.withFieldTransformer(upperCase) .transform(fromFooSimpleNullFields, ImmutableToFooSimpleBoolean.class); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java index b6f03035e..088acbf68 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java @@ -42,12 +42,12 @@ public class MixedObjectTransformationTest extends AbstractBeanTransformerTest { */ @Test public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { - //GIVEN + // GIVEN - //WHEN + // WHEN MixedToFooMissingAllArgsConstructor actual = underTest.transform(fromFoo, MixedToFooMissingAllArgsConstructor.class); - //THEN + // THEN assertThat(actual).usingRecursiveComparison() .isEqualTo(fromFoo); } @@ -57,12 +57,12 @@ public void testMixedBeanWithoutAllArgsConstructorIsCorrectlyCopied() { */ @Test public void testMixedBeanIsCorrectlyCopied() { - //GIVEN + // GIVEN - //WHEN + // WHEN MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); - //THEN + // THEN assertThat(actual).usingRecursiveComparison() .isEqualTo(fromFoo); } @@ -72,13 +72,13 @@ public void testMixedBeanIsCorrectlyCopied() { */ @Test public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { - //GIVEN + // GIVEN - //WHEN + // WHEN BeanTransformer beanTransformer = underTest.withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)); MixedToFooDiffFields actual = beanTransformer.transform(fromFoo, MixedToFooDiffFields.class); - //THEN + // THEN assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId()) .usingRecursiveComparison() .ignoringFields(IDENTIFIER_FIELD_NAME) @@ -90,18 +90,18 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopied() { */ @Test public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTransformer() { - //GIVEN + // GIVEN /* Extended FieldTransformer function declaration. * Function idTransformer = value -> value.negate(); * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", idTransformer); */ FieldTransformer fieldTransformer = new FieldTransformer<>(IDENTIFIER_FIELD_NAME, BigInteger::negate); - //WHEN + // WHEN underTest.withFieldMapping(new FieldMapping<>(ID_FIELD_NAME, IDENTIFIER_FIELD_NAME)).withFieldTransformer(fieldTransformer); MixedToFooDiffFields actual = underTest.transform(fromFoo, MixedToFooDiffFields.class); - //THEN + // THEN assertThat(actual).hasFieldOrPropertyWithValue(IDENTIFIER_FIELD_NAME, fromFoo.getId().negate()) .usingRecursiveComparison() .ignoringFields(IDENTIFIER_FIELD_NAME) @@ -113,10 +113,10 @@ public void testMixedBeanWithDifferentFieldNamesIsCorrectlyCopiedThroughFieldTra */ @Test public void testMixedBeanWithMissingFieldsReturnsTheDefaultValueWhenTheSourceObjectDoesNotContainARequiredField() { - //GIVEN + // GIVEN underTest.setDefaultValueForMissingField(true); - //WHEN + // WHEN MixedToFooMissingField actual = underTest.transform(fromFoo, MixedToFooMissingField.class); assertThat(actual.getFooField()).isNull(); @@ -128,10 +128,10 @@ public void testMixedBeanWithMissingFieldsReturnsTheDefaultValueWhenTheSourceObj */ @Test(expectedExceptions = MissingFieldException.class) public void testMixedBeanWithMissingFieldsThrowsMissingFieldExceptionWhenTheSourceObjectDoesNotContainARequiredField() { - //GIVEN + // GIVEN underTest.setDefaultValueForMissingField(false); - //WHEN + // WHEN underTest.transform(fromFoo, MixedToFooMissingField.class); } @@ -140,15 +140,15 @@ public void testMixedBeanWithMissingFieldsThrowsMissingFieldExceptionWhenTheSour */ @Test public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { - //GIVEN + // GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, val -> AGE); - //WHEN + // WHEN underTest.withFieldTransformer(ageFieldTransformer); MixedToFooNotExistingFields mixedObjectBean = underTest.transform(fromFooSimple, MixedToFooNotExistingFields.class); - //THEN + // THEN assertThat(mixedObjectBean).hasFieldOrPropertyWithValue(AGE_FIELD_NAME, AGE); } @@ -157,13 +157,13 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor */ @Test public void testFieldTransformationSkipWorksProperly() { - //GIVEN + // GIVEN underTest.skipTransformationForField(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); - //WHEN + // WHEN MixedToFoo actual = underTest.transform(fromFoo, MixedToFoo.class); - //THEN + // THEN assertThat(actual).hasNoNullFieldsOrPropertiesExcept(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); underTest.resetFieldsTransformationSkip(); } @@ -173,13 +173,13 @@ public void testFieldTransformationSkipWorksProperly() { */ @Test public void testTransformationOnAnExistingDestinationWorksProperly() { - //GIVEN + // GIVEN MixedToFoo mixedToFoo = new MixedToFoo(null, null, null, null, null); - //WHEN + // WHEN underTest.skipTransformationForField().transform(fromFoo, mixedToFoo); - //THEN + // THEN assertThat(mixedToFoo).usingRecursiveComparison() .isEqualTo(fromFoo); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index fb8b0f427..0bb1b8aa9 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -66,9 +66,9 @@ public class MutableObjectTransformationTest extends AbstractBeanTransformerTest */ @Test(expectedExceptions = InvalidBeanException.class) public void testTransformThrowsExceptionWhenMutableBeanHasNoDefaultConstructor() { - //GIVEN + // GIVEN - //WHEN + // WHEN underTest.transform(fromFoo, MutableToFooInvalid.class); } @@ -77,12 +77,12 @@ public void testTransformThrowsExceptionWhenMutableBeanHasNoDefaultConstructor() */ @Test public void testMutableBeanIsCorrectlyCopied() { - //GIVEN + // GIVEN - //WHEN + // WHEN MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); - //THEN + // THEN assertThat(actual).usingRecursiveComparison() .isEqualTo(fromFoo); } @@ -92,13 +92,13 @@ public void testMutableBeanIsCorrectlyCopied() { */ @Test public void testTransformationOnAnExistingDestinationWorksProperly() { - //GIVEN + // GIVEN MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); - //WHEN + // WHEN underTest.transform(fromFooSubClass, mutableToFoo); - //THEN + // THEN assertThat(mutableToFoo).usingRecursiveComparison() .isEqualTo(fromFooSubClass); } @@ -108,14 +108,14 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { */ @Test public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotValidAndTheValidationIsDisabled() { - //GIVEN + // GIVEN MutableToFooSubClass mutableToFoo = new MutableToFooSubClass(); fromFooSubClass.setId(null); - //WHEN + // WHEN underTest.transform(fromFooSubClass, mutableToFoo); - //THEN + // THEN assertThat(mutableToFoo).usingRecursiveComparison() .isEqualTo(fromFooSubClass); fromFooSubClass.setId(ID); @@ -126,16 +126,16 @@ public void testTransformThrowsNoExceptionIfTheDestinationObjectValuesAreNotVali */ @Test public void testFieldTransformationIsAppliedOnlyToASpecificField() { - //GIVEN + // GIVEN String namePrefix = "prefix-"; FieldTransformer nameTransformer = new FieldTransformer<>(NESTED_OBJECT_NAME_FIELD_NAME, val -> namePrefix + val); - //WHEN + // WHEN MutableToFoo actual = underTest .withFieldTransformer(nameTransformer) .transform(fromFoo, MutableToFoo.class); - //THEN + // THEN assertThat(actual) .extracting(NAME_FIELD_NAME, NESTED_OBJECT_NAME_FIELD_NAME) .containsExactly(fromFoo.getName(), namePrefix + fromFoo.getNestedObject().getName()); @@ -147,17 +147,17 @@ public void testFieldTransformationIsAppliedOnlyToASpecificField() { */ @Test public void testFieldTransformationIsAppliedToAllMatchingFields() { - //GIVEN + // GIVEN String namePrefix = "prefix-"; FieldTransformer nameTransformer = new FieldTransformer<>(NAME_FIELD_NAME, val -> namePrefix + val); - //WHEN + // WHEN MutableToFoo actual = underTest .setFlatFieldNameTransformation(true) .withFieldTransformer(nameTransformer) .transform(fromFoo, MutableToFoo.class); - //THEN + // THEN assertThat(actual.getName()).isEqualTo(namePrefix + fromFoo.getName()); assertThat(actual.getNestedObject().getName()) .isEqualTo(namePrefix + fromFoo.getNestedObject().getName()); @@ -170,13 +170,13 @@ public void testFieldTransformationIsAppliedToAllMatchingFields() { */ @Test public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { - //GIVEN + // GIVEN FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, ID, ACTIVE); - //WHEN + // WHEN MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); - //THEN + // THEN assertThat(actual).usingRecursiveComparison() .isEqualTo(fromFooSimpleNoGetters); } @@ -186,14 +186,14 @@ public void testTransformerIsAbleToCopyObjectsWithoutRequiredMethods() { */ @Test public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeField() { - //GIVEN + // GIVEN FromFooSimpleNoGetters fromFooSimpleNoGetters = new FromFooSimpleNoGetters(NAME, null, ACTIVE); underTest.setDefaultValueForMissingPrimitiveField(false); - //WHEN + // WHEN MutableToFooSimpleNoSetters actual = underTest.transform(fromFooSimpleNoGetters, MutableToFooSimpleNoSetters.class); - //THEN + // THEN assertThat(actual).usingRecursiveComparison() .isEqualTo(fromFooSimpleNoGetters); underTest.setDefaultValueForMissingPrimitiveField(true); @@ -204,13 +204,13 @@ public void testTransformerDoesNotSetsTheDefaultValueForPrimitiveTypeField() { */ @Test public void testTransformerIsAbleToCopyObjectsWithoutFieldButWithGetterMethods() { - //GIVEN + // GIVEN FromFooNoField fromFooNoField = new FromFooNoField(); - //WHEN + // WHEN MutableToFooSimpleNoSetters actual = underTest.transform(fromFooNoField, MutableToFooSimpleNoSetters.class); - //THEN + // THEN assertThat(actual).extracting(ID_FIELD_NAME, NAME_FIELD_NAME, ACTIVE_FIELD_NAME) .containsExactly(fromFooNoField.getId(), fromFooNoField.getName(), fromFooNoField.isActive()); } @@ -220,15 +220,15 @@ public void testTransformerIsAbleToCopyObjectsWithoutFieldButWithGetterMethods() */ @Test public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCorrectlyCopiedThroughTransformerFunctions() { - //GIVEN + // GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); FieldTransformer ageFieldTransformer = new FieldTransformer<>(AGE_FIELD_NAME, () -> AGE); - //WHEN + // WHEN underTest.withFieldTransformer(ageFieldTransformer); MutableToFooNotExistingFields mutableObjectBean = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); - //THEN + // THEN assertThat(mutableObjectBean).hasFieldOrPropertyWithValue(AGE_FIELD_NAME, AGE); underTest.resetFieldsTransformer(); } @@ -239,14 +239,14 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor */ @Test public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeConversionIsEnabled() { - //GIVEN + // GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); underTest.setPrimitiveTypeConversionEnabled(true); - //WHEN + // WHEN ThrowingCallable actual = () -> underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); - //THEN + // THEN assertThatThrownBy(actual).hasCauseInstanceOf(MissingFieldException.class); underTest.setPrimitiveTypeConversionEnabled(false); } @@ -257,14 +257,14 @@ public void testTransformerThrowsExceptionIfAFieldIsMissingAndThePrimitiveTypeCo */ @Test public void testTransformerDoesNotThrowExceptionIfAFieldIsMissingAndTheDefaultValueSetIsEnabled() { - //GIVEN + // GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); underTest.setPrimitiveTypeConversionEnabled(true).setDefaultValueForMissingField(true); - //WHEN + // WHEN MutableToFooNotExistingFields actual = underTest.transform(fromFooSimple, MutableToFooNotExistingFields.class); - //THEN + // THEN assertThat(actual).extracting(ID_FIELD_NAME, NAME_FIELD_NAME) .containsExactly(fromFooSimple.getId(), fromFooSimple.getName()); underTest.setPrimitiveTypeConversionEnabled(false).setDefaultValueForMissingField(false); @@ -278,15 +278,15 @@ public void testTransformerDoesNotThrowExceptionIfAFieldIsMissingAndTheDefaultVa */ @Test(dataProvider = "dataTransformationTesting") public void testTransformationWithFieldTransformationWorksProperly(final String testCaseDescription, final String fieldToTransform, final Object transformationResult) { - //GIVEN + // GIVEN FromFooSimple fromFooSimple = new FromFooSimple(NAME, ID, ACTIVE); FieldTransformer fieldTransformer = new FieldTransformer<>(fieldToTransform, val -> transformationResult); - //WHEN + // WHEN underTest.withFieldTransformer(fieldTransformer); MutableToFooSimple actual = underTest.transform(fromFooSimple, MutableToFooSimple.class); - //THEN + // THEN assertThat(actual).hasFieldOrPropertyWithValue(fieldToTransform, transformationResult); underTest.removeFieldTransformer(fieldToTransform); } @@ -310,13 +310,13 @@ private Object[][] dataTransformationTesting() { */ @Test public void testFieldTransformationSkipWorksProperly() { - //GIVEN + // GIVEN underTest.skipTransformationForField(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); - //WHEN + // WHEN MutableToFoo actual = underTest.transform(fromFoo, MutableToFoo.class); - //THEN + // THEN assertThat(actual).hasNoNullFieldsOrPropertiesExcept(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); underTest.resetFieldsTransformationSkip(); } @@ -326,13 +326,13 @@ public void testFieldTransformationSkipWorksProperly() { */ @Test public void testAutomaticPrimitiveTypeTransformationWorksProperly() { - //GIVEN + // GIVEN underTest.setPrimitiveTypeConversionEnabled(true); - //WHEN + // WHEN MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); - //THEN + // THEN assertThat(actual).extracting(CODE_FIELD_NAME, ID_FIELD_NAME, PRICE_FIELD_NAME, ACTIVE_FIELD_NAME) .containsExactly( parseInt(fromFooPrimitiveTypes.getCode()), @@ -347,15 +347,15 @@ public void testAutomaticPrimitiveTypeTransformationWorksProperly() { */ @Test public void testThatBothPrimitiveTypeTransformationAndCustomTransformationAreExecuted() { - //GIVEN + // GIVEN double newPrice = PRICE * PRICE; FieldTransformer priceTransformer = new FieldTransformer<>(PRICE_FIELD_NAME, () -> newPrice); underTest.setPrimitiveTypeConversionEnabled(true).withFieldTransformer(priceTransformer); - //WHEN + // WHEN MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); - //THEN + // THEN assertThat(actual).extracting(CODE_FIELD_NAME, ID_FIELD_NAME, ACTIVE_FIELD_NAME, PRICE_FIELD_NAME) .containsExactly( parseInt(fromFooPrimitiveTypes.getCode()), @@ -372,7 +372,7 @@ public void testThatBothPrimitiveTypeTransformationAndCustomTransformationAreExe */ @Test public void testInjectValuesThrowsException() throws Exception { - //GIVEN + // GIVEN InvalidBeanException expectedException = new InvalidBeanException("Dummy exception"); TransformerImpl underTestMock = spy(TransformerImpl.class); ClassUtils classUtils = mock(ClassUtils.class); @@ -386,7 +386,7 @@ public void testInjectValuesThrowsException() throws Exception { TransformerImpl.class.getDeclaredMethod(INJECT_VALUES_METHOD_NAME, Object.class, Class.class, Constructor.class, String.class, boolean.class); injectValuesMethod.setAccessible(true); - //WHEN + // WHEN Object actual = injectValuesMethod.invoke(underTestMock, fromFooSimple, MutableToFooSimple.class, constructor, null, true); // THEN diff --git a/bull-common/src/test/java/com/hotels/beans/sample/record/FromFooRecord.java b/bull-common/src/test/java/com/hotels/beans/sample/record/FromFooRecord.java new file mode 100644 index 000000000..ef439a1a6 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/record/FromFooRecord.java @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.hotels.beans.sample.record; + +import java.math.BigInteger; + +/** + * Sample record object. + * @param id the id + * @param name the foo name + */ +public record FromFooRecord(BigInteger id, String name) { +} diff --git a/bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java new file mode 100644 index 000000000..8e9dc8760 --- /dev/null +++ b/bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java @@ -0,0 +1,23 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.hotels.beans.sample.record; + +import java.math.BigInteger; + +/** + * Sample record object. + * @param id the id + * @param name the foo name + */ +public record RecordToFoo(BigInteger id, String name) { +} diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java index 98ffb7d57..ed1a922b6 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java @@ -177,7 +177,7 @@ public void testGetFieldValueCatchesRuntimeException() { // WHEN Object actual = underTestMock.getFieldValue(mutableToFoo, LIST_FIELD_NAME, FromFooSubClass.class); - //THEN + // THEN assertThat(actual).isNull(); verify(underTestMock, times(1)).getDeclaredField(LIST_FIELD_NAME, MutableToFoo.class); } @@ -498,9 +498,9 @@ public void testGetDeclaredFieldWorksProperly(final String testCaseDescription, */ @Test public void testGetClassDeclaredFieldThrowsTheRightException() { - //GIVEN + // GIVEN - //WHEN + // WHEN Throwable actualException = catchThrowable(() -> { Method getClassDeclaredFieldMethod = underTest.getClass().getDeclaredMethod(GET_CLASS_DECLARED_FIELD_METHOD_NAME, String.class, Class.class); getClassDeclaredFieldMethod.setAccessible(true); @@ -785,14 +785,14 @@ private Object[][] dataInvokeMethodTesting() { */ @Test public void testGetSourceFieldValueRaisesAnExceptionIfTheParameterAreNull() throws Exception { - //GIVEN + // GIVEN Method getRealTargetMethod = getMethod(underTest.getClass(), GET_REAL_TARGET_METHOD_NAME, true, Object.class); Optional optionalBigInteger = Optional.of(ZERO); - //WHEN + // WHEN Object actual = getRealTargetMethod.invoke(underTest, optionalBigInteger); - //THEN + // THEN assertThat(actual).isEqualTo(ZERO); } diff --git a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java index 4d21d3aec..a0b0d7d45 100644 --- a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java @@ -80,9 +80,9 @@ public void beforeClass() { */ @Test(dataProvider = "dataIllegalArgumentExceptionTesting", expectedExceptions = IllegalArgumentException.class) public void testNotNullRaisesAnExceptionWhenTheGivenObjectIsNull(final String testCaseDescription, final Object elemToCheck, final String exceptionMessage) { - //GIVEN + // GIVEN - //WHEN + // WHEN if (nonNull(exceptionMessage)) { Validator.notNull(elemToCheck, exceptionMessage); } else { @@ -111,9 +111,9 @@ private Object[][] dataIllegalArgumentExceptionTesting() { @Test(dataProvider = "dataNoExceptionAreRaisedTesting") public void testThatNoExceptionAreThrownWhenTheGivenObjectIsNotNullEvenWithoutACustomMessage(final String testCaseDescription, final Object elemToCheck, final String exceptionMessage) { - //GIVEN + // GIVEN - //WHEN + // WHEN if (nonNull(exceptionMessage)) { Validator.notNull(elemToCheck, exceptionMessage); } else { @@ -138,10 +138,10 @@ private Object[][] dataNoExceptionAreRaisedTesting() { */ @Test(expectedExceptions = InvalidBeanException.class) public void testValidateThrowsExceptionWhenTheBeanIsInvalid() { - //GIVEN + // GIVEN MixedToFoo validBean = createTestBean(null); - //WHEN + // WHEN underTest.validate(validBean); } @@ -150,10 +150,10 @@ public void testValidateThrowsExceptionWhenTheBeanIsInvalid() { */ @Test public void testValidateDoesNotThrowsExceptionWhenTheBeanIsValid() { - //GIVEN + // GIVEN MixedToFoo validBean = createTestBean(ID); - //WHEN + // WHEN underTest.validate(validBean); } @@ -165,9 +165,9 @@ public void testValidateDoesNotThrowsExceptionWhenTheBeanIsValid() { */ @Test(dataProvider = "dataValidationConstraintsList") public void testGetConstraintViolationsWorksAsExpected(final String testCaseDescription, final Object elemToCheck, final int totalExpectedViolation) { - //GIVEN + // GIVEN - //WHEN + // WHEN List actual = underTest.getConstraintViolationsMessages(elemToCheck); // THEN diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java index 04a62665c..23323432e 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java @@ -165,9 +165,9 @@ byte[].class, String.class, new StringConversionProcessor().convertByteArray()} */ @Test(expectedExceptions = IllegalArgumentException.class) public void testConvertValueRaisesExceptionIfItsCalledWithNullTargetClassParam() { - //GIVEN + // GIVEN - //WHEN + // WHEN underTest.convertValue(ZERO, null); } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java index e419da5ea..b9cb40e61 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java @@ -47,12 +47,12 @@ public void beforeClass() { */ @Test public void testGetTransformerWorksProperly() { - //GIVEN + // GIVEN - //WHEN + // WHEN final MapTransformer transformer = underTest.getTransformer(); - //THEN + // THEN assertThat(transformer).isNotNull(); } } diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index ec64365db..58846db90 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -88,9 +88,9 @@ public void afterMethod() { @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformMethodWithTwoArgument") public void testTransformRaisesExceptionIfItsCalledWithNullParameter(final String testCaseDescription, final Map sourceMap, final BeanTransformer beanTransformer) { - //GIVEN + // GIVEN - //WHEN + // WHEN underTest.transform(sourceMap, beanTransformer); } @@ -115,12 +115,12 @@ private Object[][] dataTransformMethodWithTwoArgument() { */ @Test(dataProvider = "dataMapTransformerObject") public void testTransformWorksProperly(final String testCaseDescription, final Map sourceMap) { - //GIVEN + // GIVEN - //WHEN + // WHEN Map actual = underTest.transform(sourceMap); - //THEN + // THEN assertThat(actual).isEqualTo(sourceMap); } @@ -143,16 +143,16 @@ private Object[][] dataMapTransformerObject() { */ @Test public void testTransformWorksProperlyWithKeyMapping() { - //GIVEN + // GIVEN Map sourceMap = new HashMap<>(); sourceMap.put(MAP_KEY_1, ZERO); sourceMap.put(MAP_KEY_2, ONE); underTest.withFieldMapping(new FieldMapping<>(MAP_KEY_1, MAP_KEY_2)); - //WHEN + // WHEN Map actual = underTest.transform(sourceMap); - //THEN + // THEN assertThat(actual).containsOnly( entry(MAP_KEY_1, ZERO), entry(MAP_KEY_2, ZERO) @@ -165,16 +165,16 @@ public void testTransformWorksProperlyWithKeyMapping() { */ @Test public void testTransformWorksProperlyWithTransformer() { - //GIVEN + // GIVEN Map sourceMap = new HashMap<>(); sourceMap.put(MAP_KEY_1, ZERO); sourceMap.put(MAP_KEY_2, ONE); underTest.withKeyTransformer(new FieldTransformer(MAP_KEY_1, String::toUpperCase)); - //WHEN + // WHEN Map actual = underTest.transform(sourceMap); - //THEN + // THEN assertThat(actual).isNotNull(); assertThat(actual.size()).isEqualTo(sourceMap.size()); assertThat(actual).containsKey(MAP_KEY_1.toUpperCase()); @@ -185,12 +185,12 @@ public void testTransformWorksProperlyWithTransformer() { */ @Test(expectedExceptions = InvalidFunctionException.class) public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { - //GIVEN + // GIVEN Map sourceMap = new HashMap<>(); sourceMap.put(MAP_KEY_1, ZERO); underTest.withKeyTransformer(new FieldTransformer<>(MAP_KEY_1, ONE::add)); - //WHEN + // WHEN underTest.transform(sourceMap); } @@ -199,12 +199,12 @@ public void testTransformRaiseAnExceptionIfTheTransformerFunctionIsNotValid() { */ @Test public void testTransformWorksProperlyWithTargetKeyAndElemType() { - //GIVEN + // GIVEN - //WHEN + // WHEN Map actual = underTest.transform(EXTREME_COMPLEX_MAP, MutableToFooSimple.class, Map.class); - //THEN + // THEN assertThat(actual).isNotNull(); assertThat(actual.size()).isEqualTo(EXTREME_COMPLEX_MAP.size()); // check that the element has been converted @@ -218,13 +218,13 @@ public void testTransformWorksProperlyWithTargetKeyAndElemType() { @Test @SuppressWarnings("unchecked") public void testTransformWorksProperlyWithMapContainingList() { - //GIVEN + // GIVEN Map> sourceMap = newHashMap(fromFooSimple, list(ITEM_1)); - //WHEN + // WHEN Map actual = underTest.transform(sourceMap, MutableToFooSimple.class, List.class); - //THEN + // THEN assertThat(actual).allSatisfy((key, value) -> { assertThat(key).isInstanceOf(MutableToFooSimple.class); assertThat(value).containsOnly(ITEM_1); @@ -236,15 +236,15 @@ public void testTransformWorksProperlyWithMapContainingList() { */ @Test public void testResetKeyTransformerWorksProperly() { - //GIVEN + // GIVEN underTest.withKeyTransformer(new FieldTransformer(MAP_KEY_1, String::toUpperCase)); - //WHEN + // WHEN underTest.resetKeyTransformer(); MapTransformerSettings transformerSettings = (MapTransformerSettings) REFLECTION_UTILS.getFieldValue(underTest, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); - //THEN + // THEN assertThat(transformerSettings.getKeyFieldsTransformers()).isEmpty(); underTest.resetKeyTransformer(); } diff --git a/pom.xml b/pom.xml index 55fe08df8..31a5ce6bc 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ UTF-8 UTF-8 - 11 + 15 ${jdk.version} ${jdk.version} 1.18.20 @@ -82,7 +82,11 @@ 3.0.1 3.1.2 + 8.42 + 2.12.1 false + + **/*Record*.java true false true @@ -344,6 +348,7 @@ ${maven.compiler.target} true true + --enable-preview @@ -377,6 +382,13 @@ org.apache.maven.plugins maven-checkstyle-plugin ${maven.checkstyle.plugin.version} + + + com.puppycrawl.tools + checkstyle + ${puppycrawl.checkstyle.version} + + process-sources @@ -391,6 +403,7 @@ true ${checkstyle.check.skip} ${checkstyle.includeTestSourceDirectory} + ${checkstyle.exclusion} @@ -401,6 +414,7 @@ ${maven.surefire.plugin.version} false + --enable-preview @@ -668,7 +682,7 @@ com.diffplug.spotless spotless-maven-plugin - ${spotless.maven.plugin.version} + ${maven.spotless.plugin.version} process-sources From 543e3823b90bab10b8661794aebb9300b3d79470 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 10:42:37 +0200 Subject: [PATCH 1303/1786] fixes a typo error in the travis.yml configuration --- .travis.yml | 2 +- .../RecordObjectTransformationTest.java | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 bull-bean-transformer/src/test/java/com/hotels/beans/transformer/RecordObjectTransformationTest.java diff --git a/.travis.yml b/.travis.yml index 3dc08e325..986a999c2 100755 --- a/.travis.yml +++ b/.travis.yml @@ -60,7 +60,7 @@ jobs: - stage: "JDK15 Release" name: "Releasing artifacts for JDK15" jdk: openjdk15 - if: type NOT IN (pull_request) AND tag IS present AAND tag =~ ^.*-jdk15$ + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk15$ script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/RecordObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/RecordObjectTransformationTest.java new file mode 100644 index 000000000..53d07212f --- /dev/null +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/RecordObjectTransformationTest.java @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.hotels.beans.transformer; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.testng.annotations.Test; + +import com.hotels.beans.sample.record.FromFooRecord; +import com.hotels.beans.sample.record.RecordToFoo; + +/** + * Unit test for all {@link BeanTransformer} functions related to a Java record. + */ +public class RecordObjectTransformationTest extends AbstractBeanTransformerTest { + /** + * Test that the transformation between Records works properly. + */ + @Test + public void testRecordIsCorrectlyCopied() { + // GIVEN + var sourceObject = new FromFooRecord(ID, NAME); + + // WHEN + var actual = underTest.transform(sourceObject, RecordToFoo.class); + + // THEN + assertThat(actual).usingRecursiveComparison() + .ignoringAllOverriddenEquals() + .isEqualTo(sourceObject); + } + + /** + * Test that the transformation from a bean to a records works properly. + */ + @Test + public void testThatARecordIsCorrectlyCopiedFromANormalBean() { + // GIVEN + + // WHEN + var actual = underTest.transform(fromFoo, RecordToFoo.class); + + // THEN + assertThat(actual) + .extracting(ID_FIELD_NAME, NAME_FIELD_NAME) + .containsExactly(fromFoo.getId(), fromFoo.getName()); + } + +} From 9dd02bb2da88ec1b5466622bd00f67ee86692911 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 10:44:47 +0200 Subject: [PATCH 1304/1786] fixes a typo error in the travis.yml configuration --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 986a999c2..28207fd5c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ env: # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= jdk: + - openjdk11 - openjdk15 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip From eb89067adf632f21a7ccb7d8c783747be5b3b4fe Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 10:45:18 +0200 Subject: [PATCH 1305/1786] fixes a typo error in the travis.yml configuration --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 28207fd5c..39c1a96bc 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,9 +11,7 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -jdk: - - openjdk11 - - openjdk15 +jdk: openjdk15 script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: From 55e7698295d682b8c098b388dff269bff1196750 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 10:49:05 +0200 Subject: [PATCH 1306/1786] Creates a step for the main build --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 39c1a96bc..6432eb39b 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,11 +11,14 @@ env: - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= # GPG_PASSPHRASE - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= -jdk: openjdk15 -script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode install: skip jobs: include: + ### Build + - stage: "Build" + name: "Build and Test" + jdk: openjdk15 + script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode ### JDK8 build - stage: "JDK8 Build" name: "JDK8 Build and Test" From 5ed8ded4e2ff5ce60cd507b0c9703ade7717affb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 10:54:32 +0200 Subject: [PATCH 1307/1786] Modifies the travis build to create perform the quality check even for jdk15 version --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6432eb39b..3d14fcffd 100755 --- a/.travis.yml +++ b/.travis.yml @@ -28,8 +28,8 @@ jobs: - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - stage: "Site Build and Quality check" name: "Publishing site and performing a code quality check" - jdk: openjdk11 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ AND tag =~ ^((?!-jdk15).)*$ + jdk: openjdk15 + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn From f2011ab3ff4bf208edf54d360ff99629461ce2a6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 11:04:17 +0200 Subject: [PATCH 1308/1786] code improvements --- .../hotels/beans/populator/OptionalPopulator.java | 2 +- .../hotels/beans/transformer/TransformerImpl.java | 5 ++--- .../ImmutableObjectTransformationTest.java | 5 +++-- .../com/hotels/transformer/utils/ClassUtils.java | 10 +++++----- .../hotels/transformer/utils/ReflectionUtils.java | 10 +++++----- .../hotels/transformer/validator/ValidatorImpl.java | 4 ++-- .../com/hotels/beans/sample/record/RecordToFoo.java | 3 +++ .../hotels/map/transformer/MapTransformerTest.java | 13 +++++++------ 8 files changed, 28 insertions(+), 24 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java index 89003a2d9..0a25446ef 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java @@ -41,7 +41,7 @@ class OptionalPopulator extends Populator { @Override public Object getPopulatedObject(final Field field, final Object fieldValue) { Object res = null; - Optional optionalFieldValue = (Optional) fieldValue; + var optionalFieldValue = (Optional) fieldValue; if (optionalFieldValue.isPresent()) { res = transform(optionalFieldValue.get(), field.getType()); } diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 632887e9b..ebbbf9f6c 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -43,7 +43,6 @@ import java.util.function.Consumer; import com.hotels.transformer.annotation.ConstructorArg; -import com.hotels.transformer.constant.ClassType; import com.hotels.transformer.error.InvalidBeanException; import com.hotels.transformer.error.MissingFieldException; import com.hotels.transformer.model.FieldTransformer; @@ -118,7 +117,7 @@ protected final void transform(final T sourceObj, final K targetObject, f */ private K injectValues(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final ClassType classType = classUtils.getClassType(targetClass); + final var classType = classUtils.getClassType(targetClass); if (classType.is(MUTABLE)) { try { k = classUtils.getNoArgsConstructor(targetClass).get(); @@ -238,7 +237,7 @@ protected boolean canBeInjectedByConstructorParams(final Constructor constructor */ protected Object[] getConstructorArgsValues(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb) { final Parameter[] constructorParameters = classUtils.getConstructorParameters(constructor); - final Object[] constructorArgsValues = new Object[constructorParameters.length]; + final var constructorArgsValues = new Object[constructorParameters.length]; range(0, constructorParameters.length) //.parallel() .forEach(i -> { diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java index 17b949748..da48bfaab 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java @@ -362,8 +362,9 @@ public void testGetConstructorValuesFromFieldsWorksProperly() throws Exception { Object[] actual = (Object[]) getConstructorValuesFromFieldsMethod.invoke(underTest, fromFooAdvFields, ImmutableToFooAdvFields.class, ""); // THEN - assertThat(actual).isNotNull(); - assertThat(actual.length).isEqualTo(TOTAL_ADV_CLASS_FIELDS); + assertThat(actual) + .isNotNull() + .hasSize(TOTAL_ADV_CLASS_FIELDS); // restore modified objects restoreObjects(getConstructorValuesFromFieldsMethod); diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java index fe86ee152..e337d02f1 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java @@ -481,7 +481,7 @@ public Optional> getBuilderClass(final Class targetClass) { return CACHE_MANAGER.getFromCache(cacheKey, Optional.class).orElseGet(() -> { Optional res = stream(getDeclaredClasses(targetClass)) .filter(nestedClass -> { - boolean hasBuildMethod = true; + var hasBuildMethod = true; try { getBuildMethod(targetClass, nestedClass); } catch (MissingMethodException e) { @@ -505,7 +505,7 @@ public Method getBuildMethod(final Class parentClass, final Class builderC final String cacheKey = "BuildMethod-" + builderClass.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { - Method method = builderClass.getDeclaredMethod(BUILD_METHOD_NAME); + var method = builderClass.getDeclaredMethod(BUILD_METHOD_NAME); if (!method.getReturnType().equals(parentClass)) { throw new MissingMethodException("Invalid " + BUILD_METHOD_NAME + " method definition. It must returns a: " + parentClass.getCanonicalName()); } @@ -547,7 +547,7 @@ public Supplier getNoArgsConstructor(final Class clazz) { final String cacheKey = "NoArgsConstructor-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Supplier.class).orElseGet(() -> { try { - MethodHandles.Lookup privateLookupIn = privateLookupIn(clazz, METHOD_HANDLES_LOOKUP); + var privateLookupIn = privateLookupIn(clazz, METHOD_HANDLES_LOOKUP); MethodHandle mh = privateLookupIn.findConstructor(clazz, methodType(void.class)); Supplier constructor = (Supplier) metafactory( privateLookupIn, "get", methodType(Supplier.class), mh.type().generic(), mh, mh.type() @@ -571,7 +571,7 @@ public Constructor getAllArgsConstructor(final Class clazz) { final String cacheKey = "AllArgsConstructor-" + clazz.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Constructor.class).orElseGet(() -> { Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); - final Constructor constructor = max(asList(declaredConstructors), comparing(Constructor::getParameterCount)); + final var constructor = max(asList(declaredConstructors), comparing(Constructor::getParameterCount)); constructor.setAccessible(true); CACHE_MANAGER.cacheObject(cacheKey, constructor); return constructor; @@ -601,7 +601,7 @@ public Parameter[] getConstructorParameters(final Constructor constructor) { public boolean hasField(final Object target, final String fieldName) { final String cacheKey = "ClassHasField-" + target.getClass().getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - boolean hasField = false; + var hasField = false; try { target.getClass().getDeclaredField(fieldName); hasField = true; diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java index a59395dc9..7ed9ddcc9 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java @@ -184,7 +184,7 @@ private Method getGetterMethod(final Class fieldClass, final String fieldName final String cacheKey = "GetterMethod-" + fieldClass.getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { - Method method = fieldClass.getMethod(getGetterMethodPrefix(fieldType) + capitalize(fieldName)); + var method = fieldClass.getMethod(getGetterMethodPrefix(fieldType) + capitalize(fieldName)); method.setAccessible(true); CACHE_MANAGER.cacheObject(cacheKey, method); return method; @@ -206,7 +206,7 @@ private Function getGetterMethodFunction(final Class fieldClass, final String Function function; try { Class fieldType = getDeclaredFieldType(fieldName, fieldClass); - MethodHandles.Lookup privateLookupIn = privateLookupIn(fieldClass, METHOD_HANDLES_LOOKUP); + var privateLookupIn = privateLookupIn(fieldClass, METHOD_HANDLES_LOOKUP); CallSite site = metafactory(privateLookupIn, "apply", methodType(Function.class), @@ -278,7 +278,7 @@ private A getAnnotation(final AnnotatedElement element, f */ private Object getFieldValueDirectAccess(final Object target, final String fieldName) { try { - Field field = getDeclaredField(fieldName, target.getClass()); + var field = getDeclaredField(fieldName, target.getClass()); return field.get(target); } catch (MissingFieldException e) { throw e; @@ -438,7 +438,7 @@ public Method getSetterMethodForField(final Class fieldClass, final String fi final String cacheKey = "SetterMethod-" + fieldClass.getName() + '-' + fieldName; return CACHE_MANAGER.getFromCache(cacheKey, Method.class).orElseGet(() -> { try { - Method method = fieldClass.getMethod(SET.getPrefix() + capitalize(fieldName), fieldType); + var method = fieldClass.getMethod(SET.getPrefix() + capitalize(fieldName), fieldType); method.setAccessible(true); CACHE_MANAGER.cacheObject(cacheKey, method); return method; @@ -524,7 +524,7 @@ public MapType getMapGenericType(final Type fieldType, final String declaringCla keyType = buildItemType(fieldType, declaringClass, fieldName); elemType = buildItemType(fieldType, declaringClass, fieldName); } - final MapType mapType = new MapType(keyType, elemType); + final var mapType = new MapType(keyType, elemType); CACHE_MANAGER.cacheObject(cacheKey, mapType); return mapType; }); diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java index d1e666dbe..621a8ce54 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java @@ -101,10 +101,10 @@ private Function, String> getConstraintViolationMess * @return a {@link javax.validation.Validator} instance. */ private jakarta.validation.Validator getValidator() { - String cacheKey = "BeanValidator"; + var cacheKey = "BeanValidator"; return cacheManager.getFromCache(cacheKey, jakarta.validation.Validator.class) .orElseGet(() -> { - jakarta.validation.Validator validator = buildDefaultValidatorFactory().getValidator(); + var validator = buildDefaultValidatorFactory().getValidator(); cacheManager.cacheObject(cacheKey, validator); return validator; }); diff --git a/bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java b/bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java index 8e9dc8760..5b95d3276 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java @@ -1,9 +1,12 @@ /** * Copyright (C) 2019-2021 Expedia, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 58846db90..2850cba45 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -87,7 +87,7 @@ public void afterMethod() { */ @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "dataTransformMethodWithTwoArgument") public void testTransformRaisesExceptionIfItsCalledWithNullParameter(final String testCaseDescription, - final Map sourceMap, final BeanTransformer beanTransformer) { + final Map sourceMap, final BeanTransformer beanTransformer) { // GIVEN // WHEN @@ -100,7 +100,7 @@ public void testTransformRaisesExceptionIfItsCalledWithNullParameter(fina */ @DataProvider private Object[][] dataTransformMethodWithTwoArgument() { - return new Object[][] { + return new Object[][]{ {"Test that an IllegalArgumentException is thrown if the sourceMap is null", null, BEAN_TRANSFORMER}, {"Test that an IllegalArgumentException is thrown if the transformer is null", SAMPLE_MAP, null} }; @@ -130,7 +130,7 @@ public void testTransformWorksProperly(final String testCaseDescription, */ @DataProvider private Object[][] dataMapTransformerObject() { - return new Object[][] { + return new Object[][]{ {"Test that a simple Map is correctly transformed", SAMPLE_MAP}, {"Test that a Map containing a list is correctly transformed", COMPLEX_MAP}, {"Test that a Map containing a Map is correctly transformed", VERY_COMPLEX_MAP}, @@ -175,9 +175,10 @@ public void testTransformWorksProperlyWithTransformer() { Map actual = underTest.transform(sourceMap); // THEN - assertThat(actual).isNotNull(); - assertThat(actual.size()).isEqualTo(sourceMap.size()); - assertThat(actual).containsKey(MAP_KEY_1.toUpperCase()); + assertThat(actual) + .isNotNull() + .hasSize(sourceMap.size()) + .containsKey(MAP_KEY_1.toUpperCase()); } /** From 15dd273f528b759b6ae3b57abff1b450a6a545c8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 11:10:33 +0200 Subject: [PATCH 1309/1786] Improves the documentation and prepares the release --- CHANGELOG-JDK15.md | 272 +----------------- README.md | 2 +- docs/site/markdown/index.md | 1 + .../site/markdown/transformer/bean/samples.md | 14 + pom.xml | 2 +- 5 files changed, 18 insertions(+), 273 deletions(-) diff --git a/CHANGELOG-JDK15.md b/CHANGELOG-JDK15.md index 8e6924f33..1fd14474e 100755 --- a/CHANGELOG-JDK15.md +++ b/CHANGELOG-JDK15.md @@ -5,274 +5,4 @@ All notable changes to this project will be documented in this file. ### [1.8.0-jdk15] 2021.06.18 #### Added * Increase the jdk version to 15 -* Enables the [Java Record](https://blogs.oracle.com/javamagazine/records-come-to-java) transformation - -### [1.7.4] 2020.10.07 -#### Changed -* Provides new utilities methods - -### [1.7.3] 2020.06.09 -#### Changed -* Removes the deprecated method: `setDefaultValueSetEnabled` - -### [1.7.2] 2020.06.09 -#### Changed -* Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` -* Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). - -### [1.7.1] 2020.03.21 -#### Added -* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). -#### Changed -* Updated `hibernate-validator` version to `6.1.4.Final` (was `6.1.2.Final`). - -### [1.6.6] 2020.03.16 -#### Changed -* Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). -* Updated `commons-lang3` version to `3.10` (was `3.9`). - -### [1.6.5] 2020.01.21 -#### Changed -* Testing dependencies update - -### [1.6.4] 2019.12.24 -#### Added -* Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). -* Implemented transformation of a field declared with its interface. - -### [1.6.3.2] 2019.12.19 -#### Added -* Added method for retrieving the class getter methods. - -### [1.6.3.1] 2019.12.09 -#### Changed -* Testing dependencies update - -### [1.6.3] 2019.12.02 -### Added -* Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. -* Modified Travis configuration in order to test the compatibility with other JDKs versions - -### [1.6.2] 2019.11.22 -#### Changed -* Removed warning leg message in case the constructor parameter names are not available in the compiled code. -* Removed `slf4j-api` dependency from the library jar. - -### [1.6.1] 2019.11.18 -### Added -* Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. -#### Changed -* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). - -### [1.6.0.2] 2019.10.30 -### Removed -* Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` -* The following deprecated classes has been removed: - * `com.hotels.beans.model.FieldMapping` - * `com.hotels.beans.model.FieldTransformer` - * `com.hotels.beans.Transformer` -### Added -* New specific exception in case the Field Transformation function defined is not valid -* Implemented a new functionality that allows to transform also Map object applying transformation function and mappings -#### Changed -* `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` -* Updated `hibernate-validator` version to `6.1.0.Final` (was `6.0.17.Final`). - -### [1.5.1] 2019.09.02 -#### Changed -* **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** - ```xml - - com.hotels.beans - bull-bean-transformer - x.y.z - - ``` -* Module `bean-utils-library` has been relocated into `bull-bean-transformer`. -* The following classes has been deprecated, please find below the complete list and the new one to be used: - - | Deprecated | **New one** | - | :----------- | :----------- | - | `com.hotels.beans.model.FieldMapping` | `com.hotels.transformer.model.FieldMapping` | - | `com.hotels.beans.model.FieldTransformer` | `com.hotels.transformer.model.FieldTransformer` | - | `com.hotels.beans.Transformer` | `com.hotels.transformer.Transformer` | - -### [1.5.0] 2019.08.06 -#### Added -* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). -#### Changed -* Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled -* Modified Transformer initialization in order to create a `ConversionAnalyzer` instance only if the automatic conversion is enabled - -### [1.4.7.1] [1.4.7.2] [1.4.7.3] 2019.07.05 -#### Changed -* Changed sonatype credential - -### [1.4.7] 2019.07.03 -#### Added -* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/HotelsDotCom/bull/issues/73)). - -### [1.4.6] 2019.06.27 -#### Changed -* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/HotelsDotCom/bull/issues/70)). - -### [1.4.5] 2019.06.05 -#### Added -* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). -* Added check during project build in order to prevent the add different versions of the same dependency. -#### Changed -* Modified library in order to let it able to retrieve values from getters if a field does not exist (see: [Issue 66](https://github.com/HotelsDotCom/bull/issues/66)). - -### [1.4.4.1] 2019.05.29 -#### Changed -* Improved Javadoc -* Added reference to the articles published on **DZone** and **InfoQ** - -### [1.4.2] 2019.05.24 -#### Added -* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/HotelsDotCom/bull/issues/62)). -#### Fixed -* Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). - -### [1.4.1.1] 2019.05.24 -#### Changed -* Made the project multi module - -### [1.4.1] 2019.05.18 -#### Changed -* Removed deprecated method: `setValidationDisabled` -* Testing dependencies update - -### [1.4.0] 2019.05.13 -#### Changed -* **Modified project behaviour:** since this version the **"Bean Validation" is disabled by default**, to enable it, the following instruction needs to be executed: `transformer.setValidationEnabled(true);` - -### [1.3.2] 2019.05.11 -### Added -* Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/HotelsDotCom/bull/issues/57)). - -### [1.3.1] 2019.05.08 -#### Changed -* In order to improve the library performances the following Changed have been applied: - * Modified no args constructor invocation in order to use `LambdaMetafactory` - * Modified field value retrieval in order to use `LambdaMetafactory` - * Modified value retrieval/set from/to source/destination object in order to minimise the executed actions -* Updated `hotels-oss-parent` version to `4.0.1` (was `4.0.0`). - -### [1.3.0] 2019.04.28 -#### Added -* Added support for the transformation of Java Beans built through Builder - -### [1.2.7] 2019.04.18 -#### Changed -* Improved optional usage. -* Fixed a bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). - -### [1.2.6] 2019.04.06 -#### Added -* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). - -### [1.2.5] 2019.03.31 -#### Added -* Improved field value retrieval function. - -### [1.2.4] 2019.03.23 -#### Changed -* Added caching for method: `getDeclaredField` - -### [1.2.3] 2019.03.22 -#### Added -* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/HotelsDotCom/bull/issues/38)) -* Performance improvement - -### [1.2.2] 2019.03.20 -#### Changed -* Testing dependencies update - -### [1.2.1] 2019.03.05 -#### Added -* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) -* Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` - -### [1.2.0] 2019.02.25 -#### Added -* Added possibility to skip the object validation (see: [Issue 31](https://github.com/HotelsDotCom/bull/issues/31)) -* Provided documentation and samples for the above functionality -### Changed -- Updated `jdk` version to `11` (was `1.8`). -- Updated Travis configuration in order to work with java 11 -- Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created - -### [1.1.4] 2019.02.20 -#### Added -* Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/HotelsDotCom/bull/issues/27)). -* Added possibility to apply a transformation function on all fields matching with the given name without evaluating the full field path. -* Added samples and tests for the above functionality -#### Fixed -* Fixed issue that was preventing the `Set` transformation - -### [1.1.3] 2019.02.17 -#### Added -* Added static transformation functionality (see: [Issue 25](https://github.com/HotelsDotCom/bull/issues/25)). - -### [1.1.2] 2019.02 -#### Added -* Made the field name mapping more flexible adding the possibility to map destination object field with field contained into nested objects. -* Added samples and tests for the above functionality. -#### Changed -* Updated hibernate dependency: `org.hibernate.validator` (was `org.hibernate.validator`). -* Removed `parallel` execution where not needed because this could cause performance degradation. - -### [1.1.1] 2019.02.09 -#### Changed -* Improved exception messaging in order to simplify the troubleshooting process -* Improved readme file - -### [1.1.0] 2019.02.04 -#### Added -* Added dependency to: `slf4j-api` as no longer available from Spring. -- Added ValidationUtils class for raising an `IllegalArgumentException` in case any parameter is null. -#### Removed -* Removed dependency: `spring-boot-starter-validation` and imported one by one the required validation dependencies -* Removed dependency: `spring-boot-starter-cache` and imported one by one the required validation dependencies - -### [1.0.17] 2019.02.03 -#### Changed -* Improved package-info comments -#### Added -* Configured Travis in order to automatically release artifacts - -### [1.0.16] 2019.01.26 -#### Changed -* Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). -* Updated `hotels-oss-parent` version to `4.0.0` (was `2.3.5`). -#### Added -* Configured Travis in order to automatically build the application, perform a quality check and publish site. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) -* Added build, test coverage and security badge to readme file. - -### [1.0.15] 2019.01.23 -#### Added -* Added GitHub site build with maven. - -### [1.0.14] 2019.01.18 -#### Added -* Added possibility to configure the transformer in order to set the default value for all destination's object fields that are not existing in the source object. - See [README.md](https://github.com/HotelsDotCom/bull/blob/master/README.md) for more details. -#### Changed -* Jumped to version `1.0.14` in order to be consequent to the previous library version hosted on a private repo. - -### [1.0.3] 2019.01.17 -#### Added -* Added changelog file. - -### [1.0.2] 2019.01.17 -#### Changed -* Removed not needed comments - -### [1.0.1] 2019.01.17 -#### Changed -* Added maven build info to the readme file. - -### [1.0.0] 2019.01.16 -#### Added -* First `BULL` release. +* Enables the [Java Record](https://blogs.oracle.com/javamagazine/records-come-to-java) transformation \ No newline at end of file diff --git a/README.md b/README.md index 00c6096b9..1b4e88ccd 100644 --- a/README.md +++ b/README.md @@ -736,7 +736,7 @@ ToBean toBean = new BeanTransformer() .transform(sourceObject, ToBean.class); ``` -## Java Record transformation samples +## Transform Java Record ### Simple case: diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 6792ef08d..6105bddfc 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -17,6 +17,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho * support copy of immutable beans. * support copy of mutable beans. * support copy of hybrid beans (some fields private and some not). +* support copy of Java Records. * support copy of Java beans without getter and setter methods. * support copy with Java primitive type. * support copy with Java Collection type. e.g. `List => List` diff --git a/docs/site/markdown/transformer/bean/samples.md b/docs/site/markdown/transformer/bean/samples.md index 08dff474a..de50e5415 100644 --- a/docs/site/markdown/transformer/bean/samples.md +++ b/docs/site/markdown/transformer/bean/samples.md @@ -480,4 +480,18 @@ Transformer transformer = beanUtils.getTransformer() ToBean toBean = transformer.transform(fromBean, ToBean.class); ``` +## Transform Java Record + +### Simple case: + +```java +public record FromFooRecord { public record RecordToFoo(BigInteger id, String name) { +} } +``` +And one line code as: + +```java +var toBean = beanUtils.getTransformer().transform(fromBean, RecordToFoo.class); +``` + More sample beans can be found in the test package: `com.hotels.beans.sample` or on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) \ No newline at end of file diff --git a/pom.xml b/pom.xml index 31a5ce6bc..5b97d1dbf 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.7.7-SNAPSHOT + 1.8.0-jdk15-SNAPSHOT pom 2019 From d6279f6170e53640cc4c1fd635c75a2f2143188a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 11:12:31 +0200 Subject: [PATCH 1310/1786] changes the project version --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index f1f585b1b..ea5d07a2d 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.7-SNAPSHOT + 1.8.0-jdk15-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index e6bf1c90c..3d948cc12 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.7-SNAPSHOT + 1.8.0-jdk15-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e30be3edf..47df6c87d 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.7-SNAPSHOT + 1.8.0-jdk15-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index f0f40ade5..30519ee2c 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.7.7-SNAPSHOT + 1.8.0-jdk15-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f6760c9f7..760746086 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.7-SNAPSHOT + 1.8.0-jdk15-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 8cc9da971..0d31a1a7f 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.7.7-SNAPSHOT + 1.8.0-jdk15-SNAPSHOT From 2be5ed13bf1b5809a60b929ecd0c3906d8e16b6c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 11:24:34 +0200 Subject: [PATCH 1311/1786] * increase the release version * removes any reference to the jdk11 --- .travis.yml | 16 ---------------- CHANGELOG-JDK15.md | 8 -------- CHANGELOG.md | 7 ++++++- README.md | 5 +---- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 14 insertions(+), 36 deletions(-) delete mode 100755 CHANGELOG-JDK15.md diff --git a/.travis.yml b/.travis.yml index 3d14fcffd..765e6a0bc 100755 --- a/.travis.yml +++ b/.travis.yml @@ -42,22 +42,6 @@ jobs: keep-history: true on: tags: true - ### JDK11 release - - stage: "JDK11 Release" - name: "Releasing artifacts for JDK11" - jdk: openjdk11 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ AND tag =~ ^((?!-jdk15).)*$ - script: skip - before_deploy: - - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true ### JDK15 release - stage: "JDK15 Release" name: "Releasing artifacts for JDK15" diff --git a/CHANGELOG-JDK15.md b/CHANGELOG-JDK15.md deleted file mode 100755 index 1fd14474e..000000000 --- a/CHANGELOG-JDK15.md +++ /dev/null @@ -1,8 +0,0 @@ -# BULL Change Log (`jdk 15` or above) - -All notable changes to this project will be documented in this file. - -### [1.8.0-jdk15] 2021.06.18 -#### Added -* Increase the jdk version to 15 -* Enables the [Java Record](https://blogs.oracle.com/javamagazine/records-come-to-java) transformation \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 727ec911c..27ea433d4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ -# BULL Change Log (`jdk 11` or above) +# BULL Change Log All notable changes to this project will be documented in this file. +### [2.0.0] 2021.06.18 +#### Added +* Increase the jdk version to 15 +* Enables the [Java Record](https://blogs.oracle.com/javamagazine/records-come-to-java) transformation + ### [1.7.6] 2021.01.11 #### Added * Provides new module `bull-bom` that includes all the project modules diff --git a/README.md b/README.md index 1b4e88ccd..1d85edad2 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,7 @@ It contains all the modules available in the project **The project provides two different builds**, one compatible with `jdk 8` (or above) and one with `jdk 11` or above. -In case you need to integrate it in a: -* `jdk 8` based project please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) -* `jdk 11` based project please refer to [CHANGELOG-JDK8](CHANGELOG.md) -* `jdk 15 or above` based project please refer to [CHANGELOG-JDK15](CHANGELOG-JDK15.md) +In case you need to integrate it in a `jdk 8` please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) file or [CHANGELOG](CHANGELOG.md) otherwise. * #### Suggestions diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index ea5d07a2d..080829da9 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 1.8.0-jdk15-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 3d948cc12..272a4bf5d 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.8.0-jdk15-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 47df6c87d..60da82d0e 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.8.0-jdk15-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 30519ee2c..c610b992b 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 1.8.0-jdk15-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 760746086..555f263b6 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 1.8.0-jdk15-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 0d31a1a7f..c3e3d9d8d 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 1.8.0-jdk15-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 5b97d1dbf..d64a7d444 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 1.8.0-jdk15-SNAPSHOT + 2.0.0-SNAPSHOT pom 2019 From 5348a3ccec213d3c4fdcd883d6a9fd2274bc6a01 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 11:29:31 +0200 Subject: [PATCH 1312/1786] modifies the travis release configuration --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 765e6a0bc..2e3f60ba7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -46,7 +46,7 @@ jobs: - stage: "JDK15 Release" name: "Releasing artifacts for JDK15" jdk: openjdk15 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk15$ + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d From 97280579d5fbbb2cf68b46a65886c92701f789be Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 12:00:07 +0200 Subject: [PATCH 1313/1786] Converts object to record where possible --- .../hotels/beans/populator/MapPopulator.java | 8 ++++---- .../beans/populator/ArrayPopulatorTest.java | 2 +- .../transformer/AbstractTransformer.java | 2 +- .../transformer/cache/CacheManager.java | 13 ++---------- .../transformer/model/FieldMapping.java | 20 +++---------------- .../hotels/transformer/model/ItemType.java | 17 +++------------- .../com/hotels/transformer/model/MapType.java | 19 +++--------------- pom.xml | 5 ++++- 8 files changed, 21 insertions(+), 65 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java index a2604e1f6..c444fc5a9 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java @@ -54,8 +54,8 @@ class MapPopulator extends Populator> { * @return the populated map */ private Map getPopulatedObject(final Map fieldValue, final MapType mapType) { - final MapElemType keyType = mapType.getKeyType(); - final MapElemType elemType = mapType.getElemType(); + final MapElemType keyType = mapType.keyType(); + final MapElemType elemType = mapType.elemType(); final boolean keyIsPrimitive = isPrimitive(keyType); final boolean elemIsPrimitive = isPrimitive(elemType); Map populatedObject; @@ -78,7 +78,7 @@ class MapPopulator extends Populator> { * @return true if it's primitive, false otherwise */ private boolean isPrimitive(final MapElemType mapElemType) { - return mapElemType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) mapElemType).getObjectClass()); + return mapElemType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) mapElemType).objectClass()); } /** @@ -96,7 +96,7 @@ private T getElemValue(final MapElemType mapElemType, final boolean elemIsPr elemValue = value; } else { if (mapElemType.getClass().equals(ItemType.class)) { - elemValue = (T) transform(value, ((ItemType) mapElemType).getObjectClass(), ((ItemType) mapElemType).getGenericClass()); + elemValue = (T) transform(value, ((ItemType) mapElemType).objectClass(), ((ItemType) mapElemType).genericClass()); } else { elemValue = (T) getPopulatedObject((Map) value, (MapType) mapElemType); } diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java index 27404c0d8..b89818b2e 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java @@ -86,7 +86,7 @@ public void testGetPopulatedObjectWorksProperly(final Class genericFieldType, assertThat((Object[]) actual).isEqualTo(array); } else if (genericFieldType == MixedToFooStaticField.class) { assertThat((Object[]) actual) - .usingElementComparatorOnFields(NORMAL_FIELD) + .usingRecursiveFieldByFieldElementComparatorOnFields(NORMAL_FIELD) .isEqualTo(array); } else { assertThat(actual).isEqualTo(array); diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java index e4bb79172..759e25648 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java @@ -84,7 +84,7 @@ protected AbstractTransformer(final String transformerFunctionCachePrefix, final public final T withFieldMapping(final FieldMapping... fieldMapping) { final Map fieldsNameMapping = settings.getFieldsNameMapping(); for (FieldMapping mapping : fieldMapping) { - fieldsNameMapping.put((P) mapping.getDestFieldName(), (P) mapping.getSourceFieldName()); + fieldsNameMapping.put((P) mapping.destFieldName(), (P) mapping.sourceFieldName()); } return (T) this; } diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java index 81c75651a..c9e8b3ce8 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java @@ -18,23 +18,14 @@ import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; -import static lombok.AccessLevel.PROTECTED; - import java.util.Map; import java.util.Optional; -import lombok.AllArgsConstructor; - /** * Cache Utils class. + * @param cacheMap the ache store */ -@AllArgsConstructor(access = PROTECTED) -public final class CacheManager { - /** - * Cache store. - */ - private final Map cacheMap; - +public record CacheManager(Map cacheMap) { /** * Caches the given object. * @param cacheKey the cache key. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java index 1b2a8964b..60b500276 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java @@ -15,26 +15,12 @@ */ package com.hotels.transformer.model; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; - /** * Specifies the field's name mapping between the source object and destination one. * @param source element type * @param target element type + * @param sourceFieldName the field name in the source object + * @param destFieldName the field name in the destination object. */ -@AllArgsConstructor -@Getter -@ToString -public class FieldMapping { - /** - * The field name in the source object. - */ - private final T sourceFieldName; - - /** - * The field name in the destination object. - */ - private final K destFieldName; +public record FieldMapping(T sourceFieldName, K destFieldName) { } diff --git a/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java b/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java index 4f7edc244..610c05187 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java @@ -16,23 +16,12 @@ package com.hotels.transformer.model; import lombok.Builder; -import lombok.Getter; /** * Bean class for mapping the "Generic" object type and its nested generic (if any). + * @param objectClass the object class. i.e. In case of: {@code Map, Integer>} the value wil be {@code List} + * @param genericClass the generic object class in the key object (if any). i.e. In case of: {@code Map, Integer>} the value wil be {@code String} */ -@Getter @Builder -public class ItemType implements MapElemType { - /** - * The object class. - * i.e. In case of: {@code Map, Integer>} the value wil be {@code List} - */ - private final Class objectClass; - - /** - * The generic object class in the key object (if any). - * i.e. In case of: {@code Map, Integer>} the value wil be {@code String} - */ - private final Class genericClass; +public record ItemType(Class objectClass, Class genericClass) implements MapElemType { } diff --git a/bull-common/src/main/java/com/hotels/transformer/model/MapType.java b/bull-common/src/main/java/com/hotels/transformer/model/MapType.java index cf71b302f..00dda2c89 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/MapType.java +++ b/bull-common/src/main/java/com/hotels/transformer/model/MapType.java @@ -15,23 +15,10 @@ */ package com.hotels.transformer.model; -import lombok.AllArgsConstructor; -import lombok.Getter; - /** * Bean class for mapping the java.util.Map type. + * @param keyType key object class + * @param elemType elem object class */ -@AllArgsConstructor -@Getter -public class MapType implements MapElemType { - /** - * key object class. - */ - private final MapElemType keyType; - - /** - * elem object class. - */ - private final MapElemType elemType; - +public record MapType(MapElemType keyType, MapElemType elemType) implements MapElemType { } diff --git a/pom.xml b/pom.xml index d64a7d444..a58562a6d 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,10 @@ 2.12.1 false - **/*Record*.java + + **/*Record*.java, + **/ItemType.java + true false true From 62a81ca4bfad3a06010763539565047dec59d66d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 12:05:29 +0200 Subject: [PATCH 1314/1786] Changes the code with the latest java code style --- .mvn/wrapper/MavenWrapperDownloader.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index 27b5f4408..4893f1d3a 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -55,13 +55,13 @@ private MavenWrapperDownloader() {} */ public static void main(final String... args) { System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); + var baseDirectory = new File(args[0]); System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); try { - Properties properties = parsePropertiesFile(MAVEN_WRAPPER_PROPERTIES_PATH, baseDirectory); + var properties = parsePropertiesFile(MAVEN_WRAPPER_PROPERTIES_PATH, baseDirectory); String url = properties.getProperty(WRAPPER_URL_PROPERTY_NAME); System.out.println("- Downloading from: " + url); - File outputFile = new File(baseDirectory.getAbsolutePath(), properties.getProperty(MAVEN_WRAPPER_JAR_PATH_PROPERTY_NAME)); + var outputFile = new File(baseDirectory.getAbsolutePath(), properties.getProperty(MAVEN_WRAPPER_JAR_PATH_PROPERTY_NAME)); if (!outputFile.getParentFile().exists()) { if (!outputFile.getParentFile().mkdirs()) { System.out.println("- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); @@ -86,11 +86,11 @@ public static void main(final String... args) { * @throws Exception if the parsing fails */ private static Properties parsePropertiesFile(final String propertiesFileName, final File baseDirectory) throws Exception { - File mavenWrapperPropertyFile = new File(baseDirectory, propertiesFileName); + var mavenWrapperPropertyFile = new File(baseDirectory, propertiesFileName); if (!mavenWrapperPropertyFile.exists()) { throw new Exception("ERROR: missing properties file: " + propertiesFileName); } - Properties properties = new Properties(); + var properties = new Properties(); try (FileInputStream mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile)) { properties.load(mavenWrapperPropertyFileInputStream); return properties; @@ -116,8 +116,8 @@ protected PasswordAuthentication getPasswordAuthentication() { } }); } - URL website = new URL(urlString); - try (FileOutputStream fos = new FileOutputStream(destination)) { + var website = new URL(urlString); + try (var fos = new FileOutputStream(destination)) { ReadableByteChannel rbc = Channels.newChannel(website.openStream()); fos.getChannel().transferFrom(rbc, 0, MAX_VALUE); } From d59e8c8a58d555c6c30a7ffc78a3232ae39a1168 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 12:19:16 +0200 Subject: [PATCH 1315/1786] minor --- .mvn/wrapper/MavenWrapperDownloader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index 4893f1d3a..4b1d1e89b 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -91,7 +91,7 @@ private static Properties parsePropertiesFile(final String propertiesFileName, f throw new Exception("ERROR: missing properties file: " + propertiesFileName); } var properties = new Properties(); - try (FileInputStream mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile)) { + try (var mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile)) { properties.load(mavenWrapperPropertyFileInputStream); return properties; } catch (IOException e) { From b0664b3c27fd65cc829d57e634cb4e24ca607e3e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 12:21:46 +0200 Subject: [PATCH 1316/1786] [maven-release-plugin] prepare release 2.0.0 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 080829da9..974ae0475 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 272a4bf5d..54d217215 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 60da82d0e..764c78e0f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index c610b992b..bde177050 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 555f263b6..e3ad6815a 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index c3e3d9d8d..ad2893513 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/pom.xml b/pom.xml index a58562a6d..1e4b8c548 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0-SNAPSHOT + 2.0.0 pom 2019 @@ -103,7 +103,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 2.0.0 From 1a17157be02501db0ea11d947256f17d8492c2ba Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 12:21:53 +0200 Subject: [PATCH 1317/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 974ae0475..c13f337a3 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 54d217215..be4a2c182 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 764c78e0f..f16c8f49a 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index bde177050..ee98addde 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index e3ad6815a..11393a521 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index ad2893513..23108968c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 1e4b8c548..173f04ad2 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0 + 2.0.1-SNAPSHOT pom 2019 @@ -103,7 +103,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 2.0.0 + HEAD From b89e5e35c74b81b4a8c138484ef7b163c80580b0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 15:12:12 +0200 Subject: [PATCH 1318/1786] javadoc plugin upgrade --- pom.xml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 173f04ad2..75b45e886 100644 --- a/pom.xml +++ b/pom.xml @@ -81,6 +81,7 @@ 3.9.1 3.0.1 + 3.3.0 3.1.2 8.42 2.12.1 @@ -94,7 +95,8 @@ false true false - \#java,\#javax,\#jakarta,\#org,\#,\#com,,\#lombok,java,javax,jakarta,org,,com,,lombok + \#java,\#javax,\#jakarta,\#org,\#,\#com,,\#lombok,java,javax,jakarta,org,,com,,lombok + false @@ -254,6 +256,7 @@ **/PerformanceTest.java + --enable-preview @@ -298,6 +301,7 @@ **/PerformanceTest.java + --enable-preview @@ -405,7 +409,8 @@ true true ${checkstyle.check.skip} - ${checkstyle.includeTestSourceDirectory} + ${checkstyle.includeTestSourceDirectory} + ${checkstyle.exclusion} @@ -509,7 +514,8 @@ ${test.coverage.check.skip} - ${project.basedir}/bull-report/target/site/jacoco-aggregate/jacoco.xml + ${project.basedir}/bull-report/target/site/jacoco-aggregate/jacoco.xml + @@ -605,7 +611,7 @@ ${maven.required.version} - + @@ -664,6 +670,7 @@ org.apache.maven.plugins maven-javadoc-plugin + ${maven.javadoc-plugin.version} ${javadoc.skip} @@ -697,8 +704,8 @@ ${spotless.plugin.skip} - - + + ${import.order} @@ -712,6 +719,7 @@ org.apache.maven.plugins maven-javadoc-plugin + ${maven.javadoc-plugin.version} public From a50a92a614ed97b3c26844598139f1168ae531b5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 16:18:09 +0200 Subject: [PATCH 1319/1786] It solves the issue with the maven site generation using the jdk15 --- .travis.yml | 4 ++-- pom.xml | 31 ++++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2e3f60ba7..bd7af1d95 100755 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ jobs: script: skip before_deploy: - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dcheckstyle.skip=true site:site javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: provider: pages local-dir: target/site @@ -67,7 +67,7 @@ jobs: before_deploy: - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install javadoc:aggregate -P default,site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - mvn install javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: - provider: script script: config/travis/deploy.sh diff --git a/pom.xml b/pom.xml index 75b45e886..ab7393739 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - + 4.0.0 BULL - Bean Utils Light Library com.hotels.beans @@ -46,20 +47,16 @@ - UTF-8 - UTF-8 15 ${jdk.version} ${jdk.version} 1.18.20 3.12.0 - 1.3.0 3.11.1 7.4.0 3.20.1 - 2.0.1.Final 7.0.1.Final 1.7.30 4.0.1 @@ -71,7 +68,8 @@ 0.89 0.91 0.98 - **/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* + **/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* + 2.3.1 @@ -571,6 +569,7 @@ ${project.basedir}/docs/site true + @@ -673,6 +672,8 @@ ${maven.javadoc-plugin.version} ${javadoc.skip} + --enable-preview + ${jdk.version} @@ -719,9 +720,10 @@ org.apache.maven.plugins maven-javadoc-plugin - ${maven.javadoc-plugin.version} public + --enable-preview + ${jdk.version} @@ -732,6 +734,21 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + + ${checkstyle.check.skip} + + + + + checkstyle + + + + + From 35af6ba6e1b5135b491d018941acd22df99c5e65 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 17:13:22 +0200 Subject: [PATCH 1320/1786] Solves the issue that was preventing jacoco to create the coverage reports --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- .../com/hotels/transformer/cache/CacheManager.java | 13 +++++++++++-- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 10 ++++------ 8 files changed, 21 insertions(+), 14 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c13f337a3..080829da9 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index be4a2c182..272a4bf5d 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f16c8f49a..60da82d0e 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java index c9e8b3ce8..81c75651a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java +++ b/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java @@ -18,14 +18,23 @@ import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; +import static lombok.AccessLevel.PROTECTED; + import java.util.Map; import java.util.Optional; +import lombok.AllArgsConstructor; + /** * Cache Utils class. - * @param cacheMap the ache store */ -public record CacheManager(Map cacheMap) { +@AllArgsConstructor(access = PROTECTED) +public final class CacheManager { + /** + * Cache store. + */ + private final Map cacheMap; + /** * Caches the given object. * @param cacheKey the cache key. diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index ee98addde..c610b992b 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 11393a521..555f263b6 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 23108968c..c3e3d9d8d 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index ab7393739..d69237d99 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT pom 2019 @@ -254,7 +254,7 @@ **/PerformanceTest.java - --enable-preview + @{argLine} --enable-preview @@ -299,7 +299,7 @@ **/PerformanceTest.java - --enable-preview + @{argLine} --enable-preview @@ -420,7 +420,7 @@ ${maven.surefire.plugin.version} false - --enable-preview + @{argLine} --enable-preview @@ -569,7 +569,6 @@ ${project.basedir}/docs/site true - @@ -749,6 +748,5 @@ - From 972769661d6fb7862f222f2c04f3151465a9b10c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 17:15:47 +0200 Subject: [PATCH 1321/1786] minor: travis stage rename --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bd7af1d95..c1112540c 100755 --- a/.travis.yml +++ b/.travis.yml @@ -43,8 +43,8 @@ jobs: on: tags: true ### JDK15 release - - stage: "JDK15 Release" - name: "Releasing artifacts for JDK15" + - stage: "Artifact Release" + name: "Releasing artifacts" jdk: openjdk15 if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip From e917a80eba36942ed5b9e6b014f5c995cde93433 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 17:27:34 +0200 Subject: [PATCH 1322/1786] [maven-release-plugin] prepare release 2.0.0 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 13 ++++++------- 7 files changed, 12 insertions(+), 13 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 080829da9..974ae0475 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 272a4bf5d..54d217215 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 60da82d0e..764c78e0f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index c610b992b..bde177050 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 555f263b6..e3ad6815a 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index c3e3d9d8d..ad2893513 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/pom.xml b/pom.xml index d69237d99..a89a9fd8f 100644 --- a/pom.xml +++ b/pom.xml @@ -15,14 +15,13 @@ See the License for the specific language governing permissions and limitations under the License. --> - + 4.0.0 BULL - Bean Utils Light Library com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0-SNAPSHOT + 2.0.0 pom 2019 @@ -103,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 2.0.0 @@ -609,7 +608,7 @@ ${maven.required.version} - + @@ -704,8 +703,8 @@ ${spotless.plugin.skip} - - + + ${import.order} From f5c99f0473c36f3c8ef2f04849b9fb7bcee49767 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 17:27:41 +0200 Subject: [PATCH 1323/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 974ae0475..c13f337a3 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 54d217215..be4a2c182 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 764c78e0f..f16c8f49a 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index bde177050..ee98addde 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index e3ad6815a..11393a521 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index ad2893513..23108968c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index a89a9fd8f..8cb2bcf23 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0 + 2.0.1-SNAPSHOT pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 2.0.0 + HEAD From 3e11c6515d94b79097fb394de9b6ffdb1809d42e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 17:28:55 +0200 Subject: [PATCH 1324/1786] [maven-release-plugin] rollback the release of 2.0.0 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 11 ++++++----- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c13f337a3..080829da9 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index be4a2c182..272a4bf5d 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f16c8f49a..60da82d0e 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index ee98addde..c610b992b 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 11393a521..555f263b6 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 23108968c..c3e3d9d8d 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 8cb2bcf23..d69237d99 100644 --- a/pom.xml +++ b/pom.xml @@ -15,13 +15,14 @@ See the License for the specific language governing permissions and limitations under the License. --> - + 4.0.0 BULL - Bean Utils Light Library com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT pom 2019 @@ -608,7 +609,7 @@ ${maven.required.version} - + @@ -703,8 +704,8 @@ ${spotless.plugin.skip} - - + + ${import.order} From c9d59f4c2a00d6ab2a24c27586d760535b2f1986 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 17:30:20 +0200 Subject: [PATCH 1325/1786] removes the default step from the release as it's not needed --- config/travis/deploy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/travis/deploy.sh b/config/travis/deploy.sh index a00e33d67..cda9e496f 100755 --- a/config/travis/deploy.sh +++ b/config/travis/deploy.sh @@ -6,10 +6,10 @@ if [ "$TRAVIS_PULL_REQUEST" == 'false' ]; then if [ "$TRAVIS_BRANCH" == 'master' ]; then echo "Deploying release" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn deploy --settings config/travis/mvn-settings.xml -B -U -P release -DskipTests=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn else echo "Deploying snapshot" gpg --import config/travis/private-key.gpg - mvn deploy --settings config/travis/mvn-settings.xml -B -U -P default,release -DskipTests=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn deploy --settings config/travis/mvn-settings.xml -B -U -P release -DskipTests=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn fi fi \ No newline at end of file From 12254a00d9843dac65afa930ea9a3ddff6e0f899 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 17:31:38 +0200 Subject: [PATCH 1326/1786] [maven-release-plugin] prepare release 2.0.0 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 13 ++++++------- 7 files changed, 12 insertions(+), 13 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 080829da9..974ae0475 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 272a4bf5d..54d217215 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 60da82d0e..764c78e0f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index c610b992b..bde177050 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 555f263b6..e3ad6815a 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index c3e3d9d8d..ad2893513 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/pom.xml b/pom.xml index d69237d99..a89a9fd8f 100644 --- a/pom.xml +++ b/pom.xml @@ -15,14 +15,13 @@ See the License for the specific language governing permissions and limitations under the License. --> - + 4.0.0 BULL - Bean Utils Light Library com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0-SNAPSHOT + 2.0.0 pom 2019 @@ -103,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 2.0.0 @@ -609,7 +608,7 @@ ${maven.required.version} - + @@ -704,8 +703,8 @@ ${spotless.plugin.skip} - - + + ${import.order} From 9be953a14bea2694f75a7b3de23fc375ead11561 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 18 Jun 2021 17:31:45 +0200 Subject: [PATCH 1327/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 974ae0475..c13f337a3 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 54d217215..be4a2c182 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 764c78e0f..f16c8f49a 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index bde177050..ee98addde 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index e3ad6815a..11393a521 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index ad2893513..23108968c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index a89a9fd8f..8cb2bcf23 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0 + 2.0.1-SNAPSHOT pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 2.0.0 + HEAD From 812df706cf502ccad59b4066efee5fce9860b53c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 19:53:06 +0200 Subject: [PATCH 1328/1786] Modifies the artifact sign updating the key --- .travis.yml | 10 +++++----- config/travis/codesigning.asc.enc | Bin 0 -> 9664 bytes config/travis/deploy.sh | 4 ++-- config/travis/mvn-settings.xml | 2 +- config/travis/private-key.gpg.enc | Bin 3664 -> 0 bytes 5 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 config/travis/codesigning.asc.enc delete mode 100644 config/travis/private-key.gpg.enc diff --git a/.travis.yml b/.travis.yml index c1112540c..1cc36f09e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,10 @@ env: # HCOM OSS Sonatype jira info - secure: W40tXg80XoNy8L3GujgF4PzuiWqY4q5o+XVqppj1atLS7dFa/KuSjJ6bBWF0ootVjmXpRofUF5/Tg2zwcwtOKm9wSjCdgmoGht2CFryieoNVuwJ7MFBLheMvpKp940vHpXDMxb5mc/lff1yM/XNLd5aUa5ITw8GE7qowc3Irc2tUTZKQem+o3mwnuj0dBsRUQt2eGIEkqDWn/pQ5SfjUWSQp3YUVv0iPjIvwV+lHSEB9Mod8Am/5TYuFxINgo6R3MX5K7rwaXjvErSUz6gAP2kqoA+EZDUotmdhFr8zVVpB8e33bPwxNlTYJ5fePKIkLz3TjEb1UVpav2/Ie/jpD0QbfCL/hukEPV/JKye+4fOIJeRZGwBXOQQsscyfcNf9utHittG4ZEzOXwYutbSf4qjoI5V48/hC8hs0OL3RJGE6e4v9tQwvIxY/IopqreACVrHIRK34fOoABQpFUPsmcGTuLrAGJqjDn9UiXJqb9Qlgav1Ly0KKH5YnKQoxyc5RvQDC8NvafSDgex0udGwTVGDNYgQeGVmrOy/C6iDIyEe5hn5gXwDFWFMxETjHcYka7gCngCbDiGIOMxiOeHbnO2dG7HbNME6p9nRovdD/n5cnp4sj3ttysyMNRt8NE2IkZRfJ+LQUqcavpkeVRvN5O/drNBtYnTOXC+lGCV0XGL2E= - secure: cniGJvvR9/RcmRAp0F+iLvqQGH3zlvDYUb1GqZpX2ZKgqJ9syidk/Xy456HdR9WM9gTHZdQLNXYQFx9Dt41pa3Ft9nEi9LvmoLp/3rh/Siogx2X/madDxqHOXshCMYUg9ndSk8KKvjYSb+ztxT8j1qDW553Fax2YPWQiGRT5FXaEg1vl6znR362AhXaU1MgB8Wq+tDzTYJZugGj13u0S/vkNuTd30IQ5sW9YoQ4QwYPJIaG6ix1EUo0P3u96edakQjIAdciMLkggsfQkZr2MF5vAHjUI4+qW5wyAV2mzauc2MKhvKkJnF6WcNYOsXBOyDCAPJNo5YM4ODJM9ot7CcfKllecBaFUs4Uqh2U0lIe6opRtMdYPwV/GAAXwanSKgM1dNxgmPHnUWffWjaUJAbN94E/EH9JtGK2FAuxWqhbsPuMbpGK3XXuojU1fYj3oGGYFmSE3xWmhtSU89xiDrmrooGxxkaRt00eWtK+qCuiR8KGkN//i3+3x2F0ysVoOJL5WSSzNyfbtfp6laHTZv/LSAFgjSEmJF04L4m4Yhm/EDKaUXZjR/TAK2NZDTxlOxaOGVhwPA8Xj5YSwDMTd5k+cPntpYn/NbWtRr4fwk6VxI4XOOtksdiSk4Eiiaco2qEyd3X1tW/B9bPaAAFk8jHD35GNZAazgvNq7+kpMOg1s= - # GPG_KEYNAME - - secure: VGoLyHHb4exm8mw1OSS+zUWGqxcDOx9F2GF5q7TKr5uiqhMkBCz1Y4hTgBakYWfJLdhQl8F/UkUpjqVPN6NHz3q87aLeZtc5GB9D+kXhTuoMIZ34p0U5HEk63v06VvfmoMUfahEVZVeb3RWUAQGuliGokyiMRS3u4hK9UDTx91x4RRx/83pHn4o6NRAzIXyOoQIYwuLbCIleNVe35Ok2LKdk7NQ2i+nDVLdnjeuHWoF27R33CeiRRV+GvF7aJRksqKwPPS63nn6aGtEmlzemyYbiwDZ1wQbf9nuSZLaU78unTGq6qyVrYbpxegWHclPsM5EKxO34uqi3m0GLRuy/W+u0R9dRaCMk4aEPmz56ClDPrmjssMXn+pyumsKU4932aVA1Q/IP14H19P/3eH2FvJLnO00eGdKgqvVRbomOyRqlRWCI/mUsR0aAr+Go+32Orf88v79EAT0WmXBYgGiJR7d2Ig7YZxY5KnM+rto59J9tZbWQJRYr+jkw5W8dPTMVQ+a4T6kGcOR4e54KIqkW1BVa/I+aaiZSP0BrIGEbk2b1UmoYGOuxOBjs0ESDHaj6KFQK026WAoedQ/bYa8J+j7JRIg/ivlvH5eycXSFTXLt4Qym/iZ8SOnJr1mWTF4xCaOmyUBqSHS2tOPJiGuNdRpFep8QT9vBEXpej2yOLyDA= + # GPG_KEY_NAME + - secure: l0BUFY0eCMvGEOLC8/7qR4UQMzUbo6aYNJxaqzqmTsp1gHR1f6t0uFV5eGkaNwlLsay8SNleqoj/kvu2gWWa6uQ7vPMSMmlg1uB2gzJhT1B1QYuCAkOJQ7cvoakU859yiED1+ZFym3aTs+DstuZa/eyNI67RWmmfgUyl5nfQqMrV6NF24lbU2KqX7mrr1VVXjEkNHcW8/Lo5AVwp21jKar7hjgqxJhMRMqpLVY1ToVkpUAWUwRc0aEWDhqf/4Zjx6I1ebpKbNzSUE0VEJOd9+87dGlm+9CcgwMZsLo+tSl5CvbX8zWRGWX3OLqKfYnJpVJRgMweZcxvm5PeICGs0IZqbenKn3Xh2JxVp6hiZ8/I6kMB2KSVxlrk/3I9McfG2xoibKpbEqwUeX95IqNnBBw4Nm1pSkandW6bJjFjGatRaaO1Am5m4+DG+Su31TleKLq3+wew3we/Qu7ksAvaJ2b3/CLZv6FO2aB79Uh0wOfzU7tCRdDkzDUvFjGvQzvfS1iTrlHjlRgPAhQd+De4EYgtkh6rHixDnf58Z0AG+J7/+ZcJhV0ivCIb3QYZJDt8RjDZDr7EtOw7QGXO9PyTo8tL8DEIVg14I3AENQtoxop3C8hzb/NFGJTIf/0CBPzsmPw4K0RsYUfjkjRYJLFAYkm7pVpp0QnwkVXnQlobYyoA= # GPG_PASSPHRASE - - secure: bFylqtr43v1wetXH/b1RJDmsDzwn6ILfFnw0rVFVKdpYndoyL3J05A3qYdZ+K1cePP7cYnetfOlMnv/e1LDGSzQ/C2RmPgEZIPRozxg0t9S+QU/G+Ro5m1VhrEDOpJv2A7IxY7WBgWEhChIKTZlDK4c2rzXDJ/Z799QQRmiOu04zGVBUjPcbU01QlFF71e3Vf5sovBPSWPifmqyKHZPquqXbY5Jo36MDAO5b3aD/rk/6nkzB+b10fAEJ/9sXX14S0ItTc7CWkjGdqjMsu9lMYUZ8Au2YgBtGAU3XBG30+uhKk7Z2XZj8Ne9QJhPbzzt53bB0loa8pQ+k6NGcCPRoTZOI3tAKKPxXf1sRolE3gYmje1GcREvsXRnZbwfZuayCOBdEXFFZzmijz/H5UgNS5rUwrY+FH6Dl4AZsQvDJdC4nJ4IVo6knRM4yx4ooI47tJBLLQS5cFOTmpYnQdZZLr5s4EPRhFpqSa61a2ZoBzTDl4Jj3M/zZ9xtIajYEdYSZ/wGpErsA/KJbHnP32lukTVG86Ndh4E2xLVVo1U5iwTZA6EsvarHKvEqLGtOYMyC2TqxuTlgzsfuGkonAlj9jx8I51Hjc5NMuamqWl4uLY2nC2BpTY1Gaufb0AJkTfp0W1/yPxaS2SGYo18UDobOGQfDniEe4CiVUkpACj0Jq7kY= + - secure: D/JuBQf12qen8ld0rV6l5OkqHJidrLwCZBBNP6zM86vYfYVneiulTFhrTSdMrmcJaCGllatc7m/8h8DBZIIQ/ax/OKnBF+SXBd2YghZyo17NALPsmNOmF1oHL6oGbBBfZ3EOoJ/B3j4zHrxtbX53+lJPvLkmveA6jTupQq/3mldVEyKekyPaRofJ88ZYsIiT4S0Q3OSoVTZuOE6Tcq24v6HkWYYH2q99c45HyI4u+xgmxsRjFJMRi+37iqecqr6VxL7Cj6RjwsjpOi2x0m2hMxa6eOrc7VdYDzV37U8O+vv9RRm02r1P0K9HAviE2VO7loOwEYW1y3ZtApwRFBQFtd2QG054mkw/HL1zLXcG+tQgndx8Ui1nmPT4uh19DjGT0vUAJ+8zP0I757sHC13DqrqPSWGatd7P+lkVIuc5QNi0Y3D7XxgnD5XAPIGy/T91GH5WQjIUJd+F0xe7PnW2h0GAsR0MyeBV3Wueh+5mKyIV9p/79nYuaIKSNhEjPj0iPTS2JzYVnutJHQGyH1uvCKDI3JaxFdgKDNNCoZY9BiVhEkbmcJmKlcsGlqFRSn9LWOFW9+NQWdo1FfKCFNCHppNzt23p7JxFd3wjy+0Fp1kRjQ3VHCm4mpx/bRI++5tjvPtQHq7D4VjiteO6FuhqJBBgz93mI9pGp66o91RwFrk= install: skip jobs: include: @@ -49,7 +49,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d + - openssl aes-256-cbc -K $encrypted_81c98acad902_key -iv $encrypted_81c98acad902_iv -in codesigning.asc.enc -out codesigning.asc -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: @@ -65,7 +65,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk8$ script: skip before_deploy: - - openssl aes-256-cbc -K $encrypted_bbb0f94c13c1_key -iv $encrypted_bbb0f94c13c1_iv -in config/travis/private-key.gpg.enc -out config/travis/private-key.gpg -d + - openssl aes-256-cbc -K $encrypted_81c98acad902_key -iv $encrypted_81c98acad902_iv -in codesigning.asc.enc -out codesigning.asc -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: diff --git a/config/travis/codesigning.asc.enc b/config/travis/codesigning.asc.enc new file mode 100644 index 0000000000000000000000000000000000000000..6a564b3bc00efca12263b09e85fd3018fed4acb8 GIT binary patch literal 9664 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 gpg - ${env.GPG_KEYNAME} + ${env.GPG_KEY_NAME} ${env.GPG_PASSPHRASE} diff --git a/config/travis/private-key.gpg.enc b/config/travis/private-key.gpg.enc deleted file mode 100644 index d70f6838bf46fcdd53d225f85c67ec7c00e9e86d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3664 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 From 5226d70021d1619c53f0bc16d0567b44aa905d28 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 19:56:52 +0200 Subject: [PATCH 1329/1786] updates the project version and temporarily removes the build step leaving only the release one --- .travis.yml | 52 +++++++++++++++++------------------ bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1cc36f09e..a271deb6d 100755 --- a/.travis.yml +++ b/.travis.yml @@ -15,33 +15,33 @@ install: skip jobs: include: ### Build - - stage: "Build" - name: "Build and Test" - jdk: openjdk15 - script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode +# - stage: "Build" +# name: "Build and Test" +# jdk: openjdk15 +# script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode ### JDK8 build - - stage: "JDK8 Build" - name: "JDK8 Build and Test" - jdk: openjdk8 - if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ - script: - - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - stage: "Site Build and Quality check" - name: "Publishing site and performing a code quality check" - jdk: openjdk15 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ - script: skip - before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true - on: - tags: true +# - stage: "JDK8 Build" +# name: "JDK8 Build and Test" +# jdk: openjdk8 +# if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ +# script: +# - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn +# - stage: "Site Build and Quality check" +# name: "Publishing site and performing a code quality check" +# jdk: openjdk15 +# if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ +# script: skip +# before_deploy: +# - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn +# - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q +# deploy: +# provider: pages +# local-dir: target/site +# skip-cleanup: true +# github-token: ${github_oauth_token} +# keep-history: true +# on: +# tags: true ### JDK15 release - stage: "Artifact Release" name: "Releasing artifacts" diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c13f337a3..080829da9 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index be4a2c182..272a4bf5d 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f16c8f49a..60da82d0e 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index ee98addde..c610b992b 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 11393a521..555f263b6 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 23108968c..c3e3d9d8d 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 8cb2bcf23..7a171144a 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT pom 2019 From 38a7ba1a328fd5d0a6795cb6a3af636742104909 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 19:58:28 +0200 Subject: [PATCH 1330/1786] [maven-release-plugin] prepare release 2.0.0 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 080829da9..974ae0475 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 272a4bf5d..54d217215 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 60da82d0e..764c78e0f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index c610b992b..bde177050 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 555f263b6..e3ad6815a 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index c3e3d9d8d..ad2893513 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/pom.xml b/pom.xml index 7a171144a..a89a9fd8f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0-SNAPSHOT + 2.0.0 pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 2.0.0 From 5a90bac26ebcb05d9de237309f0e5e1216e8db69 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 19:58:46 +0200 Subject: [PATCH 1331/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 974ae0475..c13f337a3 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 54d217215..be4a2c182 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 764c78e0f..f16c8f49a 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index bde177050..ee98addde 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index e3ad6815a..11393a521 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index ad2893513..23108968c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index a89a9fd8f..8cb2bcf23 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0 + 2.0.1-SNAPSHOT pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 2.0.0 + HEAD From db16f862b8813e309b233f02f8b7886c1566ead4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 20:01:31 +0200 Subject: [PATCH 1332/1786] updates the key path --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a271deb6d..7eed0a1bb 100755 --- a/.travis.yml +++ b/.travis.yml @@ -49,7 +49,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ script: skip before_deploy: - - openssl aes-256-cbc -K $encrypted_81c98acad902_key -iv $encrypted_81c98acad902_iv -in codesigning.asc.enc -out codesigning.asc -d + - openssl aes-256-cbc -K $encrypted_81c98acad902_key -iv $encrypted_81c98acad902_iv -in config/travis/codesigning.asc.enc -out config/travis/codesigning.asc -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: @@ -65,7 +65,7 @@ jobs: if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk8$ script: skip before_deploy: - - openssl aes-256-cbc -K $encrypted_81c98acad902_key -iv $encrypted_81c98acad902_iv -in codesigning.asc.enc -out codesigning.asc -d + - openssl aes-256-cbc -K $encrypted_81c98acad902_key -iv $encrypted_81c98acad902_iv -in config/travis/codesigning.asc.enc -out config/travis/codesigning.asc -d - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q deploy: From 642291b2ac68ecbd897d6f6fb8e9678903dfd627 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 20:02:24 +0200 Subject: [PATCH 1333/1786] updates the key path --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c13f337a3..080829da9 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index be4a2c182..272a4bf5d 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f16c8f49a..60da82d0e 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index ee98addde..c610b992b 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 11393a521..555f263b6 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 23108968c..c3e3d9d8d 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 8cb2bcf23..7a171144a 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.1-SNAPSHOT + 2.0.0-SNAPSHOT pom 2019 From 73ebf588316abc113ed4952a201319a85b0ae645 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 20:03:35 +0200 Subject: [PATCH 1334/1786] [maven-release-plugin] prepare release 2.0.0 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 080829da9..974ae0475 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 272a4bf5d..54d217215 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 60da82d0e..764c78e0f 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index c610b992b..bde177050 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 555f263b6..e3ad6815a 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index c3e3d9d8d..ad2893513 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0-SNAPSHOT + 2.0.0 diff --git a/pom.xml b/pom.xml index 7a171144a..a89a9fd8f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0-SNAPSHOT + 2.0.0 pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 2.0.0 From 4ae98c13b2728a5dccd1543b1722b8e8ee866c6d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 20:03:42 +0200 Subject: [PATCH 1335/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 974ae0475..c13f337a3 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 54d217215..be4a2c182 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 764c78e0f..f16c8f49a 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index bde177050..ee98addde 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index e3ad6815a..11393a521 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index ad2893513..23108968c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.0 + 2.0.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index a89a9fd8f..8cb2bcf23 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.0 + 2.0.1-SNAPSHOT pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 2.0.0 + HEAD From 44f1d9901c5301b8ec15c88acb3bd0526780c788 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 20:07:03 +0200 Subject: [PATCH 1336/1786] restoring all the steps --- .travis.yml | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7eed0a1bb..0ccce8583 100755 --- a/.travis.yml +++ b/.travis.yml @@ -15,33 +15,33 @@ install: skip jobs: include: ### Build -# - stage: "Build" -# name: "Build and Test" -# jdk: openjdk15 -# script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + - stage: "Build" + name: "Build and Test" + jdk: openjdk15 + script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode ### JDK8 build -# - stage: "JDK8 Build" -# name: "JDK8 Build and Test" -# jdk: openjdk8 -# if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ -# script: -# - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -# - stage: "Site Build and Quality check" -# name: "Publishing site and performing a code quality check" -# jdk: openjdk15 -# if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ -# script: skip -# before_deploy: -# - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -# - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -# deploy: -# provider: pages -# local-dir: target/site -# skip-cleanup: true -# github-token: ${github_oauth_token} -# keep-history: true -# on: -# tags: true + - stage: "JDK8 Build" + name: "JDK8 Build and Test" + jdk: openjdk8 + if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ + script: + - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - stage: "Site Build and Quality check" + name: "Publishing site and performing a code quality check" + jdk: openjdk15 + if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ + script: skip + before_deploy: + - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + deploy: + provider: pages + local-dir: target/site + skip-cleanup: true + github-token: ${github_oauth_token} + keep-history: true + on: + tags: true ### JDK15 release - stage: "Artifact Release" name: "Releasing artifacts" From 2086c54d19092917403db4cb16823ebdf0360f20 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 20 Jun 2021 21:25:54 +0200 Subject: [PATCH 1337/1786] minor: code improvement --- .../map/transformer/MapTransformerTest.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index 2850cba45..f43578dbf 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -1,12 +1,9 @@ /** * Copyright (C) 2019-2021 Expedia, Inc. - * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -177,8 +174,8 @@ public void testTransformWorksProperlyWithTransformer() { // THEN assertThat(actual) .isNotNull() - .hasSize(sourceMap.size()) - .containsKey(MAP_KEY_1.toUpperCase()); + .hasSize(sourceMap.size()) + .containsKey(MAP_KEY_1.toUpperCase()); } /** @@ -206,11 +203,11 @@ public void testTransformWorksProperlyWithTargetKeyAndElemType() { Map actual = underTest.transform(EXTREME_COMPLEX_MAP, MutableToFooSimple.class, Map.class); // THEN - assertThat(actual).isNotNull(); - assertThat(actual.size()).isEqualTo(EXTREME_COMPLEX_MAP.size()); - // check that the element has been converted - assertThat(actual).allSatisfy((key, value) -> - assertThat(key).isInstanceOf(MutableToFooSimple.class)); + assertThat(actual) + .isNotNull() + .hasSize(EXTREME_COMPLEX_MAP.size()) + .allSatisfy((key, value) -> + assertThat(key).isInstanceOf(MutableToFooSimple.class)); } /** From 3bc5680108d8f74ffef4dfe32531ab11d6a8230d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Jun 2021 02:00:31 +0000 Subject: [PATCH 1338/1786] Bump checkstyle from 8.42 to 8.43 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 8.42 to 8.43. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-8.42...checkstyle-8.43) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8cb2bcf23..184360169 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ 3.0.1 3.3.0 3.1.2 - 8.42 + 8.43 2.12.1 false From d25e0b5b2f2631e815784d280675587043773885 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Jun 2021 02:00:35 +0000 Subject: [PATCH 1339/1786] Bump assertj-core from 3.20.1 to 3.20.2 Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.20.1 to 3.20.2. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.20.1...assertj-core-3.20.2) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8cb2bcf23..653635edb 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.11.1 7.4.0 - 3.20.1 + 3.20.2 7.0.1.Final 1.7.30 From f128b4ca01e0a7fe0bbc7dbe3d143b2c77cf96ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Jun 2021 02:00:37 +0000 Subject: [PATCH 1340/1786] Bump slf4j-api from 1.7.30 to 1.7.31 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.30 to 1.7.31. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/commits) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8cb2bcf23..bea5f5e14 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 3.20.1 7.0.1.Final - 1.7.30 + 1.7.31 4.0.1 0.8.7 From fa10fe2a87e35f6195c0cbf0672be772710c9223 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 21 Jun 2021 14:05:22 +0200 Subject: [PATCH 1341/1786] minor: readme update --- README.md | 4 ++-- docs/site/markdown/transformer/bean/samples.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1d85edad2..ec48a773d 100644 --- a/README.md +++ b/README.md @@ -738,8 +738,8 @@ ToBean toBean = new BeanTransformer() ### Simple case: ```java -public record FromFooRecord { public record RecordToFoo(BigInteger id, String name) { -} } +public record FromFooRecord(BigInteger id, String name) { public record RecordToFoo(BigInteger id, String name) { +} } ``` And one line code as: diff --git a/docs/site/markdown/transformer/bean/samples.md b/docs/site/markdown/transformer/bean/samples.md index de50e5415..50df7e1be 100644 --- a/docs/site/markdown/transformer/bean/samples.md +++ b/docs/site/markdown/transformer/bean/samples.md @@ -485,8 +485,8 @@ ToBean toBean = transformer.transform(fromBean, ToBean.class); ### Simple case: ```java -public record FromFooRecord { public record RecordToFoo(BigInteger id, String name) { -} } +public record FromFooRecord(BigInteger id, String name) { public record RecordToFoo(BigInteger id, String name) { +} } ``` And one line code as: From ec3a9d26370b174e3206e7dc0629af848fe3c46c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Jun 2021 02:00:29 +0000 Subject: [PATCH 1342/1786] Bump mockito-core from 3.11.1 to 3.11.2 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.11.1 to 3.11.2. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.11.1...v3.11.2) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ba980027e..c63b0c3b5 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ 1.18.20 3.12.0 - 3.11.1 + 3.11.2 7.4.0 3.20.2 From 22ef490b41f924bf3910b7391535f01338e04491 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jun 2021 14:59:01 +0200 Subject: [PATCH 1343/1786] Enables the validation for the Object types --- CHANGELOG.md | 8 +++++++ .../beans/transformer/TransformerImpl.java | 23 +++++++++++-------- .../map/transformer/MapTransformerTest.java | 3 +++ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27ea433d4..3bd8df612 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,19 @@ All notable changes to this project will be documented in this file. +### [2.0.1] 2021.06.23 +#### Changed +* Fixes an issue that was preventing the transformation of Object type fields + ### [2.0.0] 2021.06.18 #### Added * Increase the jdk version to 15 * Enables the [Java Record](https://blogs.oracle.com/javamagazine/records-come-to-java) transformation +### [1.7.7] 2021.06.23 +#### Changed +* Fixes an issue that was preventing the transformation of Object type fields + ### [1.7.6] 2021.01.11 #### Added * Provides new module `bull-bom` that includes all the project modules diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index ebbbf9f6c..3374c6f7a 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -56,13 +56,18 @@ public class TransformerImpl extends AbstractBeanTransformer { * {@inheritDoc} */ @Override + @SuppressWarnings("unchecked") protected final K transform(final T sourceObj, final Class targetClass, final String breadcrumb) { final K k; - final Optional> builderClass = getBuilderClass(targetClass); - if (builderClass.isPresent()) { - k = injectThroughBuilder(sourceObj, targetClass, builderClass.get(), breadcrumb); + if (targetClass.equals(Object.class)) { + k = (K) sourceObj; } else { - k = injectValues(sourceObj, targetClass, breadcrumb); + final Optional> builderClass = getBuilderClass(targetClass); + if (builderClass.isPresent()) { + k = injectThroughBuilder(sourceObj, targetClass, builderClass.get(), breadcrumb); + } else { + k = injectValues(sourceObj, targetClass, breadcrumb); + } } if (settings.isValidationEnabled()) { validator.validate(k); @@ -176,7 +181,7 @@ private K injectValues(final T sourceObj, final Class targetClass, fin * @throws InvalidBeanException {@link InvalidBeanException} if the target object is not compliant with the requirements */ protected K handleInjectionException(final T sourceObj, final Class targetClass, final Constructor constructor, final String breadcrumb, - final Object[] constructorArgs, final boolean forceConstructorInjection, final Exception e) { + final Object[] constructorArgs, final boolean forceConstructorInjection, final Exception e) { String errorMsg; if (!classUtils.areParameterNamesAvailable(constructor)) { if (!forceConstructorInjection) { @@ -447,8 +452,8 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN */ @SuppressWarnings("unchecked") private Object getTransformedValue(final FieldTransformer transformerFunction, final Object fieldValue, - final Class sourceObjectClass, final String sourceFieldName, final Field field, - final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { + final Class sourceObjectClass, final String sourceFieldName, final Field field, + final boolean isDestinationFieldPrimitiveType, final String breadcrumb) { Object transformedValue = fieldValue; if (settings.isPrimitiveTypeConversionEnabled() && isDestinationFieldPrimitiveType) { transformedValue = applyPrimitiveTypeConversion(sourceObjectClass, sourceFieldName, field, breadcrumb, transformedValue); @@ -546,7 +551,7 @@ private FieldTransformer getTransformerFunction(final Field field, final String */ @SuppressWarnings("unchecked") private Object applyPrimitiveTypeConversion(final Class sourceObjectClass, final String sourceFieldName, - final Field field, final String fieldTransformerKey, final Object fieldValue) { + final Field field, final String fieldTransformerKey, final Object fieldValue) { Object transformedValue = fieldValue; FieldTransformer primitiveTypeTransformer = getPrimitiveTypeTransformer(sourceObjectClass, sourceFieldName, field, fieldTransformerKey); if (nonNull(primitiveTypeTransformer)) { @@ -564,7 +569,7 @@ private Object applyPrimitiveTypeConversion(final Class sourceObjectClass, fi * @return the default type transformer function */ private FieldTransformer getPrimitiveTypeTransformer(final Class sourceObjectClass, final String sourceFieldName, - final Field field, final String fieldTransformerKey) { + final Field field, final String fieldTransformerKey) { String cacheKey = TRANSFORMER_FUNCTION_CACHE_PREFIX + "-" + field.getDeclaringClass().getName() + "-" + fieldTransformerKey + "-" + field.getName(); return cacheManager.getFromCache(cacheKey, FieldTransformer.class) .orElseGet(() -> { diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java index f43578dbf..7d8c35bb8 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java @@ -1,9 +1,12 @@ /** * Copyright (C) 2019-2021 Expedia, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at + * * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. From b733b239a429cca56b7bd7f5d66e0e9dacff6a8e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jun 2021 15:00:15 +0200 Subject: [PATCH 1344/1786] [maven-release-plugin] prepare release 2.0.1 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c13f337a3..8e68cd7d9 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.1 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index be4a2c182..d85f73159 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index f16c8f49a..ed83c6c5a 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index ee98addde..a4b37372d 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1-SNAPSHOT + 2.0.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 11393a521..6bf4724f4 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.1 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 23108968c..788233e51 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1-SNAPSHOT + 2.0.1 diff --git a/pom.xml b/pom.xml index c63b0c3b5..dbd5ed2c8 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.1-SNAPSHOT + 2.0.1 pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 2.0.1 From 1c84dde001cb76756bcb1765de9d68a26613067d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jun 2021 15:00:22 +0200 Subject: [PATCH 1345/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 8e68cd7d9..620929f22 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1 + 2.0.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index d85f73159..402f677b5 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1 + 2.0.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index ed83c6c5a..81a35a788 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1 + 2.0.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index a4b37372d..590fe2aa9 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1 + 2.0.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 6bf4724f4..0a74d1d39 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1 + 2.0.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 788233e51..2d94162ac 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1 + 2.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index dbd5ed2c8..53079fc44 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.1 + 2.0.2-SNAPSHOT pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 2.0.1 + HEAD From 39d19da1cda3c13d086db04c017e1eabbb46cca5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jun 2021 15:28:42 +0200 Subject: [PATCH 1346/1786] updates the CHANGELOG-JDK8.md --- CHANGELOG-JDK8.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 9eaa4011c..b5d4e9e6c 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,9 +2,13 @@ All notable changes to this project will be documented in this file. -### [1.7.5-jdk8] 2021.01.11 -#### Added -* Provides new module `bull-bom` that includes all the project modules +### [1.7.5-jdk8] 2020.06.23 +#### Changed +* * Fixes an issue that was preventing the transformation of Object type fields + +### [1.7.4-jdk8] 2020.12.24 +#### Changed +* Updated `hibernate-validator` version to `7.0.0.Final` (was `6.1.5.Final`). ### [1.7.3-jdk8] 2020.10.07 #### Changed From 347b6da29f3888d8be4041ca2c8d32b755163b1a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 23 Jun 2021 15:41:51 +0200 Subject: [PATCH 1347/1786] implements a test for the object type copy --- .../transformer/MutableObjectTransformationTest.java | 11 +++++++---- .../beans/sample/FromFooOnlyPrimitiveTypes.java | 1 + .../sample/mixed/MutableToFooOnlyPrimitiveTypes.java | 1 + .../hotels/transformer/AbstractTransformerTest.java | 3 ++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java index 0bb1b8aa9..e89eda788 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java @@ -55,6 +55,7 @@ public class MutableObjectTransformationTest extends AbstractBeanTransformerTest { private static final boolean ACTIVE = true; private static final String PRICE_FIELD_NAME = "price"; + private static final String UUID_FIELD_NAME = "uuid"; private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; private static final String INJECT_VALUES_METHOD_NAME = "injectValues"; private static final String NESTED_OBJECT_NAME_FIELD_NAME = "nestedObject.name"; @@ -333,12 +334,13 @@ public void testAutomaticPrimitiveTypeTransformationWorksProperly() { MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); // THEN - assertThat(actual).extracting(CODE_FIELD_NAME, ID_FIELD_NAME, PRICE_FIELD_NAME, ACTIVE_FIELD_NAME) + assertThat(actual).extracting(CODE_FIELD_NAME, ID_FIELD_NAME, PRICE_FIELD_NAME, ACTIVE_FIELD_NAME, UUID_FIELD_NAME) .containsExactly( parseInt(fromFooPrimitiveTypes.getCode()), String.valueOf(fromFooPrimitiveTypes.getId()), (double) fromFooPrimitiveTypes.getPrice(), - ACTIVE); + ACTIVE, + fromFooPrimitiveTypes.getUuid()); underTest.setPrimitiveTypeConversionEnabled(false); } @@ -356,12 +358,13 @@ public void testThatBothPrimitiveTypeTransformationAndCustomTransformationAreExe MutableToFooOnlyPrimitiveTypes actual = underTest.transform(fromFooPrimitiveTypes, MutableToFooOnlyPrimitiveTypes.class); // THEN - assertThat(actual).extracting(CODE_FIELD_NAME, ID_FIELD_NAME, ACTIVE_FIELD_NAME, PRICE_FIELD_NAME) + assertThat(actual).extracting(CODE_FIELD_NAME, ID_FIELD_NAME, ACTIVE_FIELD_NAME, PRICE_FIELD_NAME, UUID_FIELD_NAME) .containsExactly( parseInt(fromFooPrimitiveTypes.getCode()), String.valueOf(fromFooPrimitiveTypes.getId()), ACTIVE, - newPrice); + newPrice, + fromFooPrimitiveTypes.getUuid()); underTest.setPrimitiveTypeConversionEnabled(false); underTest.removeFieldTransformer(PRICE_FIELD_NAME); } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java index e28560ccd..3e644bfb0 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java @@ -32,4 +32,5 @@ public class FromFooOnlyPrimitiveTypes { private int id; private float price; private String active; + private Object uuid; } diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java index cbeb7870b..16bddacba 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java +++ b/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java @@ -28,4 +28,5 @@ public class MutableToFooOnlyPrimitiveTypes { private String id; private double price; private boolean active; + private Object uuid; } diff --git a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java index ddb083284..322e08e94 100644 --- a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java @@ -28,6 +28,7 @@ import java.util.Locale; import java.util.Map; import java.util.Optional; +import java.util.UUID; import com.hotels.beans.sample.FromFoo; import com.hotels.beans.sample.FromFooAdvFields; @@ -155,6 +156,6 @@ private FromFooAdvFields createFromFooAdvFields() { * @return the {@link FromFooOnlyPrimitiveTypes} instance. */ private FromFooOnlyPrimitiveTypes createFromFooPrimitiveTypes() { - return new FromFooOnlyPrimitiveTypes(ID.toString(), ID.intValue(), PRICE, String.valueOf(ACTIVE)); + return new FromFooOnlyPrimitiveTypes(ID.toString(), ID.intValue(), PRICE, String.valueOf(ACTIVE), UUID.randomUUID()); } } From 7f44c60c6bf4f7f78db8c39654165006cd5072da Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jun 2021 08:39:41 +0200 Subject: [PATCH 1348/1786] Removes the default profile to let the javadoc generation happening --- CHANGELOG.md | 4 ++++ bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 11 +---------- 8 files changed, 11 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bd8df612..d189b56af 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [2.0.1.1] 2021.06.24 +#### Adds +* Adds the javadoc generation to the release + ### [2.0.1] 2021.06.23 #### Changed * Fixes an issue that was preventing the transformation of Object type fields diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 620929f22..f0191265e 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.1-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 402f677b5..0c708af46 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 81a35a788..c3269ad2c 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 590fe2aa9..5c9761b87 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0a74d1d39..dd1270715 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2d94162ac..7f50c63b4 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 53079fc44..ce2cef7b8 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.2-SNAPSHOT + 2.0.1.1-SNAPSHOT pom 2019 @@ -194,15 +194,6 @@ - - default - - true - - - true - - relaxed From 8c4479d0bc2b43f72cc71bccb992dacff64627ae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jun 2021 08:41:14 +0200 Subject: [PATCH 1349/1786] [maven-release-plugin] prepare release 2.0.1.1 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index f0191265e..596677b35 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.1-SNAPSHOT + 2.0.1.1 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 0c708af46..82e17a1ec 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.1-SNAPSHOT + 2.0.1.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index c3269ad2c..eb732230c 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.1-SNAPSHOT + 2.0.1.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 5c9761b87..2ae837a63 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.1-SNAPSHOT + 2.0.1.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index dd1270715..8a88bda93 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.1-SNAPSHOT + 2.0.1.1 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 7f50c63b4..5bd30b1c4 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.1-SNAPSHOT + 2.0.1.1 diff --git a/pom.xml b/pom.xml index ce2cef7b8..57428cd7c 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.1.1-SNAPSHOT + 2.0.1.1 pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - HEAD + 2.0.1.1 From 84b33d365075e9c01056e0e613e015da3550e213 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jun 2021 08:41:21 +0200 Subject: [PATCH 1350/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 596677b35..620929f22 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.1 + 2.0.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 82e17a1ec..402f677b5 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.1 + 2.0.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index eb732230c..81a35a788 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.1 + 2.0.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 2ae837a63..590fe2aa9 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.1 + 2.0.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 8a88bda93..0a74d1d39 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.1 + 2.0.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 5bd30b1c4..2d94162ac 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.1 + 2.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 57428cd7c..2fb29bf86 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/HotelsDotCom/bull - 2.0.1.1 + 2.0.2-SNAPSHOT pom 2019 @@ -102,7 +102,7 @@ scm:git:git@github.com:HotelsDotCom/bull.git scm:git:git@github.com:HotelsDotCom/bull.git https://github.com/HotelsDotCom/bull - 2.0.1.1 + HEAD From 8da9bdbf5776d3a2cb3a4fb9af53a001f860a28f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 24 Jun 2021 09:09:54 +0200 Subject: [PATCH 1351/1786] minor: changelog update --- CHANGELOG-JDK8.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index b5d4e9e6c..8c1cc3585 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -### [1.7.5-jdk8] 2020.06.23 +### [1.7.6-jdk8] 2020.06.23 #### Changed * * Fixes an issue that was preventing the transformation of Object type fields From 1e77b8a068338921dfb1e823def6a071fdcb4ca9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Jun 2021 02:00:46 +0000 Subject: [PATCH 1352/1786] Bump checkstyle from 8.43 to 8.44 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 8.43 to 8.44. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-8.43...checkstyle-8.44) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2fb29bf86..7ab8f3c4f 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ 3.0.1 3.3.0 3.1.2 - 8.43 + 8.44 2.12.1 false From bd61ea99529f5fc02ff2b8f258e1a063fdba8586 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 12:50:13 +0200 Subject: [PATCH 1353/1786] Updates any reference from hotelsDotCom repo to the new one: ExpediaGroup --- .github/CODEOWNERS | 6 +-- CHANGELOG-JDK8.md | 34 ++++++++--------- CHANGELOG.md | 38 +++++++++---------- PULL_REQUEST_TEMPLATE.md | 4 +- README.md | 30 +++++++-------- RELEASE.md | 10 ++--- .../beans/transformer/TransformerImpl.java | 2 +- code-of-conduct.md | 2 +- .../site/markdown/transformer/bean/testing.md | 2 +- docs/site/site.xml | 4 +- pom.xml | 8 ++-- 11 files changed, 70 insertions(+), 70 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a542d1ebc..3f21d07b2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,8 +1,8 @@ # CODEOWNERS file defines the users/teams that are able to approve pull requests. # These owners will be the default owners for everything on this repo. -# https://github.com/HotelsDotCom/bull +# https://github.com/ExpediaGroup/bull -* @HotelsDotCom/bull-committers borriello.fabio@gmail.com +* @ExpediaGroup/bull-committers borriello.fabio@gmail.com # Only some members of Customer Insights can alter the CODEOWNERS file -.github/CODEOWNERS borriello.fabio@gmail.com @HotelsDotCom/bull-admin \ No newline at end of file +.github/CODEOWNERS borriello.fabio@gmail.com @ExpediaGroup/bull-admin \ No newline at end of file diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 8c1cc3585..a07f0c9ab 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -25,7 +25,7 @@ All notable changes to this project will be documented in this file. ### [1.7.0-jdk8] 2020.03.20 #### Added -* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). +* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/ExpediaGroup/bull/issues/144)). #### Changed * Updated `hibernate-validator` version to `6.1.3.Final` (was `6.1.2.Final`). @@ -40,7 +40,7 @@ All notable changes to this project will be documented in this file. ### [1.6.4] 2019.12.24 #### Added -* Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). +* Implemented Wildcards types support (see: [Issue 111](https://github.com/ExpediaGroup/bull/issues/111)). * Implemented transformation of a field declared with its interface. ### [1.6.3.1-jdk8] 2019.12.19 @@ -103,26 +103,26 @@ All notable changes to this project will be documented in this file. ### [1.1.23] 2019.08.06 #### Added -* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). +* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/ExpediaGroup/bull/issues/61)). #### Changed * Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled * Modified Transformer initialization in order to create a `ConversionAnalyzer` instance only if the automatic conversion is enabled ### [1.1.22] 2019.07.03 #### Added -* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/HotelsDotCom/bull/issues/73)). +* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/ExpediaGroup/bull/issues/73)). ### [1.1.21] 2019.06.27 #### Changed -* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/HotelsDotCom/bull/issues/70)). +* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/ExpediaGroup/bull/issues/70)). ### [1.1.20] 2019.05.24 #### Added -* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/HotelsDotCom/bull/issues/62)). -* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). +* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/ExpediaGroup/bull/issues/62)). +* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/ExpediaGroup/bull/issues/68)). * Added check during project build in order to prevent the add different versions of the same dependency. #### Fixed -* Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). +* Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/ExpediaGroup/bull/issues/64)). ### [1.1.19] 2019.05.23 #### Changed @@ -139,7 +139,7 @@ All notable changes to this project will be documented in this file. ### [1.1.16] 2019.05.11 ### Added -* Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/HotelsDotCom/bull/issues/57)). +* Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/ExpediaGroup/bull/issues/57)). ### [1.1.15] 2019.05.08 #### Changed @@ -153,11 +153,11 @@ All notable changes to this project will be documented in this file. ### [1.1.13] 2019.04.18 #### Changed * Improved optional usage. -* Fixed bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). +* Fixed bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/ExpediaGroup/bull/issues/52)). ### [1.1.12] 2019.04.06 #### Added -* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). +* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/ExpediaGroup/bull/issues/44)). ### [1.1.10] 2019.03.31 #### Added @@ -169,7 +169,7 @@ All notable changes to this project will be documented in this file. ### [1.1.8] 2019.03.22 #### Added -* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/HotelsDotCom/bull/issues/38)) +* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/ExpediaGroup/bull/issues/38)) * Performance improvement ### [1.1.7] 2019.03.20 @@ -178,7 +178,7 @@ All notable changes to this project will be documented in this file. ### [1.1.6] 2019.03.05 #### Added -* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) for project compiled with `jdk` 8. +* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/ExpediaGroup/bull/issues/24)) for project compiled with `jdk` 8. * Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` ### [1.1.5] 2019.03.03 @@ -187,7 +187,7 @@ All notable changes to this project will be documented in this file. ### [1.1.4] 2019.02.20 #### Added -* Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/HotelsDotCom/bull/issues/27)). +* Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/ExpediaGroup/bull/issues/27)). * Added possibility to apply a transformation function on all fields matching with the given name without evaluating the full field path. * Added samples and tests for the above functionality #### Fixed @@ -195,7 +195,7 @@ All notable changes to this project will be documented in this file. ### [1.1.3] 2019.02.17 #### Added -* Added static transformation functionality (see: [Issue 25](https://github.com/HotelsDotCom/bull/issues/25)). +* Added static transformation functionality (see: [Issue 25](https://github.com/ExpediaGroup/bull/issues/25)). ### [1.1.2] 2019.02 #### Added @@ -229,7 +229,7 @@ All notable changes to this project will be documented in this file. * Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). * Updated `hotels-oss-parent` version to `4.0.0` (was `2.3.5`). #### Added -* Configured Travis in order to automatically build the application, perform a quality check and publish site. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) +* Configured Travis in order to automatically build the application, perform a quality check and publish site. Travis build site available [here](https://travis-ci.org/ExpediaGroup/bull) * Added build, test coverage and security badge to readme file. ### [1.0.15] 2019.01.23 @@ -239,7 +239,7 @@ All notable changes to this project will be documented in this file. ### [1.0.14] 2019.01.18 #### Added * Added possibility to configure the transformer in order to set the default value for all destination's object fields that are not existing in the source object. - See [README.md](https://github.com/HotelsDotCom/bull/blob/master/README.md) for more details. + See [README.md](https://github.com/ExpediaGroup/bull/blob/master/README.md) for more details. #### Changed * Jumped to version `1.0.14` in order to be consequent to the previous library version hosted on a private repo. diff --git a/CHANGELOG.md b/CHANGELOG.md index d189b56af..ac5d84018 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,7 +38,7 @@ All notable changes to this project will be documented in this file. ### [1.7.1] 2020.03.21 #### Added -* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/HotelsDotCom/bull/issues/144)). +* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/ExpediaGroup/bull/issues/144)). #### Changed * Updated `hibernate-validator` version to `6.1.4.Final` (was `6.1.2.Final`). @@ -53,7 +53,7 @@ All notable changes to this project will be documented in this file. ### [1.6.4] 2019.12.24 #### Added -* Implemented Wildcards types support (see: [Issue 111](https://github.com/HotelsDotCom/bull/issues/111)). +* Implemented Wildcards types support (see: [Issue 111](https://github.com/ExpediaGroup/bull/issues/111)). * Implemented transformation of a field declared with its interface. ### [1.6.3.2] 2019.12.19 @@ -115,7 +115,7 @@ All notable changes to this project will be documented in this file. ### [1.5.0] 2019.08.06 #### Added -* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/HotelsDotCom/bull/issues/61)). +* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/ExpediaGroup/bull/issues/61)). #### Changed * Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled * Modified Transformer initialization in order to create a `ConversionAnalyzer` instance only if the automatic conversion is enabled @@ -126,18 +126,18 @@ All notable changes to this project will be documented in this file. ### [1.4.7] 2019.07.03 #### Added -* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/HotelsDotCom/bull/issues/73)). +* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/ExpediaGroup/bull/issues/73)). ### [1.4.6] 2019.06.27 #### Changed -* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/HotelsDotCom/bull/issues/70)). +* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/ExpediaGroup/bull/issues/70)). ### [1.4.5] 2019.06.05 #### Added -* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/HotelsDotCom/bull/issues/68)). +* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/ExpediaGroup/bull/issues/68)). * Added check during project build in order to prevent the add different versions of the same dependency. #### Changed -* Modified library in order to let it able to retrieve values from getters if a field does not exist (see: [Issue 66](https://github.com/HotelsDotCom/bull/issues/66)). +* Modified library in order to let it able to retrieve values from getters if a field does not exist (see: [Issue 66](https://github.com/ExpediaGroup/bull/issues/66)). ### [1.4.4.1] 2019.05.29 #### Changed @@ -146,9 +146,9 @@ All notable changes to this project will be documented in this file. ### [1.4.2] 2019.05.24 #### Added -* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/HotelsDotCom/bull/issues/62)). +* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/ExpediaGroup/bull/issues/62)). #### Fixed -* Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/HotelsDotCom/bull/issues/64)). +* Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/ExpediaGroup/bull/issues/64)). ### [1.4.1.1] 2019.05.24 #### Changed @@ -165,7 +165,7 @@ All notable changes to this project will be documented in this file. ### [1.3.2] 2019.05.11 ### Added -* Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/HotelsDotCom/bull/issues/57)). +* Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/ExpediaGroup/bull/issues/57)). ### [1.3.1] 2019.05.08 #### Changed @@ -182,11 +182,11 @@ All notable changes to this project will be documented in this file. ### [1.2.7] 2019.04.18 #### Changed * Improved optional usage. -* Fixed a bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/HotelsDotCom/bull/issues/52)). +* Fixed a bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/ExpediaGroup/bull/issues/52)). ### [1.2.6] 2019.04.06 #### Added -* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/HotelsDotCom/bull/issues/44)). +* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/ExpediaGroup/bull/issues/44)). ### [1.2.5] 2019.03.31 #### Added @@ -198,7 +198,7 @@ All notable changes to this project will be documented in this file. ### [1.2.3] 2019.03.22 #### Added -* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/HotelsDotCom/bull/issues/38)) +* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/ExpediaGroup/bull/issues/38)) * Performance improvement ### [1.2.2] 2019.03.20 @@ -207,12 +207,12 @@ All notable changes to this project will be documented in this file. ### [1.2.1] 2019.03.05 #### Added -* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/HotelsDotCom/bull/issues/24)) +* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/ExpediaGroup/bull/issues/24)) * Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` ### [1.2.0] 2019.02.25 #### Added -* Added possibility to skip the object validation (see: [Issue 31](https://github.com/HotelsDotCom/bull/issues/31)) +* Added possibility to skip the object validation (see: [Issue 31](https://github.com/ExpediaGroup/bull/issues/31)) * Provided documentation and samples for the above functionality ### Changed - Updated `jdk` version to `11` (was `1.8`). @@ -221,7 +221,7 @@ All notable changes to this project will be documented in this file. ### [1.1.4] 2019.02.20 #### Added -* Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/HotelsDotCom/bull/issues/27)). +* Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/ExpediaGroup/bull/issues/27)). * Added possibility to apply a transformation function on all fields matching with the given name without evaluating the full field path. * Added samples and tests for the above functionality #### Fixed @@ -229,7 +229,7 @@ All notable changes to this project will be documented in this file. ### [1.1.3] 2019.02.17 #### Added -* Added static transformation functionality (see: [Issue 25](https://github.com/HotelsDotCom/bull/issues/25)). +* Added static transformation functionality (see: [Issue 25](https://github.com/ExpediaGroup/bull/issues/25)). ### [1.1.2] 2019.02 #### Added @@ -263,7 +263,7 @@ All notable changes to this project will be documented in this file. * Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). * Updated `hotels-oss-parent` version to `4.0.0` (was `2.3.5`). #### Added -* Configured Travis in order to automatically build the application, perform a quality check and publish site. Travis build site available [here](https://travis-ci.org/HotelsDotCom/bull) +* Configured Travis in order to automatically build the application, perform a quality check and publish site. Travis build site available [here](https://travis-ci.org/ExpediaGroup/bull) * Added build, test coverage and security badge to readme file. ### [1.0.15] 2019.01.23 @@ -273,7 +273,7 @@ All notable changes to this project will be documented in this file. ### [1.0.14] 2019.01.18 #### Added * Added possibility to configure the transformer in order to set the default value for all destination's object fields that are not existing in the source object. - See [README.md](https://github.com/HotelsDotCom/bull/blob/master/README.md) for more details. + See [README.md](https://github.com/ExpediaGroup/bull/blob/master/README.md) for more details. #### Changed * Jumped to version `1.0.14` in order to be consequent to the previous library version hosted on a private repo. diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index e78e3bfd0..2533dd05f 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -27,9 +27,9 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] My changes generate no new warnings - [ ] Any dependent changes have been merged and published in downstream modules - [ ] My changes have no bad impacts on performances -- [ ] My changes have been tested through Unit Tests and the overall coverage has not decreased. Check the coverall report for your branch: [here](https://coveralls.io/github/HotelsDotCom/bull) +- [ ] My changes have been tested through Unit Tests and the overall coverage has not decreased. Check the coverall report for your branch: [here](https://coveralls.io/github/ExpediaGroup/bull) - [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file - [ ] Any implemented change has been added in the [CHANGELOG-JDK8.md](./CHANGELOG-JDK8.md) file -- [ ] My changes have been applied on a separate branch too with compatibility with Java 8. Follow this [instructions](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#3-prepare-the-jdk8-release) for help. +- [ ] My changes have been applied on a separate branch too with compatibility with Java 8. Follow this [instructions](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#3-prepare-the-jdk8-release) for help. - [ ] The maven version has been increased. diff --git a/README.md b/README.md index ec48a773d..93b5d862b 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,14 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central&color=blue)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg?color=blue)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) -[![Build Status](https://travis-ci.com/HotelsDotCom/bull.svg?branch=master)](https://travis-ci.com/HotelsDotCom/bull) +[![Build Status](https://travis-ci.com/ExpediaGroup/bull.svg?branch=master)](https://travis-ci.com/ExpediaGroup/bull) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) -[![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://hotelsdotcom.github.io/bull/) -[![Coverage Status](https://coveralls.io/repos/github/HotelsDotCom/bull/badge.svg?branch=master)](https://coveralls.io/github/HotelsDotCom/bull?branch=master) +[![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://opensource.expediagroup.com/bull/) +[![Coverage Status](https://coveralls.io/repos/github/ExpediaGroup/bull/badge.svg?branch=master)](https://coveralls.io/github/ExpediaGroup/bull?branch=master) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) -![GitHub license](https://img.shields.io/github/license/HotelsDotCom/bull.svg) -[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=HotelsDotCom/bull)](https://dependabot.com) +![GitHub license](https://img.shields.io/github/license/ExpediaGroup/bull.svg) +[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=ExpediaGroup/bull)](https://dependabot.com) All BULL modules are available on Maven Central: @@ -148,12 +148,12 @@ mvnw.cmd versions:display-dependency-updates -P check-for-updates # Feature samples -* [Bean Transformation](https://github.com/HotelsDotCom/bull#bean-transformation-samples) -* [Bean Validation](https://github.com/HotelsDotCom/bull#validation-samples) -* [Primitive Type conversion](https://github.com/HotelsDotCom/bull#primitive-type-object-converter) -* [Map Transformation](https://hotelsdotcom.github.io/bull/transformer/map/samples.html) -* [Supported Builder Pattern](https://hotelsdotcom.github.io/bull/transformer/bean/builder.html) -* [How to use it in Kotlin](https://hotelsdotcom.github.io/bull/kotlin.html) +* [Bean Transformation](https://github.com/ExpediaGroup/bull#bean-transformation-samples) +* [Bean Validation](https://github.com/ExpediaGroup/bull#validation-samples) +* [Primitive Type conversion](https://github.com/ExpediaGroup/bull#primitive-type-object-converter) +* [Map Transformation](https://opensource.expediagroup.com/bull/transformer/map/samples.html) +* [Supported Builder Pattern](https://opensource.expediagroup.com/bull/transformer/bean/builder.html) +* [How to use it in Kotlin](https://opensource.expediagroup.com/bull/kotlin.html) ## Bean transformation samples @@ -939,11 +939,11 @@ byte converted = conversionFunction.map(processor -> processor.apply(c)).orElse( ## `Map` transformation samples -Samples on how to transform a `Map` and all others function applicable to it can be viewed [here](https://hotelsdotcom.github.io/bull/transformer/mapTransformer.html) +Samples on how to transform a `Map` and all others function applicable to it can be viewed [here](https://opensource.expediagroup.com/bull/transformer/mapTransformer.html) ## Documentation -Detailed project documentation is available [here](https://hotelsdotcom.github.io/bull), including some samples for [testing the library](https://hotelsdotcom.github.io/bull/transformer/testing.html) inside your project. +Detailed project documentation is available [here](https://opensource.expediagroup.com/bull), including some samples for [testing the library](https://opensource.expediagroup.com/bull/transformer/testing.html) inside your project. An article that explains how it works, with suggestion and examples is available on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) @@ -965,12 +965,12 @@ All the instructions for releasing a new version are available at [RELEASES.md]( ## Badge your project -[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) +[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/ExpediaGroup/bull) Add the following snippet in your Markdown file: ``` -[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/HotelsDotCom/bull) +[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/ExpediaGroup/bull) ``` ## Support diff --git a/RELEASE.md b/RELEASE.md index 8531d5353..eaf16e2ca 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -64,7 +64,7 @@ $ git checkout -b feature/my-new-feature-jdk8 1.7.0-jdk8 ``` **IMPORTANT:** In the new branch, apply only the changes introduced comparing the code with the `jdk11` branch. -When completed, commit your code and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. +When completed, commit your code and verify that the [Travis build](https://travis-ci.org/ExpediaGroup/bull/builds) is green. ## Example of a release process sequence @@ -76,8 +76,8 @@ The following examples assume that your local repository is: The guide explains how to do a release both the `jdk11` and `jdk8` compatible: -* [JDK8 Release](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk8-release) -* [JDK11 Release](https://github.com/HotelsDotCom/bull/blob/master/RELEASE.md#jdk11-release) +* [JDK8 Release](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#jdk8-release) +* [JDK11 Release](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#jdk11-release) **IMPORTANT:** In case something goes wrong, do not leave ghost tags or tags not related to a successful release. @@ -119,7 +119,7 @@ The maven version is now set with the latest released, but you need to change it $ mvn versions:set -D newVersion=X.Y.Z-jdk8 ``` -Commit all the changes and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. +Commit all the changes and verify that the [Travis build](https://travis-ci.org/ExpediaGroup/bull/builds) is green. #### 4. Create a new tag for the release version @@ -172,7 +172,7 @@ The maven version is now set with the latest released, but you need to change it $ mvn versions:set -D newVersion=X.Y.Z ``` -Commit all the changes and verify that the [Travis build](https://travis-ci.org/HotelsDotCom/bull/builds) is green. +Commit all the changes and verify that the [Travis build](https://travis-ci.org/ExpediaGroup/bull/builds) is green. #### 3. Create a new tag for the release version diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java index 3374c6f7a..110e8a67e 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java @@ -189,7 +189,7 @@ protected K handleInjectionException(final T sourceObj, final Class ta } else { errorMsg = "Constructor's parameters name have been removed from the compiled code. " + "This caused a problems during the: " + targetClass.getSimpleName() + " injection. " - + "Consider to use: @ConstructorArg annotation: https://github.com/HotelsDotCom/bull#different-field-names-defining-constructor-args " + + "Consider to use: @ConstructorArg annotation: https://github.com/ExpediaGroup/bull#different-field-names-defining-constructor-args " + "or add the property: true to your maven-compiler configuration"; } } else { diff --git a/code-of-conduct.md b/code-of-conduct.md index f29be49b6..cc018369d 100644 --- a/code-of-conduct.md +++ b/code-of-conduct.md @@ -55,7 +55,7 @@ further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise, unacceptable behavior may be -reported by contacting a member of the project team: [Hcom Tech Checkout Payments](https://github.com/orgs/HotelsDotCom/teams/bull-committers/members). All +reported by contacting a member of the project team: [Hcom Tech Checkout Payments](https://github.com/orgs/ExpediaGroup/teams/bull-committers/members). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality concerning the reporter of an incident. diff --git a/docs/site/markdown/transformer/bean/testing.md b/docs/site/markdown/transformer/bean/testing.md index d50e35bd2..d5e92b9e1 100644 --- a/docs/site/markdown/transformer/bean/testing.md +++ b/docs/site/markdown/transformer/bean/testing.md @@ -27,7 +27,7 @@ For both scenarios: 1 and 2 we can use a mocked version of the `BeanUtils` objec ### Before start As BULL contains final methods that need to be mocked and, as Mockito requires a special configuration in order to mock final classes/methods, an extension needs -to be added to the test resource folder. This file is available [here](https://github.com/HotelsDotCom/bull/tree/master/src/test/resources/mockito-extensions). +to be added to the test resource folder. This file is available [here](https://github.com/ExpediaGroup/bull/tree/master/src/test/resources/mockito-extensions). All the examples will be based on the following source object and destination object: diff --git a/docs/site/site.xml b/docs/site/site.xml index 77a0aa585..c0a0849df 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -12,7 +12,7 @@ false true - HotelsDotCom/bull + ExpediaGroup/bull right #cf2d35 @@ -57,7 +57,7 @@ - + diff --git a/pom.xml b/pom.xml index 7ab8f3c4f..a8a784670 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ BULL - Bean Utils Light Library com.hotels.beans bean-utils-library-parent - https://github.com/HotelsDotCom/bull + https://github.com/ExpediaGroup/bull 2.0.2-SNAPSHOT pom 2019 @@ -99,9 +99,9 @@ - scm:git:git@github.com:HotelsDotCom/bull.git - scm:git:git@github.com:HotelsDotCom/bull.git - https://github.com/HotelsDotCom/bull + scm:git:git@github.com:ExpediaGroup/bull.git + scm:git:git@github.com:ExpediaGroup/bull.git + https://github.com/ExpediaGroup/bull HEAD From dc57dd53c0240468d965bd4be9f9db244532afc6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 14:30:16 +0200 Subject: [PATCH 1354/1786] adds the github action file --- .github/workflows/github-actions.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/github-actions.yml diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml new file mode 100644 index 000000000..dca839c57 --- /dev/null +++ b/.github/workflows/github-actions.yml @@ -0,0 +1,17 @@ +name: BULL CI/CD +on: [push] +jobs: + Explore-GitHub-Actions: + runs-on: ubuntu-latest + steps: + - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." + - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" + - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + - name: Check out repository code + uses: actions/checkout@v2 + - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." + - run: echo "🖥️ The workflow is now ready to test your code on the runner." + - name: List files in the repository + run: | + ls ${{ github.workspace }} + - run: echo "🍏 This job's status is ${{ job.status }}." \ No newline at end of file From bb14676d08d4ead408c46b7aa7ddde0971b428eb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 14:37:13 +0200 Subject: [PATCH 1355/1786] adds the github action configuration with a simple maven build step --- .github/workflows/github-actions.yml | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index dca839c57..bc17b610f 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,17 +1,14 @@ -name: BULL CI/CD +name: BULL CI on: [push] jobs: - Explore-GitHub-Actions: + build: runs-on: ubuntu-latest steps: - - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - - name: Check out repository code - uses: actions/checkout@v2 - - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ github.workspace }} - - run: echo "🍏 This job's status is ${{ job.status }}." \ No newline at end of file + - uses: actions/checkout@v2 + - name: Set up JDK 15 + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' + - name: Build with Maven + run: mvn clean install jacoco:report-aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode From e7b7a4c728f464909383a04f0afe9d3c99b5fc1a Mon Sep 17 00:00:00 2001 From: Daniel Albuquerque Date: Mon, 12 Jul 2021 13:37:28 +0100 Subject: [PATCH 1356/1786] Update github-actions.yml --- .github/workflows/github-actions.yml | 33 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index dca839c57..8457002b6 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,17 +1,22 @@ -name: BULL CI/CD -on: [push] +name: Run tests with JDK 15 + +on: + pull_request: + branches: + - master + push: + branches: + - master + jobs: - Explore-GitHub-Actions: + build: + name: Run tests runs-on: ubuntu-latest steps: - - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - - name: Check out repository code - uses: actions/checkout@v2 - - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ github.workspace }} - - run: echo "🍏 This job's status is ${{ job.status }}." \ No newline at end of file + - uses: actions/checkout@v1 + - uses: AdoptOpenJDK/install-jdk@v1 + with: + version: '15' + architecture: x64 + - name: Build with Maven + run: ./mvnw verify From 15a486d9bfee451aa2d6565c1ca861f75abfdf60 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 15:14:50 +0200 Subject: [PATCH 1357/1786] disabling coveralls --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 46d6d06c9..0261faf5c 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -13,4 +13,4 @@ jobs: env: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - name: Build and Test - run: mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + run: mvn clean install jacoco:report-aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode From acbab4bde2b9964aeb265b393ca4698ad3da1c24 Mon Sep 17 00:00:00 2001 From: Daniel Albuquerque Date: Mon, 12 Jul 2021 14:18:22 +0100 Subject: [PATCH 1358/1786] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 71 +++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..e75e50376 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,71 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + schedule: + - cron: '45 1 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'java' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From c7738d115a3caac4527fa93a9d8928c2092c4c6f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 15:35:54 +0200 Subject: [PATCH 1359/1786] disables mycecila --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 0261faf5c..97a001131 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -13,4 +13,4 @@ jobs: env: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - name: Build and Test - run: mvn clean install jacoco:report-aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + run: mvn clean install jacoco:report-aggregate -B -Dlicense.skipAddThirdParty=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode From caa2baf4b9b819f95670496b6b72da6b06db6cbf Mon Sep 17 00:00:00 2001 From: Daniel Albuquerque Date: Mon, 12 Jul 2021 14:41:18 +0100 Subject: [PATCH 1360/1786] Update codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e75e50376..55b2c3b7f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,6 +38,11 @@ jobs: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: '15' + - name: Checkout repository uses: actions/checkout@v2 @@ -51,21 +56,11 @@ jobs: # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release + - run: | + ./mvnw clean verify - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 From 30d1641c8e045eced91cf896d11c88986f238520 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 15:50:53 +0200 Subject: [PATCH 1361/1786] disables mycecila --- .github/workflows/github-actions.yml | 4 +-- pom.xml | 44 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 97a001131..0c5b6e385 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -10,7 +10,7 @@ jobs: with: java-version: '15' distribution: 'adopt' + - name: Build and Test env: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - - name: Build and Test - run: mvn clean install jacoco:report-aggregate -B -Dlicense.skipAddThirdParty=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + run: mvn clean install jacoco:report-aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode diff --git a/pom.xml b/pom.xml index a8a784670..4a221d03e 100644 --- a/pom.xml +++ b/pom.xml @@ -247,6 +247,16 @@ @{argLine} --enable-preview + + com.mycila + license-maven-plugin + ${license.maven.plugin.version} + + + none + + + @@ -255,6 +265,20 @@ true + + + + com.mycila + license-maven-plugin + ${license.maven.plugin.version} + + + none + + + + + @@ -312,6 +336,16 @@ + + com.mycila + license-maven-plugin + ${license.maven.plugin.version} + + + none + + + @@ -325,6 +359,16 @@ versions-maven-plugin false + + com.mycila + license-maven-plugin + ${license.maven.plugin.version} + + + none + + + From b17ababa6f3535200b81f62bbf9d21e9de3dc21e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 15:53:37 +0200 Subject: [PATCH 1362/1786] adds the coverall analysis --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 0c5b6e385..759425eed 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -13,4 +13,4 @@ jobs: - name: Build and Test env: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - run: mvn clean install jacoco:report-aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + run: mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode From e1988b043ed738474ce545fd9698ed23ffa1947e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 16:11:18 +0200 Subject: [PATCH 1363/1786] adds another action file --- ...ub-actions.yml => github-default-actions.yml} | 2 +- .github/workflows/github-release-actions.yml | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) rename .github/workflows/{github-actions.yml => github-default-actions.yml} (97%) create mode 100644 .github/workflows/github-release-actions.yml diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-default-actions.yml similarity index 97% rename from .github/workflows/github-actions.yml rename to .github/workflows/github-default-actions.yml index 759425eed..3ce4009a9 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -1,7 +1,7 @@ name: BULL CI on: [push] jobs: - build: + BuildAndTest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml new file mode 100644 index 000000000..92cde7e5c --- /dev/null +++ b/.github/workflows/github-release-actions.yml @@ -0,0 +1,16 @@ +name: BULL Release +on: [push] +jobs: + Release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 15 + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' + - name: Build and Test + env: + COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + run: mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode From 88e2e494bab77c820dec545842627557342ed0af Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 16:17:57 +0200 Subject: [PATCH 1364/1786] testing the tag condition --- .github/workflows/github-release-actions.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 92cde7e5c..fdf06ab37 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -1,5 +1,10 @@ name: BULL Release -on: [push] +on: + push: + branches: + - "!*" + tags: + - "*" jobs: Release: runs-on: ubuntu-latest From 61a18608b3ebf7bb9d7603f48371668ede4814f3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 16:22:58 +0200 Subject: [PATCH 1365/1786] setting names to the job --- .github/workflows/github-default-actions.yml | 29 ++++++++++---------- .github/workflows/github-release-actions.yml | 3 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 3ce4009a9..058bd8d65 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -1,16 +1,17 @@ -name: BULL CI +name: Build and Test on: [push] jobs: - BuildAndTest: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 15 - uses: actions/setup-java@v2 - with: - java-version: '15' - distribution: 'adopt' - - name: Build and Test - env: - COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - run: mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + job: + name: "BuildAndTest" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 15 + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' + - name: Build and Test + env: + COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + run: mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index fdf06ab37..93041213d 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -6,7 +6,8 @@ on: tags: - "*" jobs: - Release: + job: + name: "Site Build and Quality check" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From d6d064947bf3c0298a362c908d7494683a6ec31d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 16:23:50 +0200 Subject: [PATCH 1366/1786] changing name --- .github/workflows/github-default-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 058bd8d65..9d075df41 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -2,7 +2,7 @@ name: Build and Test on: [push] jobs: job: - name: "BuildAndTest" + name: "Build and Test" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From 9610c42cda3fe454eedd8065989b71bfcf2edd04 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 12 Jul 2021 16:55:44 +0200 Subject: [PATCH 1367/1786] Adds the sonar cloud quality check on code tagging --- .github/workflows/github-default-actions.yml | 1 - .github/workflows/github-release-actions.yml | 20 +++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 9d075df41..24b7c20c9 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -2,7 +2,6 @@ name: Build and Test on: [push] jobs: job: - name: "Build and Test" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 93041213d..0cd0b22aa 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -11,12 +11,26 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: Extract build information + id: build_info + run: | + echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} + echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} + echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - name: Set up JDK 15 uses: actions/setup-java@v2 with: java-version: '15' distribution: 'adopt' - - name: Build and Test + - name: Quality check and Site build env: - COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - run: mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + SOURCE_NAME: ${{ steps.build_info.outputs.SOURCE_NAME }} + SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + SONAR_PROJECT_KEY: ${{ secrets.SONAR_PROJECT_KEY }} + SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + mvn versions:set -D newVersion=$TAG_NAME -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn install sonar:sonar -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=SONAR_TOKEN -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q From b8922dad26469dc099d3a29e7d8074f144e575cd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 08:46:54 +0200 Subject: [PATCH 1368/1786] skips the test coverage during the site release --- .github/workflows/github-default-actions.yml | 1 + .github/workflows/github-release-actions.yml | 7 +++++++ pom.xml | 1 + 3 files changed, 9 insertions(+) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 24b7c20c9..9d075df41 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -2,6 +2,7 @@ name: Build and Test on: [push] jobs: job: + name: "Build and Test" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 0cd0b22aa..775679464 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -34,3 +34,10 @@ jobs: run: | mvn versions:set -D newVersion=$TAG_NAME -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn mvn install sonar:sonar -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=SONAR_TOKEN -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - name: Deploy GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: target/site + user_name: eg-oss-ci + user_email: oss@expediagroup.com diff --git a/pom.xml b/pom.xml index 4a221d03e..c230ff5e1 100644 --- a/pom.xml +++ b/pom.xml @@ -233,6 +233,7 @@ true false true + true From 05fbc5153b2995c555d0ba3c74d0b9549fe6ab70 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 08:51:05 +0200 Subject: [PATCH 1369/1786] test sonar --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 775679464..f7b03f114 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -33,7 +33,7 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | mvn versions:set -D newVersion=$TAG_NAME -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install sonar:sonar -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=SONAR_TOKEN -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -Dsonar.branch.name=test - name: Deploy GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: From 98c4565917411a111fc4b027326b6f09b256c727 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 08:58:38 +0200 Subject: [PATCH 1370/1786] test sonar --- .github/workflows/github-release-actions.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index f7b03f114..0a1553c04 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -1,10 +1,11 @@ name: BULL Release -on: - push: - branches: - - "!*" - tags: - - "*" +#on: +# push: +# branches: +# - "!*" +# tags: +# - "*" +on: [push] jobs: job: name: "Site Build and Quality check" @@ -30,10 +31,10 @@ jobs: SONAR_PROJECT_KEY: ${{ secrets.SONAR_PROJECT_KEY }} SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }} run: | mvn versions:set -D newVersion=$TAG_NAME -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -Dsonar.branch.name=test + mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_LOGIN -Dsonar.branch.name=test -Psite-release - name: Deploy GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: From 5d38599e430427b5c7ab54b22bc8f581f6e78e0b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:09:28 +0200 Subject: [PATCH 1371/1786] test sonar --- .github/workflows/github-release-actions.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 0a1553c04..bca68ddaa 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -31,10 +31,10 @@ jobs: SONAR_PROJECT_KEY: ${{ secrets.SONAR_PROJECT_KEY }} SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn versions:set -D newVersion=$TAG_NAME -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_LOGIN -Dsonar.branch.name=test -Psite-release +# mvn versions:set -D newVersion=$TAG_NAME -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dsonar.branch.name=test -Psite-release - name: Deploy GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: From 5adbbd3a2e1f4336010114f12c876a640a8bd48e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:10:22 +0200 Subject: [PATCH 1372/1786] test sonar --- .github/workflows/github-release-actions.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index bca68ddaa..a9ea432fa 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -33,7 +33,6 @@ jobs: SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | -# mvn versions:set -D newVersion=$TAG_NAME -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dsonar.branch.name=test -Psite-release - name: Deploy GitHub Pages uses: peaceiris/actions-gh-pages@v3 From 583ae9c803b8688339615724bd1dff90e6ec108c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:13:36 +0200 Subject: [PATCH 1373/1786] use the sonar organization variable --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index a9ea432fa..659eb00c0 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -33,7 +33,7 @@ jobs: SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dsonar.branch.name=test -Psite-release + mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dsonar.branch.name=test -Psite-release - name: Deploy GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: From c2b850ae34df8a970403e1cf75a1276a0c2af10b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:25:53 +0200 Subject: [PATCH 1374/1786] use the sonar organization variable --- .github/workflows/github-release-actions.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 659eb00c0..b574c0500 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -23,21 +23,20 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: Quality check and Site build + - name: Quality check env: SOURCE_NAME: ${{ steps.build_info.outputs.SOURCE_NAME }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} - SONAR_PROJECT_KEY: ${{ secrets.SONAR_PROJECT_KEY }} SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dsonar.branch.name=test -Psite-release - - name: Deploy GitHub Pages + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - name: Site Build uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: target/site user_name: eg-oss-ci user_email: oss@expediagroup.com + run: mvn install site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q From 59d44691a41760f5568bc5ee93f02cdc6be8834a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:31:50 +0200 Subject: [PATCH 1375/1786] adds the new token --- .github/workflows/github-release-actions.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index b574c0500..624001dcd 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -23,7 +23,7 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: Quality check + - name: Quality check and Site build env: SOURCE_NAME: ${{ steps.build_info.outputs.SOURCE_NAME }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} @@ -31,12 +31,11 @@ jobs: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - - name: Site Build + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + - name: Deploy GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: - github_token: ${{ secrets.GITHUB_TOKEN }} + github_token: ${{ secrets.DEPLOY_GITHUB_TOKEN }} publish_dir: target/site user_name: eg-oss-ci - user_email: oss@expediagroup.com - run: mvn install site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + user_email: oss@expediagroup.com \ No newline at end of file From 0ab4ba4cd0d5481490764c6e05d821264e7515bb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:34:32 +0200 Subject: [PATCH 1376/1786] adds the new token --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 624001dcd..9dab20d4c 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -35,7 +35,7 @@ jobs: - name: Deploy GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: - github_token: ${{ secrets.DEPLOY_GITHUB_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: target/site user_name: eg-oss-ci user_email: oss@expediagroup.com \ No newline at end of file From 1694d3fc5984c9bd0217574a4822456fe9702f57 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:37:32 +0200 Subject: [PATCH 1377/1786] adds the new token --- .github/workflows/github-release-actions.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 9dab20d4c..71b39578a 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -31,11 +31,4 @@ jobs: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - - name: Deploy GitHub Pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: target/site - user_name: eg-oss-ci - user_email: oss@expediagroup.com \ No newline at end of file + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q \ No newline at end of file From cd24b45b5eb8f113aba32b3d1ad955013aaf8c3f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:39:45 +0200 Subject: [PATCH 1378/1786] adds the new token --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 71b39578a..7935b44f0 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -31,4 +31,4 @@ jobs: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q \ No newline at end of file + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release \ No newline at end of file From 230a44d77cbab14e1c99ad2c2cabd54760fe5fb0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:45:39 +0200 Subject: [PATCH 1379/1786] divides the step --- .github/workflows/github-default-actions.yml | 7 ++++- .github/workflows/github-release-actions.yml | 28 ++++++++++++-------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 9d075df41..3a56dfd94 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -1,5 +1,10 @@ name: Build and Test -on: [push] +on: + push: + branches: + - "*" + tags: + - "!*" jobs: job: name: "Build and Test" diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 7935b44f0..6b36b018d 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -1,11 +1,10 @@ name: BULL Release -#on: -# push: -# branches: -# - "!*" -# tags: -# - "*" -on: [push] +on: + push: + branches: + - "!*" + tags: + - "*" jobs: job: name: "Site Build and Quality check" @@ -23,12 +22,19 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: Quality check and Site build + - name: Project version set env: - SOURCE_NAME: ${{ steps.build_info.outputs.SOURCE_NAME }} - SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - name: Quality check + env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release \ No newline at end of file + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -P site-release + - name: Site build + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + mvn install site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q \ No newline at end of file From 0682da98c5b5ee6bc792a451a182b2dcb9d7801d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:47:29 +0200 Subject: [PATCH 1380/1786] divides the step --- .github/workflows/github-default-actions.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 3a56dfd94..abed0fd09 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -2,9 +2,9 @@ name: Build and Test on: push: branches: + - "**" + tags-ignore: - "*" - tags: - - "!*" jobs: job: name: "Build and Test" From 414dff0869ccaf6bab85440aeca1d5f85614fe8e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:47:55 +0200 Subject: [PATCH 1381/1786] divides the step --- .github/workflows/github-default-actions.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index abed0fd09..9b3791c66 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -1,8 +1,6 @@ name: Build and Test on: push: - branches: - - "**" tags-ignore: - "*" jobs: From 48ec044403c7f77a52a7b97371b2f3c6b139fdcb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:52:04 +0200 Subject: [PATCH 1382/1786] divides the step --- .github/workflows/github-release-actions.yml | 21 ++------------------ 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 6b36b018d..7b4042e8b 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -1,10 +1,5 @@ name: BULL Release -on: - push: - branches: - - "!*" - tags: - - "*" +on: [push] jobs: job: name: "Site Build and Quality check" @@ -17,24 +12,12 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - - name: Set up JDK 15 - uses: actions/setup-java@v2 - with: - java-version: '15' - distribution: 'adopt' - - name: Project version set - env: - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} - run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - name: Quality check env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -P site-release + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -P compatibility-mode - name: Site build - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | mvn install site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q \ No newline at end of file From 7847fa6a2eae3dab2b790e3b8544c361c4e96573 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 09:55:58 +0200 Subject: [PATCH 1383/1786] divides the step --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 7b4042e8b..947f15c40 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -17,7 +17,7 @@ jobs: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -P compatibility-mode + mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -Dsonar.branch.name=test -Psite-release - name: Site build run: | mvn install site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q \ No newline at end of file From f67c11f3895f979402fd33c12d24bdae74c58d70 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:03:05 +0200 Subject: [PATCH 1384/1786] skip spotless --- .github/workflows/github-default-actions.yml | 3 +++ pom.xml | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 9b3791c66..65e5a1f1c 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -1,6 +1,9 @@ name: Build and Test on: push: + branches: + - "*" + - "*/*" tags-ignore: - "*" jobs: diff --git a/pom.xml b/pom.xml index c230ff5e1..5056fe959 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ false \#java,\#javax,\#jakarta,\#org,\#,\#com,,\#lombok,java,javax,jakarta,org,,com,,lombok - false + false @@ -737,7 +737,7 @@ - ${spotless.plugin.skip} + ${spotless.maven.plugin.skip} From d42dbedd750306932e9f4774c216154d3c165de0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:07:30 +0200 Subject: [PATCH 1385/1786] sets the jdk --- .github/workflows/github-release-actions.yml | 7 ++++++- pom.xml | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 947f15c40..fc1fb9e42 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,12 +12,17 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} + - name: Set up JDK 15 + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' - name: Quality check env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -Dsonar.branch.name=test -Psite-release + mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -Dsonar.branch.name=test -Pcompatibility-mode - name: Site build run: | mvn install site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5056fe959..6bd85895e 100644 --- a/pom.xml +++ b/pom.xml @@ -265,6 +265,7 @@ compatibility-mode true + true From 96b009cda20c8d5651cb1bb8ba6da5d055fab33f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:11:01 +0200 Subject: [PATCH 1386/1786] sets the jdk --- .github/workflows/github-release-actions.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index fc1fb9e42..763cf1f72 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -2,7 +2,7 @@ name: BULL Release on: [push] jobs: job: - name: "Site Build and Quality check" + name: "BULL Release" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -22,7 +22,7 @@ jobs: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=borriello-fabio-bitbucket -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -Dsonar.branch.name=test -Pcompatibility-mode + mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -P compatibility-mode -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - name: Site build run: | - mvn install site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q \ No newline at end of file + mvn install site:site javadoc:aggregate -P site-release \ No newline at end of file From 485738f3afbfd7867acb29d4b75d410ad956aa7c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:15:12 +0200 Subject: [PATCH 1387/1786] sets the jdk --- .github/workflows/github-release-actions.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 763cf1f72..d61b300b6 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -20,9 +20,7 @@ jobs: - name: Quality check env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=${SONAR_TOKEN} -P compatibility-mode -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }} + run: mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -P compatibility-mode - name: Site build - run: | - mvn install site:site javadoc:aggregate -P site-release \ No newline at end of file + run: mvn install site:site javadoc:aggregate -P site-release \ No newline at end of file From edaaf3816fe1b166b66457dfa42b1d758f6e8d06 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:20:25 +0200 Subject: [PATCH 1388/1786] adds the dependencies cache --- .github/workflows/github-release-actions.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index d61b300b6..7aa7a1ba5 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -6,6 +6,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: Cache maven dependencies + uses: actions/cache@v2 + env: + cache-name: cache-maven-dependencies + with: + # mvn cache files are stored in `~/.m2` + path: ~/.m2 - name: Extract build information id: build_info run: | @@ -21,6 +28,6 @@ jobs: env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }} - run: mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=${SONAR_ORGANIZATION} -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -P compatibility-mode + run: mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -P compatibility-mode - name: Site build run: mvn install site:site javadoc:aggregate -P site-release \ No newline at end of file From 621df5b65a78f79db642a9e856ef644b6cde5124 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:21:37 +0200 Subject: [PATCH 1389/1786] adds the dependencies cache --- .github/workflows/github-release-actions.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 7aa7a1ba5..394014ffe 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -13,6 +13,11 @@ jobs: with: # mvn cache files are stored in `~/.m2` path: ~/.m2 + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- - name: Extract build information id: build_info run: | From ecd91b5a8dd61432b672341a43f686d391a4cfe7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:38:43 +0200 Subject: [PATCH 1390/1786] adds the dependencies cache --- .github/workflows/github-release-actions.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 394014ffe..7ca30659a 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -29,10 +29,19 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: Quality check + - name: SonarCloud Scan + uses: sonarsource/sonarcloud-github-action@master env: - SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} - SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }} - run: mvn clean install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=3e48ff9274e9be71d176cb68da4272b08d749248 -P compatibility-mode + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: > + -Dsonar.organization=borriello-fabio-bitbucket + -Dsonar.projectKey=BULL + -Dsonar.sources=**/*.java + -Dsonar.exclusions=**/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* + -Dsonar.verbose=true - name: Site build + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: mvn install site:site javadoc:aggregate -P site-release \ No newline at end of file From 23d88fcd0507b9392a9ce27c7f28374789aa5a65 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:40:45 +0200 Subject: [PATCH 1391/1786] adds the dependencies cache --- .github/workflows/github-release-actions.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 7ca30659a..8eee80978 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -1,5 +1,5 @@ name: BULL Release -on: [push] +on: [ push ] jobs: job: name: "BULL Release" @@ -36,11 +36,11 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: args: > - -Dsonar.organization=borriello-fabio-bitbucket - -Dsonar.projectKey=BULL - -Dsonar.sources=**/*.java - -Dsonar.exclusions=**/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* - -Dsonar.verbose=true + -Dsonar.organization=borriello-fabio-bitbucket + -Dsonar.projectKey=BULL + -Dsonar.sources=**/*.java + -Dsonar.exclusions=**/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* + -Dsonar.verbose=true - name: Site build env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From d954ea2100f55b3d4c5ae21e41d038c87cd1af2c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:43:33 +0200 Subject: [PATCH 1392/1786] adds the dependencies cache --- .github/workflows/github-release-actions.yml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 8eee80978..5902b2e5b 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -1,5 +1,5 @@ name: BULL Release -on: [ push ] +on: [push] jobs: job: name: "BULL Release" @@ -29,18 +29,12 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: SonarCloud Scan - uses: sonarsource/sonarcloud-github-action@master + - name: Quality check env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - with: - args: > - -Dsonar.organization=borriello-fabio-bitbucket - -Dsonar.projectKey=BULL - -Dsonar.sources=**/*.java - -Dsonar.exclusions=**/AbstractTransformer.*,**/model/*,**/constant/*,**/error/*,**/annotation/* - -Dsonar.verbose=true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode - name: Site build env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From b4417318a3ba354e551d51192f64d8cdb0cde5b5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 10:52:26 +0200 Subject: [PATCH 1393/1786] adds the pages deploy step --- .github/workflows/github-release-actions.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 5902b2e5b..f75b3aff2 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -38,4 +38,11 @@ jobs: - name: Site build env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: mvn install site:site javadoc:aggregate -P site-release \ No newline at end of file + run: mvn install site:site javadoc:aggregate -P site-release + - name: Deploy GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: target/site + user_name: eg-oss-ci + user_email: oss@expediagroup.com \ No newline at end of file From 697d2a845bde6bd1e6cf311e67c474ec3e242e01 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 11:30:26 +0200 Subject: [PATCH 1394/1786] adds the pages deploy step --- .github/workflows/github-release-actions.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index f75b3aff2..0303c66b9 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -38,11 +38,11 @@ jobs: - name: Site build env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: mvn install site:site javadoc:aggregate -P site-release + run: mvn site:site javadoc:aggregate -P site-release - name: Deploy GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: target/site + publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com \ No newline at end of file From 5af2d60fef1592df4543d412e60e0260ac85b7ec Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 12:41:20 +0200 Subject: [PATCH 1395/1786] Adds the release step --- .github/workflows/github-release-actions.yml | 26 ++++++++++++- config/maven/mvn-settings.xml | 23 +++++++++++ config/travis/codesigning.asc.enc | Bin 9664 -> 0 bytes config/travis/deploy.sh | 15 ------- config/travis/mvn-settings.xml | 38 ------------------ pom.xml | 39 +++++++++++++++++++ 6 files changed, 86 insertions(+), 55 deletions(-) create mode 100644 config/maven/mvn-settings.xml delete mode 100644 config/travis/codesigning.asc.enc delete mode 100755 config/travis/deploy.sh delete mode 100755 config/travis/mvn-settings.xml diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 0303c66b9..e2727b29b 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -1,5 +1,10 @@ name: BULL Release -on: [push] +on: + push: + branches: + - "!*" + tags: + - "*" jobs: job: name: "BULL Release" @@ -29,6 +34,16 @@ jobs: with: java-version: '15' distribution: 'adopt' + server-id: ossrh + server-username: SONATYPE_USERNAME # env variable for username in deploy + server-password: SONATYPE_PASSWORD # env variable for token in deploy + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: GPG_PRIVATE_KEY_PASSPHRASE # env variable for GPG private key passphrase + - name: Project version set + env: + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - name: Quality check env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} @@ -45,4 +60,11 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./target/site user_name: eg-oss-ci - user_email: oss@expediagroup.com \ No newline at end of file + user_email: oss@expediagroup.com + - name: Publish package + run: mvn deploy --settings ./config/maven/mvn-settings.xml -P release -Dmaven.test.skip=true + env: + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} \ No newline at end of file diff --git a/config/maven/mvn-settings.xml b/config/maven/mvn-settings.xml new file mode 100644 index 000000000..ad2f77932 --- /dev/null +++ b/config/maven/mvn-settings.xml @@ -0,0 +1,23 @@ + + + + oss-sonatype + ${env.SONATYPE_USERNAME} + ${env.SONATYPE_PASSWORD} + + + + + + release + + true + + + gpg + ${env.GPG_PRIVATE_KEY} + ${env.GPG_PRIVATE_KEY_PASSPHRASE} + + + + diff --git a/config/travis/codesigning.asc.enc b/config/travis/codesigning.asc.enc deleted file mode 100644 index 6a564b3bc00efca12263b09e85fd3018fed4acb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9664 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 - - - ossrh - ${env.HCOM_OSSRH_USERNAME} - ${env.HCOM_OSSRH_PASSWORD} - - - sonatype-nexus-staging - ${env.HCOM_OSSRH_USERNAME} - ${env.HCOM_OSSRH_PASSWORD} - - - sonatype-nexus-snapshots - ${env.HCOM_OSSRH_USERNAME} - ${env.HCOM_OSSRH_PASSWORD} - - - - ${github_server_id} - ${github_oauth_token} - - - - - - release - - true - - - gpg - ${env.GPG_KEY_NAME} - ${env.GPG_PASSPHRASE} - - - - diff --git a/pom.xml b/pom.xml index 6bd85895e..218148bc8 100644 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,8 @@ 3.1.2 8.44 2.12.1 + 3.0.0-M4 + 1.6.8 false @@ -105,6 +107,19 @@ HEAD + + + oss-sonatype + Sonatype Nexus Snapshots Repository + https://oss.sonatype.org/content/repositories/snapshots + + + oss-sonatype + Sonatype Nexus Release Repository + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + @@ -308,6 +323,30 @@ + + + org.apache.maven.plugins + maven-release-plugin + ${maven.release.plugin.version} + + true + false + release + clean compile + deploy + + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${maven.nexus-staging.plugin.version} + true + + oss-sonatype + https://oss.sonatype.org/ + true + + org.apache.maven.plugins From 8b896f5e2c81570900a274147e4fd63ee3ddb036 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 12:42:54 +0200 Subject: [PATCH 1396/1786] [maven-release-plugin] prepare release 2.0.1.2 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 620929f22..c47e2bf95 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 402f677b5..6929fd016 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 81a35a788..48ada4e01 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 590fe2aa9..360d35f75 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0a74d1d39..f170b71ce 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2d94162ac..7fb6a6000 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/pom.xml b/pom.xml index 218148bc8..b7c3574ff 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.2-SNAPSHOT + 2.0.1.2 pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.0.1.2 From af79377324f93b538ae0e3fbcf707e5afb15c010 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 12:43:02 +0200 Subject: [PATCH 1397/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c47e2bf95..620929f22 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 6929fd016..402f677b5 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 48ada4e01..81a35a788 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 360d35f75..590fe2aa9 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f170b71ce..0a74d1d39 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 7fb6a6000..2d94162ac 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index b7c3574ff..218148bc8 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.1.2 + 2.0.2-SNAPSHOT pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.0.1.2 + HEAD From f4d13c1b68e491af7d59412c3458e2bf99432703 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 12:44:46 +0200 Subject: [PATCH 1398/1786] yaml indentation fix --- .github/workflows/github-release-actions.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index e2727b29b..18e4aeb49 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -61,10 +61,10 @@ jobs: publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com - - name: Publish package - run: mvn deploy --settings ./config/maven/mvn-settings.xml -P release -Dmaven.test.skip=true - env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} \ No newline at end of file + - name: Publish package + run: mvn deploy --settings ./config/maven/mvn-settings.xml -P release -Dmaven.test.skip=true + env: + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} \ No newline at end of file From 947e8759d6aa9b5c150652bf0b89c9999743b811 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 12:46:41 +0200 Subject: [PATCH 1399/1786] [maven-release-plugin] prepare release 2.0.1.2 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 620929f22..c47e2bf95 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 402f677b5..6929fd016 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 81a35a788..48ada4e01 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 590fe2aa9..360d35f75 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0a74d1d39..f170b71ce 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2d94162ac..7fb6a6000 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/pom.xml b/pom.xml index 218148bc8..b7c3574ff 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.2-SNAPSHOT + 2.0.1.2 pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.0.1.2 From cfb3180f19ea2ea30a22d23303a853827b707c99 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 12:46:49 +0200 Subject: [PATCH 1400/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c47e2bf95..620929f22 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 6929fd016..402f677b5 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 48ada4e01..81a35a788 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 360d35f75..590fe2aa9 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f170b71ce..0a74d1d39 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 7fb6a6000..2d94162ac 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index b7c3574ff..218148bc8 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.1.2 + 2.0.2-SNAPSHOT pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.0.1.2 + HEAD From 1012932de6e632c292688643c364e1a551969fdc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 12:53:25 +0200 Subject: [PATCH 1401/1786] adds the gpg key name as param --- .github/workflows/github-release-actions.yml | 28 ++------------------ config/maven/mvn-settings.xml | 14 ---------- 2 files changed, 2 insertions(+), 40 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 18e4aeb49..dc3935c27 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -37,34 +37,10 @@ jobs: server-id: ossrh server-username: SONATYPE_USERNAME # env variable for username in deploy server-password: SONATYPE_PASSWORD # env variable for token in deploy - gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import - gpg-passphrase: GPG_PRIVATE_KEY_PASSPHRASE # env variable for GPG private key passphrase - - name: Project version set - env: - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} - run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - name: Quality check - env: - SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode - - name: Site build - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: mvn site:site javadoc:aggregate -P site-release - - name: Deploy GitHub Pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./target/site - user_name: eg-oss-ci - user_email: oss@expediagroup.com - name: Publish package - run: mvn deploy --settings ./config/maven/mvn-settings.xml -P release -Dmaven.test.skip=true env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} \ No newline at end of file + GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} + run: mvn deploy -Dgpg.keyname=$GPG_PRIVATE_KEY -Dgpg.passphrase=$GPG_PRIVATE_KEY_PASSPHRASE --settings ./config/maven/mvn-settings.xml -P release -Dmaven.test.skip=true \ No newline at end of file diff --git a/config/maven/mvn-settings.xml b/config/maven/mvn-settings.xml index ad2f77932..638ddc9a2 100644 --- a/config/maven/mvn-settings.xml +++ b/config/maven/mvn-settings.xml @@ -6,18 +6,4 @@ ${env.SONATYPE_PASSWORD} - - - - release - - true - - - gpg - ${env.GPG_PRIVATE_KEY} - ${env.GPG_PRIVATE_KEY_PASSPHRASE} - - - From 1393f2d977ac635b65abd33ffc516170856beb1e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 12:56:34 +0200 Subject: [PATCH 1402/1786] adds the gpg key name as param --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index dc3935c27..1ef4731bc 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -43,4 +43,4 @@ jobs: SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} - run: mvn deploy -Dgpg.keyname=$GPG_PRIVATE_KEY -Dgpg.passphrase=$GPG_PRIVATE_KEY_PASSPHRASE --settings ./config/maven/mvn-settings.xml -P release -Dmaven.test.skip=true \ No newline at end of file + run: mvn deploy -Dgpg.keyname=${GPG_PRIVATE_KEY} -Dgpg.passphrase=${GPG_PRIVATE_KEY_PASSPHRASE} --settings ./config/maven/mvn-settings.xml -P release -Dmaven.test.skip=true \ No newline at end of file From 28b2f64bb18a94c08abaa307d699363092d2b474 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 14:12:59 +0200 Subject: [PATCH 1403/1786] adds the gpg key name as param --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 1ef4731bc..8208080c0 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -43,4 +43,4 @@ jobs: SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} - run: mvn deploy -Dgpg.keyname=${GPG_PRIVATE_KEY} -Dgpg.passphrase=${GPG_PRIVATE_KEY_PASSPHRASE} --settings ./config/maven/mvn-settings.xml -P release -Dmaven.test.skip=true \ No newline at end of file + run: mvn deploy -Dgpg.keyname=${GPG_PRIVATE_KEY} -Dgpg.passphrase=${GPG_PRIVATE_KEY_PASSPHRASE} \ No newline at end of file From e4a4faacb701a12d8a2e8fc1ba8b5dcab5691294 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 14:41:05 +0200 Subject: [PATCH 1404/1786] adds the gpg key name as param --- .github/workflows/github-release-actions.yml | 28 +++++++++----------- config/maven/mvn-settings.xml | 9 ------- pom.xml | 6 +++++ 3 files changed, 19 insertions(+), 24 deletions(-) delete mode 100644 config/maven/mvn-settings.xml diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 8208080c0..ebe238cfb 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -11,18 +11,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Cache maven dependencies - uses: actions/cache@v2 - env: - cache-name: cache-maven-dependencies + - name: Cache Maven repository + uses: actions/cache@v2.1.6 with: - # mvn cache files are stored in `~/.m2` path: ~/.m2 - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 - name: Extract build information id: build_info run: | @@ -34,13 +28,17 @@ jobs: with: java-version: '15' distribution: 'adopt' - server-id: ossrh + server-id: oss-sonatype server-username: SONATYPE_USERNAME # env variable for username in deploy server-password: SONATYPE_PASSWORD # env variable for token in deploy - - name: Publish package + # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase + settings-path: ${{ github.workspace }} + - name: Release artifacts + run: | + mvn deploy -s $GITHUB_WORKSPACE/settings.xml --settings /home/runner/.m2/settings.xml -B -P release -Dmaven.test.skip=true env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} - run: mvn deploy -Dgpg.keyname=${GPG_PRIVATE_KEY} -Dgpg.passphrase=${GPG_PRIVATE_KEY_PASSPHRASE} \ No newline at end of file + GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} \ No newline at end of file diff --git a/config/maven/mvn-settings.xml b/config/maven/mvn-settings.xml deleted file mode 100644 index 638ddc9a2..000000000 --- a/config/maven/mvn-settings.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - oss-sonatype - ${env.SONATYPE_USERNAME} - ${env.SONATYPE_PASSWORD} - - - diff --git a/pom.xml b/pom.xml index 218148bc8..b62dd6609 100644 --- a/pom.xml +++ b/pom.xml @@ -320,6 +320,12 @@ sign + + + --pinentry-mode + loopback + + From c24214aaa3d70dad9612133aad987256b86e9cf1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 14:47:34 +0200 Subject: [PATCH 1405/1786] adds the test execution --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index ebe238cfb..8b904b38b 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -37,7 +37,7 @@ jobs: settings-path: ${{ github.workspace }} - name: Release artifacts run: | - mvn deploy -s $GITHUB_WORKSPACE/settings.xml --settings /home/runner/.m2/settings.xml -B -P release -Dmaven.test.skip=true + mvn deploy -s $GITHUB_WORKSPACE/settings.xml --settings /home/runner/.m2/settings.xml -B -P release env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} From c9c09ff237a6d491fa23efd5966d9111855e9fb0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 14:57:44 +0200 Subject: [PATCH 1406/1786] adds the settings print --- .github/workflows/github-release-actions.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 8b904b38b..66fa2603f 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -37,6 +37,10 @@ jobs: settings-path: ${{ github.workspace }} - name: Release artifacts run: | + echo "/home/runner/.m2/settings.xml content" + cat /home/runner/.m2/settings.xml + echo "~/.m2/settings.xml content" + cat ~/.m2/settings.xml mvn deploy -s $GITHUB_WORKSPACE/settings.xml --settings /home/runner/.m2/settings.xml -B -P release env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} From 2ccd51500b36c0ef248ad488f565b9dc4a6db16f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 14:59:50 +0200 Subject: [PATCH 1407/1786] adds the settings print --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 66fa2603f..e1be8fe3a 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -38,7 +38,7 @@ jobs: - name: Release artifacts run: | echo "/home/runner/.m2/settings.xml content" - cat /home/runner/.m2/settings.xml + cat $GITHUB_WORKSPACE/settings.xml echo "~/.m2/settings.xml content" cat ~/.m2/settings.xml mvn deploy -s $GITHUB_WORKSPACE/settings.xml --settings /home/runner/.m2/settings.xml -B -P release From 177e9c25ad02d12761945a8bec58fe01cd9362e7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 15:07:04 +0200 Subject: [PATCH 1408/1786] adding all the steps to the deploy --- .github/workflows/github-release-actions.yml | 61 ++++++++++++++------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index e1be8fe3a..5cc4091dc 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -23,26 +23,49 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - - name: Set up JDK 15 - uses: actions/setup-java@v2 - with: - java-version: '15' - distribution: 'adopt' - server-id: oss-sonatype - server-username: SONATYPE_USERNAME # env variable for username in deploy - server-password: SONATYPE_PASSWORD # env variable for token in deploy - # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin - gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import - gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase - settings-path: ${{ github.workspace }} + - name: Set up JDK 15 + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' + server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml + server-username: SONATYPE_USERNAME # env variable for username in deploy + server-password: SONATYPE_PASSWORD # env variable for token in deploy + # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase + settings-path: ${{ github.workspace }} + - name: Quality check + env: + SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode + - name: Site build + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn site:site javadoc:aggregate -P site-release + - name: Deploy GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./target/site + user_name: eg-oss-ci + user_email: oss@expediagroup.com - name: Release artifacts - run: | - echo "/home/runner/.m2/settings.xml content" - cat $GITHUB_WORKSPACE/settings.xml - echo "~/.m2/settings.xml content" - cat ~/.m2/settings.xml - mvn deploy -s $GITHUB_WORKSPACE/settings.xml --settings /home/runner/.m2/settings.xml -B -P release env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} \ No newline at end of file + GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + echo "GITHUB_WORKSPACE/settings.xml content" + cat $GITHUB_WORKSPACE/settings.xml + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true From 87b607d204172801a3a23734618b13832730d53d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 15:08:59 +0200 Subject: [PATCH 1409/1786] [maven-release-plugin] prepare release 2.0.1.2 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 620929f22..c47e2bf95 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 402f677b5..6929fd016 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 81a35a788..48ada4e01 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 590fe2aa9..360d35f75 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0a74d1d39..f170b71ce 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2d94162ac..7fb6a6000 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/pom.xml b/pom.xml index b62dd6609..954a8e6b7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.2-SNAPSHOT + 2.0.1.2 pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.0.1.2 From ed5a92805fcea3fe46afa999f7f8c50395cd29ff Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 15:09:06 +0200 Subject: [PATCH 1410/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c47e2bf95..620929f22 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 6929fd016..402f677b5 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 48ada4e01..81a35a788 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 360d35f75..590fe2aa9 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f170b71ce..0a74d1d39 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 7fb6a6000..2d94162ac 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 954a8e6b7..b62dd6609 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.1.2 + 2.0.2-SNAPSHOT pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.0.1.2 + HEAD From ccfcc6d165529efa60b908d8ebf473f8b7f396f0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 15:11:51 +0200 Subject: [PATCH 1411/1786] adding all the steps to the deploy --- .github/workflows/github-release-actions.yml | 84 ++++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 5cc4091dc..29411cd18 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -23,49 +23,49 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - - name: Set up JDK 15 - uses: actions/setup-java@v2 - with: - java-version: '15' - distribution: 'adopt' - server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: SONATYPE_USERNAME # env variable for username in deploy - server-password: SONATYPE_PASSWORD # env variable for token in deploy - # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin - gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import - gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase - settings-path: ${{ github.workspace }} - - name: Quality check - env: - SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} - run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode - - name: Site build - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} - run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn site:site javadoc:aggregate -P site-release - - name: Deploy GitHub Pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./target/site - user_name: eg-oss-ci - user_email: oss@expediagroup.com - - name: Release artifacts + - name: Set up JDK 15 + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' + server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml + server-username: SONATYPE_USERNAME # env variable for username in deploy + server-password: SONATYPE_PASSWORD # env variable for token in deploy + # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase + settings-path: ${{ github.workspace }} + - name: Quality check + env: + SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode + - name: Site build env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - echo "GITHUB_WORKSPACE/settings.xml content" - cat $GITHUB_WORKSPACE/settings.xml mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true + mvn site:site javadoc:aggregate -P site-release + - name: Deploy GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./target/site + user_name: eg-oss-ci + user_email: oss@expediagroup.com + - name: Release artifacts + env: + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + echo "GITHUB_WORKSPACE/settings.xml content" + cat $GITHUB_WORKSPACE/settings.xml + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file From d6f1f073ab822815281b09d7897254b3025a7f31 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 15:37:14 +0200 Subject: [PATCH 1412/1786] [maven-release-plugin] prepare release 2.0.1.2 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 620929f22..c47e2bf95 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 402f677b5..6929fd016 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 81a35a788..48ada4e01 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 590fe2aa9..360d35f75 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0a74d1d39..f170b71ce 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2d94162ac..7fb6a6000 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/pom.xml b/pom.xml index b62dd6609..954a8e6b7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.2-SNAPSHOT + 2.0.1.2 pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.0.1.2 From 7ee04ff4412fecb4dac0078dad6baeb30e823d0a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 15:37:25 +0200 Subject: [PATCH 1413/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c47e2bf95..620929f22 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 6929fd016..402f677b5 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 48ada4e01..81a35a788 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 360d35f75..590fe2aa9 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f170b71ce..0a74d1d39 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 7fb6a6000..2d94162ac 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 954a8e6b7..b62dd6609 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.1.2 + 2.0.2-SNAPSHOT pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.0.1.2 + HEAD From ee337824df63104088883d02f1bbbc7fb880044f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 15:38:43 +0200 Subject: [PATCH 1414/1786] indentation fix --- .github/workflows/github-release-actions.yml | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 29411cd18..d567e5f69 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -58,14 +58,14 @@ jobs: publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com - - name: Release artifacts - env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} - run: | - echo "GITHUB_WORKSPACE/settings.xml content" - cat $GITHUB_WORKSPACE/settings.xml - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file + - name: Release artifacts + env: + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + echo "GITHUB_WORKSPACE/settings.xml content" + cat $GITHUB_WORKSPACE/settings.xml + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file From 9262542ca669182217efb1c8b2bb9bd8d79c306c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 15:39:53 +0200 Subject: [PATCH 1415/1786] [maven-release-plugin] prepare release 2.0.1.2 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 620929f22..c47e2bf95 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 402f677b5..6929fd016 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 81a35a788..48ada4e01 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 590fe2aa9..360d35f75 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0a74d1d39..f170b71ce 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2d94162ac..7fb6a6000 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/pom.xml b/pom.xml index b62dd6609..954a8e6b7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.2-SNAPSHOT + 2.0.1.2 pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.0.1.2 From 85932728df2f1b3693017bae92496eb3479c791b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 15:40:01 +0200 Subject: [PATCH 1416/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c47e2bf95..620929f22 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 6929fd016..402f677b5 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 48ada4e01..81a35a788 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 360d35f75..590fe2aa9 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f170b71ce..0a74d1d39 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 7fb6a6000..2d94162ac 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 954a8e6b7..b62dd6609 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.1.2 + 2.0.2-SNAPSHOT pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.0.1.2 + HEAD From 47c95bdd93785c0184838980ec1d36f60925f76f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 16:05:05 +0200 Subject: [PATCH 1417/1786] indentation fix --- .github/workflows/github-default-actions.yml | 15 +++++++++++++-- .github/workflows/github-release-actions.yml | 18 ++++++++---------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 65e5a1f1c..23232266d 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -12,7 +12,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up JDK 15 + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: "Set up JDK 15" uses: actions/setup-java@v2 with: java-version: '15' @@ -20,4 +26,9 @@ jobs: - name: Build and Test env: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - run: mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + run: | + echo "Release version: ${SONATYPE_USERNAME}" + echo "Release version 2: ${SONATYPE_PASSWORD}" + mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index d567e5f69..d3b1fe783 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Cache Maven repository + - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: path: ~/.m2 @@ -23,7 +23,7 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - - name: Set up JDK 15 + - name: "Set up JDK 15" uses: actions/setup-java@v2 with: java-version: '15' @@ -35,7 +35,7 @@ jobs: gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase settings-path: ${{ github.workspace }} - - name: Quality check + - name: "Quality check" env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} @@ -43,29 +43,27 @@ jobs: TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode - - name: Site build + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - name: "Site build" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn site:site javadoc:aggregate -P site-release - - name: Deploy GitHub Pages + mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - name: "Deploy GitHub Pages" uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com - - name: Release artifacts + - name: "Release artifacts" env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - echo "GITHUB_WORKSPACE/settings.xml content" - cat $GITHUB_WORKSPACE/settings.xml mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file From c0af45e0a18f6b1d0e966e8153f10ca21724ac46 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 16:11:29 +0200 Subject: [PATCH 1418/1786] indentation fix --- .github/workflows/github-default-actions.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 23232266d..665ac5ab8 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -26,9 +26,5 @@ jobs: - name: Build and Test env: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} run: | - echo "Release version: ${SONATYPE_USERNAME}" - echo "Release version 2: ${SONATYPE_PASSWORD}" mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode From 88a71d1d302744cf55022ef3d956fb46a88ff5a2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 16:49:22 +0200 Subject: [PATCH 1419/1786] specifies the GitHub action workflow for the jdk 11 build --- .github/workflows/github-default-actions.yml | 6 +- .../github-default-jdk11-actions.yml | 30 +++++++++ .../github-jdk11-release-actions.yml | 62 +++++++++++++++++++ .github/workflows/github-release-actions.yml | 10 +-- 4 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/github-default-jdk11-actions.yml create mode 100644 .github/workflows/github-jdk11-release-actions.yml diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 665ac5ab8..991204aef 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -1,9 +1,9 @@ name: Build and Test on: push: - branches: - - "*" - - "*/*" + branches-ignore: + - "*-jdk11" + - "*/*-jdk11" tags-ignore: - "*" jobs: diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml new file mode 100644 index 000000000..2c63a8f56 --- /dev/null +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -0,0 +1,30 @@ +name: Build and Test JDK 11 +on: + push: + branches: + - "*-jdk11" + - "*/*-jdk11" + tags-ignore: + - "*" +jobs: + job: + name: "Build and Test" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: "Set up JDK 11" + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + - name: Build and Test + env: + COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + run: | + mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml new file mode 100644 index 000000000..0b3416fe0 --- /dev/null +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -0,0 +1,62 @@ +name: BULL JDK 11 Release +on: + push: + branches: + - "!*" + tags: + - "*-jdk11" +jobs: + job: + name: "BULL Release" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: Extract build information + id: build_info + run: | + echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} + echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} + echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} + - name: "Set up JDK 11" + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml + server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy + server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy + # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase + settings-path: ${{ github.workspace }} + - name: "Quality check" + env: + SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - name: "Site build" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + - name: "Release artifacts" + env: + SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} + GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index d3b1fe783..705d31b04 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -5,6 +5,8 @@ on: - "!*" tags: - "*" + tags-ignore: + - "*-jdk11" jobs: job: name: "BULL Release" @@ -29,8 +31,8 @@ jobs: java-version: '15' distribution: 'adopt' server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: SONATYPE_USERNAME # env variable for username in deploy - server-password: SONATYPE_PASSWORD # env variable for token in deploy + server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy + server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase @@ -60,8 +62,8 @@ jobs: user_email: oss@expediagroup.com - name: "Release artifacts" env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | From f19abf0db1172a439f190b5706c99ae6992d4cf9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 16:50:41 +0200 Subject: [PATCH 1420/1786] specifies the GitHub action workflow for the jdk 11 build --- .github/workflows/github-release-actions.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 705d31b04..681765dce 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -3,8 +3,6 @@ on: push: branches: - "!*" - tags: - - "*" tags-ignore: - "*-jdk11" jobs: From 6d51c893f482c81ebc7bfd2231bf74243d0664df Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 16:52:49 +0200 Subject: [PATCH 1421/1786] [maven-release-plugin] prepare release 2.0.1.2 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 620929f22..c47e2bf95 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 402f677b5..6929fd016 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 81a35a788..48ada4e01 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 590fe2aa9..360d35f75 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0a74d1d39..f170b71ce 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2d94162ac..7fb6a6000 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/pom.xml b/pom.xml index b62dd6609..954a8e6b7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.2-SNAPSHOT + 2.0.1.2 pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.0.1.2 From c157ce24003b97397bbc844faa2b23dac2bbc6f4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 16:52:57 +0200 Subject: [PATCH 1422/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c47e2bf95..620929f22 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 6929fd016..402f677b5 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 48ada4e01..81a35a788 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 360d35f75..590fe2aa9 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f170b71ce..0a74d1d39 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 7fb6a6000..2d94162ac 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 954a8e6b7..b62dd6609 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.1.2 + 2.0.2-SNAPSHOT pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.0.1.2 + HEAD From cbc6c49bfc960f27e3109f13c7a72b28fcc62516 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:08:54 +0200 Subject: [PATCH 1423/1786] specifies the GitHub action workflow for the jdk 11 build --- .github/workflows/github-release-actions.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 681765dce..4bf8b13d2 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -29,8 +29,8 @@ jobs: java-version: '15' distribution: 'adopt' server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy - server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy + server-username: BULL_SONATYPE_USERNAME # env variable for username in deploy + server-password: BULL_SONATYPE_PASSWORD # env variable for token in deploy # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase @@ -60,8 +60,8 @@ jobs: user_email: oss@expediagroup.com - name: "Release artifacts" env: - SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.BULL_SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.BULL_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | From 1470e5eb84e907b3fa763de08dbaef2578aee328 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:10:38 +0200 Subject: [PATCH 1424/1786] [maven-release-plugin] prepare release 2.0.1.2 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 620929f22..c47e2bf95 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 402f677b5..6929fd016 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 81a35a788..48ada4e01 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 590fe2aa9..360d35f75 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0a74d1d39..f170b71ce 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2d94162ac..7fb6a6000 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.2-SNAPSHOT + 2.0.1.2 diff --git a/pom.xml b/pom.xml index b62dd6609..954a8e6b7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.2-SNAPSHOT + 2.0.1.2 pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.0.1.2 From e7a710faaab2fcbbf3c1bcdde5ca1d1d34a21483 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:10:46 +0200 Subject: [PATCH 1425/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index c47e2bf95..620929f22 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 6929fd016..402f677b5 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 48ada4e01..81a35a788 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 360d35f75..590fe2aa9 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.hotels.beans bean-utils-library-parent - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index f170b71ce..0a74d1d39 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 7fb6a6000..2d94162ac 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.hotels.beans - 2.0.1.2 + 2.0.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 954a8e6b7..b62dd6609 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.hotels.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.1.2 + 2.0.2-SNAPSHOT pom 2019 @@ -104,7 +104,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.0.1.2 + HEAD From fffe8d6bc9967871aa8e697ef03f0bbfe8e32485 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:17:01 +0200 Subject: [PATCH 1426/1786] disabling sonatype plugins --- .github/workflows/github-release-actions.yml | 10 ++--- pom.xml | 46 ++++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 4bf8b13d2..fad32779f 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -42,15 +42,15 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn versions:set -D newVersion=${TAG_NAME} + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - name: "Site build" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn versions:set -D newVersion=${TAG_NAME} + mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - name: "Deploy GitHub Pages" uses: peaceiris/actions-gh-pages@v3 with: @@ -65,5 +65,5 @@ jobs: GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn versions:set -D newVersion=${TAG_NAME} mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index b62dd6609..66437481b 100644 --- a/pom.xml +++ b/pom.xml @@ -330,29 +330,29 @@ - - org.apache.maven.plugins - maven-release-plugin - ${maven.release.plugin.version} - - true - false - release - clean compile - deploy - - - - org.sonatype.plugins - nexus-staging-maven-plugin - ${maven.nexus-staging.plugin.version} - true - - oss-sonatype - https://oss.sonatype.org/ - true - - + + + + + + + + + + + + + + + + + + + + + + + org.apache.maven.plugins From 9d17012ff8ff860086dbe6b587d258943257f6bb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:24:41 +0200 Subject: [PATCH 1427/1786] disabling sonatype plugins --- .github/workflows/github-release-actions.yml | 9 ++++---- pom.xml | 22 ++++++++++---------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index fad32779f..2a2991e5c 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -29,8 +29,8 @@ jobs: java-version: '15' distribution: 'adopt' server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: BULL_SONATYPE_USERNAME # env variable for username in deploy - server-password: BULL_SONATYPE_PASSWORD # env variable for token in deploy + server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy + server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase @@ -60,10 +60,11 @@ jobs: user_email: oss@expediagroup.com - name: "Release artifacts" env: - SONATYPE_USERNAME: ${{ secrets.BULL_SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.BULL_SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | + cat $GITHUB_WORKSPACE/settings.xml mvn versions:set -D newVersion=${TAG_NAME} mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index 66437481b..ce9a36fb0 100644 --- a/pom.xml +++ b/pom.xml @@ -342,17 +342,17 @@ - - - - - - - - - - - + + org.sonatype.plugins + nexus-staging-maven-plugin + ${maven.nexus-staging.plugin.version} + true + + oss-sonatype + https://oss.sonatype.org/ + true + + org.apache.maven.plugins From 5e4944e717f269074056b2263690a580709c29c2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:30:10 +0200 Subject: [PATCH 1428/1786] using a different env name --- .github/workflows/github-release-actions.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 2a2991e5c..642a46dda 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -60,8 +60,8 @@ jobs: user_email: oss@expediagroup.com - name: "Release artifacts" env: - SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} + HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} + HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | From 569ebb51945d28bb3fa9135fe959a668363e49da Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:37:44 +0200 Subject: [PATCH 1429/1786] testing with the default env variables --- .github/workflows/github-release-actions.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 642a46dda..30fb52278 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -29,8 +29,8 @@ jobs: java-version: '15' distribution: 'adopt' server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy - server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy + server-username: SONATYPE_USERNAME # env variable for username in deploy + server-password: SONATYPE_PASSWORD # env variable for token in deploy # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase @@ -60,8 +60,8 @@ jobs: user_email: oss@expediagroup.com - name: "Release artifacts" env: - HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} - HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} + HCOM_SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + HCOM_SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | From 182d1e19a424bfb86dc1c5144be85e659668ddce Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:43:15 +0200 Subject: [PATCH 1430/1786] testing with the default env variables --- .github/workflows/github-release-actions.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 30fb52278..4c565226c 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -29,8 +29,8 @@ jobs: java-version: '15' distribution: 'adopt' server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: SONATYPE_USERNAME # env variable for username in deploy - server-password: SONATYPE_PASSWORD # env variable for token in deploy + server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy + server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase @@ -65,6 +65,5 @@ jobs: GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - cat $GITHUB_WORKSPACE/settings.xml mvn versions:set -D newVersion=${TAG_NAME} mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file From 4ed5cae370d9c448fb82c2f5c0a755f332dda5a3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:49:30 +0200 Subject: [PATCH 1431/1786] testing with the default env variables --- .github/workflows/github-jdk11-release-actions.yml | 14 +++++++------- .github/workflows/github-release-actions.yml | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 0b3416fe0..cddf34033 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -42,21 +42,21 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn versions:set -D newVersion=${TAG_NAME} + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - name: "Site build" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn versions:set -D newVersion=${TAG_NAME} + mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - name: "Release artifacts" env: - SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} + HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} + HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_USERNAME }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + mvn versions:set -D newVersion=${TAG_NAME} mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 4c565226c..a153e743b 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -60,8 +60,8 @@ jobs: user_email: oss@expediagroup.com - name: "Release artifacts" env: - HCOM_SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - HCOM_SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} + HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_USERNAME }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | From c30518470f505dc121f8c1616920e345d7f89cae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 17:56:19 +0200 Subject: [PATCH 1432/1786] testing with the default env variables --- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index cddf34033..6ff3cde19 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -54,7 +54,7 @@ jobs: - name: "Release artifacts" env: HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} - HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_USERNAME }} + HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index a153e743b..28bb78519 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -61,7 +61,7 @@ jobs: - name: "Release artifacts" env: HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} - HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_USERNAME }} + HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | From 04701da8c15ff8044133b644f4e6c251e192ffc3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 18:01:12 +0200 Subject: [PATCH 1433/1786] minor: badge update --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 93b5d862b..3cf4eca3e 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,13 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central&color=blue)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg?color=blue)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) -[![Build Status](https://travis-ci.com/ExpediaGroup/bull.svg?branch=master)](https://travis-ci.com/ExpediaGroup/bull) +[![Build Status](https://github.com/ExpediaGroup/bull/actions/workflows/github-actions.yml/badge.svg)](https://github.com/ExpediaGroup/bull/actions/workflows/github-actions.yml/badge.svg) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://opensource.expediagroup.com/bull/) [![Coverage Status](https://coveralls.io/repos/github/ExpediaGroup/bull/badge.svg?branch=master)](https://coveralls.io/github/ExpediaGroup/bull?branch=master) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) ![GitHub license](https://img.shields.io/github/license/ExpediaGroup/bull.svg) -[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=ExpediaGroup/bull)](https://dependabot.com) All BULL modules are available on Maven Central: From 6a456d07ed1a10f8005497819f7af4d1b69000fa Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 18:01:55 +0200 Subject: [PATCH 1434/1786] removes the commented code --- pom.xml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pom.xml b/pom.xml index ce9a36fb0..a164b15c8 100644 --- a/pom.xml +++ b/pom.xml @@ -329,19 +329,6 @@ - - - - - - - - - - - - - org.sonatype.plugins nexus-staging-maven-plugin From b9fec0d75121cdf101c557c2dd73752af65025d1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 18:05:12 +0200 Subject: [PATCH 1435/1786] removes the travis config file as not needed anymore --- .travis.yml | 83 ----------------------------------------------------- 1 file changed, 83 deletions(-) delete mode 100755 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100755 index 0ccce8583..000000000 --- a/.travis.yml +++ /dev/null @@ -1,83 +0,0 @@ -language: java -cache: - directories: - - $HOME/.m2 -env: - global: - # HCOM OSS Sonatype jira info - - secure: W40tXg80XoNy8L3GujgF4PzuiWqY4q5o+XVqppj1atLS7dFa/KuSjJ6bBWF0ootVjmXpRofUF5/Tg2zwcwtOKm9wSjCdgmoGht2CFryieoNVuwJ7MFBLheMvpKp940vHpXDMxb5mc/lff1yM/XNLd5aUa5ITw8GE7qowc3Irc2tUTZKQem+o3mwnuj0dBsRUQt2eGIEkqDWn/pQ5SfjUWSQp3YUVv0iPjIvwV+lHSEB9Mod8Am/5TYuFxINgo6R3MX5K7rwaXjvErSUz6gAP2kqoA+EZDUotmdhFr8zVVpB8e33bPwxNlTYJ5fePKIkLz3TjEb1UVpav2/Ie/jpD0QbfCL/hukEPV/JKye+4fOIJeRZGwBXOQQsscyfcNf9utHittG4ZEzOXwYutbSf4qjoI5V48/hC8hs0OL3RJGE6e4v9tQwvIxY/IopqreACVrHIRK34fOoABQpFUPsmcGTuLrAGJqjDn9UiXJqb9Qlgav1Ly0KKH5YnKQoxyc5RvQDC8NvafSDgex0udGwTVGDNYgQeGVmrOy/C6iDIyEe5hn5gXwDFWFMxETjHcYka7gCngCbDiGIOMxiOeHbnO2dG7HbNME6p9nRovdD/n5cnp4sj3ttysyMNRt8NE2IkZRfJ+LQUqcavpkeVRvN5O/drNBtYnTOXC+lGCV0XGL2E= - - secure: cniGJvvR9/RcmRAp0F+iLvqQGH3zlvDYUb1GqZpX2ZKgqJ9syidk/Xy456HdR9WM9gTHZdQLNXYQFx9Dt41pa3Ft9nEi9LvmoLp/3rh/Siogx2X/madDxqHOXshCMYUg9ndSk8KKvjYSb+ztxT8j1qDW553Fax2YPWQiGRT5FXaEg1vl6znR362AhXaU1MgB8Wq+tDzTYJZugGj13u0S/vkNuTd30IQ5sW9YoQ4QwYPJIaG6ix1EUo0P3u96edakQjIAdciMLkggsfQkZr2MF5vAHjUI4+qW5wyAV2mzauc2MKhvKkJnF6WcNYOsXBOyDCAPJNo5YM4ODJM9ot7CcfKllecBaFUs4Uqh2U0lIe6opRtMdYPwV/GAAXwanSKgM1dNxgmPHnUWffWjaUJAbN94E/EH9JtGK2FAuxWqhbsPuMbpGK3XXuojU1fYj3oGGYFmSE3xWmhtSU89xiDrmrooGxxkaRt00eWtK+qCuiR8KGkN//i3+3x2F0ysVoOJL5WSSzNyfbtfp6laHTZv/LSAFgjSEmJF04L4m4Yhm/EDKaUXZjR/TAK2NZDTxlOxaOGVhwPA8Xj5YSwDMTd5k+cPntpYn/NbWtRr4fwk6VxI4XOOtksdiSk4Eiiaco2qEyd3X1tW/B9bPaAAFk8jHD35GNZAazgvNq7+kpMOg1s= - # GPG_KEY_NAME - - secure: l0BUFY0eCMvGEOLC8/7qR4UQMzUbo6aYNJxaqzqmTsp1gHR1f6t0uFV5eGkaNwlLsay8SNleqoj/kvu2gWWa6uQ7vPMSMmlg1uB2gzJhT1B1QYuCAkOJQ7cvoakU859yiED1+ZFym3aTs+DstuZa/eyNI67RWmmfgUyl5nfQqMrV6NF24lbU2KqX7mrr1VVXjEkNHcW8/Lo5AVwp21jKar7hjgqxJhMRMqpLVY1ToVkpUAWUwRc0aEWDhqf/4Zjx6I1ebpKbNzSUE0VEJOd9+87dGlm+9CcgwMZsLo+tSl5CvbX8zWRGWX3OLqKfYnJpVJRgMweZcxvm5PeICGs0IZqbenKn3Xh2JxVp6hiZ8/I6kMB2KSVxlrk/3I9McfG2xoibKpbEqwUeX95IqNnBBw4Nm1pSkandW6bJjFjGatRaaO1Am5m4+DG+Su31TleKLq3+wew3we/Qu7ksAvaJ2b3/CLZv6FO2aB79Uh0wOfzU7tCRdDkzDUvFjGvQzvfS1iTrlHjlRgPAhQd+De4EYgtkh6rHixDnf58Z0AG+J7/+ZcJhV0ivCIb3QYZJDt8RjDZDr7EtOw7QGXO9PyTo8tL8DEIVg14I3AENQtoxop3C8hzb/NFGJTIf/0CBPzsmPw4K0RsYUfjkjRYJLFAYkm7pVpp0QnwkVXnQlobYyoA= - # GPG_PASSPHRASE - - secure: D/JuBQf12qen8ld0rV6l5OkqHJidrLwCZBBNP6zM86vYfYVneiulTFhrTSdMrmcJaCGllatc7m/8h8DBZIIQ/ax/OKnBF+SXBd2YghZyo17NALPsmNOmF1oHL6oGbBBfZ3EOoJ/B3j4zHrxtbX53+lJPvLkmveA6jTupQq/3mldVEyKekyPaRofJ88ZYsIiT4S0Q3OSoVTZuOE6Tcq24v6HkWYYH2q99c45HyI4u+xgmxsRjFJMRi+37iqecqr6VxL7Cj6RjwsjpOi2x0m2hMxa6eOrc7VdYDzV37U8O+vv9RRm02r1P0K9HAviE2VO7loOwEYW1y3ZtApwRFBQFtd2QG054mkw/HL1zLXcG+tQgndx8Ui1nmPT4uh19DjGT0vUAJ+8zP0I757sHC13DqrqPSWGatd7P+lkVIuc5QNi0Y3D7XxgnD5XAPIGy/T91GH5WQjIUJd+F0xe7PnW2h0GAsR0MyeBV3Wueh+5mKyIV9p/79nYuaIKSNhEjPj0iPTS2JzYVnutJHQGyH1uvCKDI3JaxFdgKDNNCoZY9BiVhEkbmcJmKlcsGlqFRSn9LWOFW9+NQWdo1FfKCFNCHppNzt23p7JxFd3wjy+0Fp1kRjQ3VHCm4mpx/bRI++5tjvPtQHq7D4VjiteO6FuhqJBBgz93mI9pGp66o91RwFrk= -install: skip -jobs: - include: - ### Build - - stage: "Build" - name: "Build and Test" - jdk: openjdk15 - script: travis_retry mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=${COVERALLS_TOKEN} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode - ### JDK8 build - - stage: "JDK8 Build" - name: "JDK8 Build and Test" - jdk: openjdk8 - if: branch =~ ^.*-jdk8$ OR tag =~ ^.*-jdk8$ - script: - - travis_retry mvn clean install -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - stage: "Site Build and Quality check" - name: "Publishing site and performing a code quality check" - jdk: openjdk15 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ - script: skip - before_deploy: - - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - travis_retry mvn install sonar:sonar -Dsonar.projectKey=${sonar_project_key} -Dsonar.organization=${sonar_organization} -Dsonar.host.url=${sonar_host_url} -Dsonar.login=${sonar_token} -Dcheckstyle.skip=true site:site javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - deploy: - provider: pages - local-dir: target/site - skip-cleanup: true - github-token: ${github_oauth_token} - keep-history: true - on: - tags: true - ### JDK15 release - - stage: "Artifact Release" - name: "Releasing artifacts" - jdk: openjdk15 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^((?!-jdk8).)*$ - script: skip - before_deploy: - - openssl aes-256-cbc -K $encrypted_81c98acad902_key -iv $encrypted_81c98acad902_iv -in config/travis/codesigning.asc.enc -out config/travis/codesigning.asc -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install -DskipTests -Dmaven.test.skip=true javadoc:aggregate -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true - ### JDK8 release - - stage: "JDK8 Release" - name: "Releasing artifacts for JDK8" - jdk: openjdk8 - if: type NOT IN (pull_request) AND tag IS present AND tag =~ ^.*-jdk8$ - script: skip - before_deploy: - - openssl aes-256-cbc -K $encrypted_81c98acad902_key -iv $encrypted_81c98acad902_iv -in config/travis/codesigning.asc.enc -out config/travis/codesigning.asc -d - - mvn versions:set -D newVersion=${TRAVIS_TAG} -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - mvn install javadoc:aggregate -P site-release -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - deploy: - - provider: script - script: config/travis/deploy.sh - skip_cleanup: true - on: - tags: true -notifications: - slack: - rooms: - - bull-crew:hTuN6VsJod6aUOU6FWIFiQca - on_failure: change - on_success: change - on_pull_requests: true From 8d7593b9400b514d928df00f8fae251c0ad66fae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 18:13:58 +0200 Subject: [PATCH 1436/1786] updates the pull request template --- CHANGELOG-JDK11.md | 3 ++ PULL_REQUEST_TEMPLATE.md | 4 +-- RELEASE.md | 62 ++++++++++++++++++++-------------------- 3 files changed, 36 insertions(+), 33 deletions(-) create mode 100755 CHANGELOG-JDK11.md diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md new file mode 100755 index 000000000..6bad62429 --- /dev/null +++ b/CHANGELOG-JDK11.md @@ -0,0 +1,3 @@ +# BULL Change Log (`jdk 11` or above) + +All notable changes to this project will be documented in this file. \ No newline at end of file diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 2533dd05f..5cddfba25 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -29,7 +29,7 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] My changes have no bad impacts on performances - [ ] My changes have been tested through Unit Tests and the overall coverage has not decreased. Check the coverall report for your branch: [here](https://coveralls.io/github/ExpediaGroup/bull) - [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file -- [ ] Any implemented change has been added in the [CHANGELOG-JDK8.md](./CHANGELOG-JDK8.md) file -- [ ] My changes have been applied on a separate branch too with compatibility with Java 8. Follow this [instructions](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#3-prepare-the-jdk8-release) for help. +- [ ] Any implemented change has been added in the [CHANGELOG-JDK11.md](./CHANGELOG-JDK11.md) file +- [ ] My changes have been applied on a separate branch too with compatibility with Java 11. Follow this [instructions](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#3-prepare-the-jdk11-release) for help. - [ ] The maven version has been increased. diff --git a/RELEASE.md b/RELEASE.md index eaf16e2ca..f79735777 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -10,23 +10,23 @@ Make the following checks before performing a release: * Do all unit tests pass? * Do all examples work? * Does documentation build? - * Have the new features been applied on a separate branch with compatibility with `jdk8`? + * Have the new features been applied on a separate branch with compatibility with `jdk11`? #### 2. Update VERSION and CHANGELOG #### Increment the version number. -The application is released with the compatibility for both: `jdk11` and `jdk8`, the latest version number are: -in the [CHANGELOG.md](CHANGELOG.md) file for `jdk11` and [CHANGELOG-JDK8.md](CHANGELOG-JDK8.md) file for `jdk8`. +The application is released with the compatibility for both: `jdk15` and `jdk11`, the latest version number are: +in the [CHANGELOG.md](CHANGELOG.md) file for `jdk15` and [CHANGELOG-JDK11.md](CHANGELOG-JDK11.md) file for `jdk11`. The version number structure is: *major* **.** *minor* **.** *revision*. * *major* = significant incompatible change (e.g. partial or whole rewrite). * *minor* = some new functionality or changes that are mostly/wholly backward compatible. * *revision* = very minor changes, e.g. bugfixes. -For `jdk8` only, the version number is the same as the `jdk11` one, with the suffix: `-jdk8`. +For `jdk11` only, the version number is the same as the `jdk15` one, with the suffix: `-jdk11`. -e.g. if the new release version would be `X.Y.Z` then the `jdk8` correspondent one is: `X.Y.Z-jdk8` +e.g. if the new release version would be `X.Y.Z` then the `jdk11` correspondent one is: `X.Y.Z-jdk11` #### Update the change log @@ -40,30 +40,30 @@ Make the following check before performing a release: * Specify under the `### Changed` label everything that has been changed in the new version * Specify under the `### Removed` label everything that has been removed in the new version -the same changes must be reported in [CHANGELOG-JDK8.md](CHANGELOG-JDK8.md) +the same changes must be reported in [CHANGELOG-JDK11.md](CHANGELOG-JDK11.md) -#### 3. Prepare the jdk8 release +#### 3. Prepare the jdk11 release -All the changes implemented need to be reported to a `jdk8` compatible version. +All the changes implemented need to be reported to a `jdk11` compatible version. -The BULL code for the `jdk8` is slightly different so all the changes need to be reported on the other version starting +The BULL code for the `jdk11` is slightly different so all the changes need to be reported on the other version starting from it's latest release tag. -The first thing to do is to create a branch (that would have the same name as the `jdk11` one plus the suffix: `-jdk8`) -starting from the latest `jdk8` release tag: +The first thing to do is to create a branch (that would have the same name as the `jdk15` one plus the suffix: `-jdk11`) +starting from the latest `jdk11` release tag: ```shell script -$ git checkout -b [branch name]-jdk8 [latest jdk8 release tag] +$ git checkout -b [branch name]-jdk11 [latest jdk11 release tag] ``` -e.g. if the latest `jdk8` release tag is: `1.7.0-jdk8` and the new feature branch is: `feature/my-new-feature` +e.g. if the latest `jdk11` release tag is: `1.7.0-jdk11` and the new feature branch is: `feature/my-new-feature` the command to perform is: ```shell script -$ git checkout -b feature/my-new-feature-jdk8 1.7.0-jdk8 +$ git checkout -b feature/my-new-feature-jdk11 1.7.0-jdk11 ``` -**IMPORTANT:** In the new branch, apply only the changes introduced comparing the code with the `jdk11` branch. +**IMPORTANT:** In the new branch, apply only the changes introduced comparing the code with the `jdk15` branch. When completed, commit your code and verify that the [Travis build](https://travis-ci.org/ExpediaGroup/bull/builds) is green. ## Example of a release process sequence @@ -74,16 +74,16 @@ The following examples assume that your local repository is: * is all synced with GitHub * the Pull Request has been approved and merged on master -The guide explains how to do a release both the `jdk11` and `jdk8` compatible: +The guide explains how to do a release both the `jdk15` and `jdk11` compatible: -* [JDK8 Release](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#jdk8-release) * [JDK11 Release](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#jdk11-release) +* [JDK15 Release](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#jdk15-release) **IMPORTANT:** In case something goes wrong, do not leave ghost tags or tags not related to a successful release. -### JDK8 Release +### JDK11 Release -The following steps will do a release "`X.Y.Z-jdk8`" +The following steps will do a release "`X.Y.Z-jdk11`" ```shell script $ git status @@ -92,19 +92,19 @@ Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean ``` -#### 1. Create a branch from the latest JDK8 release tag +#### 1. Create a branch from the latest JDK11 release tag Assuming that: -* The latest release for `jdk8` was: `A.B.C-jdk8` +* The latest release for `jdk11` was: `A.B.C-jdk11` * your new feature branch is: `feature/my-new-feature` -* The new release version is: `X.Y.Z-jdk8` +* The new release version is: `X.Y.Z-jdk11` -the release branch would be: `release/my-new-feature-jdk8` +the release branch would be: `release/my-new-feature-jdk11` ```shell script -$ git checkout -b release/my-new-feature-jdk8 A.B.C-jdk8 -$ git push --set-upstream origin release/my-new-feature-jdk8 +$ git checkout -b release/my-new-feature-jdk11 A.B.C-jdk11 +$ git push --set-upstream origin release/my-new-feature-jdk11 ``` #### 2. Apply the changes to the new branch @@ -116,7 +116,7 @@ Apply all the changes you implemented to this branch. The maven version is now set with the latest released, but you need to change it with the new one you are going to release: ```shell script -$ mvn versions:set -D newVersion=X.Y.Z-jdk8 +$ mvn versions:set -D newVersion=X.Y.Z-jdk11 ``` Commit all the changes and verify that the [Travis build](https://travis-ci.org/ExpediaGroup/bull/builds) is green. @@ -126,7 +126,7 @@ Commit all the changes and verify that the [Travis build](https://travis-ci.org/ Once you will have created the tag, and pushed it to the remote repo, an automatic release will be performed by Travis. ```shell script -$ git tag -a X.Y.Z-jdk8 -m "my version X.Y.Z-jdk8" +$ git tag -a X.Y.Z-jdk11 -m "my version X.Y.Z-jdk11" $ git push origin --tags ``` @@ -135,8 +135,8 @@ $ git push origin --tags If the release went successfully, you can now delete the branch: ```shell script -$ git branch -D release/my-new-feature-jdk8 -$ git push --delete release/my-new-feature-jdk8 +$ git branch -D release/my-new-feature-jdk11 +$ git push --delete release/my-new-feature-jdk11 ``` ### JDK11 Release @@ -154,7 +154,7 @@ nothing to commit, working directory clean Assuming that: -* The latest release for `jdk11` was: `A.B.C` +* The latest release for `jdk15` was: `A.B.C` * your new feature branch is: `feature/my-new-feature` * The new release version is: `X.Y.Z` @@ -189,5 +189,5 @@ If the release went successfully, you can now delete the branch: ```shell script $ git branch -D release/my-new-feature -$ git push --delete release/my-new-feature-jdk8 +$ git push --delete release/my-new-feature-jdk11 ``` From a51c915102d11b9f56b75cca6a949b1d49c567b6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 18:19:43 +0200 Subject: [PATCH 1437/1786] removes the build step from code ql --- .github/workflows/codeql-analysis.yml | 30 ++++++++------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 55b2c3b7f..2f89802a7 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,13 +13,11 @@ name: "CodeQL" on: push: - branches: [ master ] + branches: + - "*" pull_request: - # The branches below must be a subset of the branches above - branches: [ master ] - schedule: - - cron: '45 1 * * 5' - + branches: + - "*" jobs: analyze: name: Analyze @@ -28,24 +26,18 @@ jobs: actions: read contents: read security-events: write - strategy: fail-fast: false matrix: language: [ 'java' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - steps: - - name: Setup Java - uses: actions/setup-java@v1 - with: - java-version: '15' - + - name: "Set up JDK 15" + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' - name: Checkout repository uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v1 @@ -58,9 +50,5 @@ jobs: # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl - - - run: | - ./mvnw clean verify - - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 From 38f39762bec20e002d23e570a6a9b62c156d7563 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 18:20:45 +0200 Subject: [PATCH 1438/1786] indentation fix --- .github/workflows/codeql-analysis.yml | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2f89802a7..0ec104938 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -36,19 +36,19 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: Checkout repository - uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + - name: Checkout repository + uses: actions/checkout@v2 + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 2d268f03efe0c2b9030cddea76b84c9486ef25dd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 18:22:43 +0200 Subject: [PATCH 1439/1786] re-adds the missing step --- .github/workflows/codeql-analysis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0ec104938..573179a36 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -47,8 +47,9 @@ jobs: # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main - # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl + - run: | + ./mvnw clean verify - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 From db96e0443135851de13dc91dc31eb4bc01ef7850 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 18:24:14 +0200 Subject: [PATCH 1440/1786] minor changes --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 573179a36..51990be8f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,7 +39,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL + - name: "Initialize CodeQL" uses: github/codeql-action/init@v1 with: languages: ${{ matrix.language }} @@ -51,5 +51,5 @@ jobs: # 📚 https://git.io/JvXDl - run: | ./mvnw clean verify - - name: Perform CodeQL Analysis + - name: "Perform CodeQL Analysis" uses: github/codeql-action/analyze@v1 From f18711463d2cad7947873d92f35015036573a68f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 18:31:29 +0200 Subject: [PATCH 1441/1786] minor: indentation fix --- .github/ISSUE_TEMPLATE/bug_report.md | 21 +++++----- .github/ISSUE_TEMPLATE/custom.md | 4 +- .github/ISSUE_TEMPLATE/feature_request.md | 4 +- .github/workflows/github-default-actions.yml | 42 +++++++++---------- .../github-default-jdk11-actions.yml | 42 +++++++++---------- 5 files changed, 55 insertions(+), 58 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e60cd75c1..3b0799021 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,5 @@ --- -name: Bug report -about: Create a report to help us improve -title: '' +name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '[Fabio Borriello](https://github.com/fborriello)' @@ -12,6 +10,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -24,15 +23,17 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhoneX] - - OS: [e.g. iOS12.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] + +- Device: [e.g. iPhoneX] +- OS: [e.g. iOS12.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md index 48d5f81fa..e350e3714 100644 --- a/.github/ISSUE_TEMPLATE/custom.md +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -1,7 +1,5 @@ --- -name: Custom issue template -about: Describe this issue template's purpose here. -title: '' +name: Custom issue template about: Describe this issue template's purpose here. title: '' labels: '' assignees: '' diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d6..5fe926b25 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,5 @@ --- -name: Feature request -about: Suggest an idea for this project -title: '' +name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 991204aef..2b4416f23 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -7,24 +7,24 @@ on: tags-ignore: - "*" jobs: - job: - name: "Build and Test" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - name: "Set up JDK 15" - uses: actions/setup-java@v2 - with: - java-version: '15' - distribution: 'adopt' - - name: Build and Test - env: - COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - run: | - mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + job: + name: "Build and Test" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: "Set up JDK 15" + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' + - name: Build and Test + env: + COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + run: | + mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 2c63a8f56..28eaa4ae3 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -7,24 +7,24 @@ on: tags-ignore: - "*" jobs: - job: - name: "Build and Test" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - name: "Set up JDK 11" - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build and Test - env: - COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - run: | - mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + job: + name: "Build and Test" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: "Set up JDK 11" + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + - name: Build and Test + env: + COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + run: | + mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode From 6f997707902332b0c5252e8bae786eb05741c0d0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 13 Jul 2021 20:04:09 +0200 Subject: [PATCH 1442/1786] minor: fixes the build badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3cf4eca3e..708df54cd 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central&color=blue)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg?color=blue)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) -[![Build Status](https://github.com/ExpediaGroup/bull/actions/workflows/github-actions.yml/badge.svg)](https://github.com/ExpediaGroup/bull/actions/workflows/github-actions.yml/badge.svg) +[![Build Status](https://github.com/ExpediaGroup/bull/actions/workflows/github-default-actions.yml/badge.svg?branch=master)](https://github.com/ExpediaGroup/bull/actions/workflows/github-default-actions.yml/badge.svg?branch=master) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://opensource.expediagroup.com/bull/) From 84c8d5bb7b6555987f1e0ad01caa6ed8309f2cd8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 07:15:57 +0200 Subject: [PATCH 1443/1786] testing the release with a single version set and skipping tests --- .github/workflows/github-release-actions.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 28bb78519..9f67057a3 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -35,22 +35,23 @@ jobs: gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase settings-path: ${{ github.workspace }} + - name: "Project version set" + env: + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} - name: "Quality check" env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - name: "Site build" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} - mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -DskipTests=true - name: "Deploy GitHub Pages" uses: peaceiris/actions-gh-pages@v3 with: @@ -63,7 +64,5 @@ jobs: HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file From 5a9eb6732d6a79f6f932488dd4665bbc965332c5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 07:36:33 +0200 Subject: [PATCH 1444/1786] testing the release with a single version set and skipping tests --- .github/workflows/github-jdk11-release-actions.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 6ff3cde19..72ba9e864 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -35,28 +35,27 @@ jobs: gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase settings-path: ${{ github.workspace }} + - name: "Project version set" + env: + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} - name: "Quality check" env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - name: "Site build" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - name: "Release artifacts" env: HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | - mvn versions:set -D newVersion=${TAG_NAME} mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file From 2cd5b27f22f5a508dc05cf3fe9489743fe67511b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 07:36:52 +0200 Subject: [PATCH 1445/1786] testing the release with a single version set and skipping tests --- .github/workflows/github-jdk11-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 72ba9e864..5962378d1 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -51,7 +51,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -DskipTests=true - name: "Release artifacts" env: HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} From d6057bcce1f7dc5fff6204bfbfe4b6b04bf9a182 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 07:41:04 +0200 Subject: [PATCH 1446/1786] prints the source branch name --- .github/workflows/github-default-actions.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 2b4416f23..0884c5cd3 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -18,13 +18,23 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 + - name: Extract build information + id: build_info + run: | + echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} + echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "Set up JDK 15" uses: actions/setup-java@v2 with: java-version: '15' distribution: 'adopt' - - name: Build and Test + - name: "Build and Test" env: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} run: | mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + - name: "Quality check" + env: + SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} + run: | + echo "Branch: $SOURCE_BRANCH" \ No newline at end of file From 42bb2f63ad6d4706de0d9931c18123620e4643b1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 08:10:14 +0200 Subject: [PATCH 1447/1786] adds the quality check on branches too --- .github/workflows/github-default-actions.yml | 7 +++++-- .github/workflows/github-default-jdk11-actions.yml | 14 +++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 0884c5cd3..e2fcef40f 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -1,4 +1,4 @@ -name: Build and Test +name: "Build, test and quality check" on: push: branches-ignore: @@ -35,6 +35,9 @@ jobs: mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode - name: "Quality check" env: + SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} run: | - echo "Branch: $SOURCE_BRANCH" \ No newline at end of file + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn \ No newline at end of file diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 28eaa4ae3..855644ea8 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -1,4 +1,4 @@ -name: Build and Test JDK 11 +name: "Build, test and quality check JDK 11" on: push: branches: @@ -8,7 +8,7 @@ on: - "*" jobs: job: - name: "Build and Test" + name: "Build, test and quality check" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -23,8 +23,16 @@ jobs: with: java-version: '11' distribution: 'adopt' - - name: Build and Test + - name: "Build and Test" env: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} run: | mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + - name: "Quality check" + env: + SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} + run: | + mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn \ No newline at end of file From 4da1c13c8f91ecf385890fbaafa7a719c1cfbb20 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 08:10:58 +0200 Subject: [PATCH 1448/1786] adds the quality check on branches too --- .github/workflows/github-default-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index e2fcef40f..38869cef1 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -8,7 +8,7 @@ on: - "*" jobs: job: - name: "Build and Test" + name: "Build, test and quality check" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From 421990e514224e518397bad790320c12d7754192 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 08:19:31 +0200 Subject: [PATCH 1449/1786] minor improvements --- .github/workflows/github-default-actions.yml | 4 ++-- .github/workflows/github-default-jdk11-actions.yml | 7 ++++++- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- README.md | 2 +- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 38869cef1..7b64f9db2 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -1,4 +1,4 @@ -name: "Build, test and quality check" +name: "Build" on: push: branches-ignore: @@ -18,7 +18,7 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - - name: Extract build information + - name: "Extract build information" id: build_info run: | echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 855644ea8..1e183f7cb 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -1,4 +1,4 @@ -name: "Build, test and quality check JDK 11" +name: "Build JDK 11" on: push: branches: @@ -18,6 +18,11 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 + - name: "Extract build information" + id: build_info + run: | + echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} + echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "Set up JDK 11" uses: actions/setup-java@v2 with: diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 5962378d1..884f8b424 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -17,7 +17,7 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - - name: Extract build information + - name: "Extract build information" id: build_info run: | echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 9f67057a3..941d75a68 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -17,7 +17,7 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - - name: Extract build information + - name: "Extract build information" id: build_info run: | echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} diff --git a/README.md b/README.md index 708df54cd..4036fd57a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central&color=blue)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) [![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg?color=blue)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) -[![Build Status](https://github.com/ExpediaGroup/bull/actions/workflows/github-default-actions.yml/badge.svg?branch=master)](https://github.com/ExpediaGroup/bull/actions/workflows/github-default-actions.yml/badge.svg?branch=master) +[![Build Status](https://github.com/ExpediaGroup/bull/actions/workflows/github-default-actions.yml/badge.svg?branch=master)](https://github.com/ExpediaGroup/bull/actions) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://opensource.expediagroup.com/bull/) From 58893235aaac92d020a4e27712758df12ac57c1b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 08:22:20 +0200 Subject: [PATCH 1450/1786] adds the jdk 11 version in the proper file --- CHANGELOG-JDK11.md | 280 ++++++++++++++++++++++++++++++++++++++++++++- CHANGELOG.md | 280 +-------------------------------------------- README.md | 8 +- 3 files changed, 286 insertions(+), 282 deletions(-) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index 6bad62429..8f6951aa8 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -1,3 +1,281 @@ # BULL Change Log (`jdk 11` or above) -All notable changes to this project will be documented in this file. \ No newline at end of file +All notable changes to this project will be documented in this file. + +### [1.7.7] 2021.06.23 +#### Changed +* Fixes an issue that was preventing the transformation of Object type fields + +### [1.7.6] 2021.01.11 +#### Added +* Provides new module `bull-bom` that includes all the project modules + +### [1.7.4] 2020.10.07 +#### Changed +* Provides new utilities methods + +### [1.7.3] 2020.06.09 +#### Changed +* Removes the deprecated method: `setDefaultValueSetEnabled` + +### [1.7.2] 2020.06.09 +#### Changed +* Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` +* Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). + +### [1.7.1] 2020.03.21 +#### Added +* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/ExpediaGroup/bull/issues/144)). +#### Changed +* Updated `hibernate-validator` version to `6.1.4.Final` (was `6.1.2.Final`). + +### [1.6.6] 2020.03.16 +#### Changed +* Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). +* Updated `commons-lang3` version to `3.10` (was `3.9`). + +### [1.6.5] 2020.01.21 +#### Changed +* Testing dependencies update + +### [1.6.4] 2019.12.24 +#### Added +* Implemented Wildcards types support (see: [Issue 111](https://github.com/ExpediaGroup/bull/issues/111)). +* Implemented transformation of a field declared with its interface. + +### [1.6.3.2] 2019.12.19 +#### Added +* Added method for retrieving the class getter methods. + +### [1.6.3.1] 2019.12.09 +#### Changed +* Testing dependencies update + +### [1.6.3] 2019.12.02 +### Added +* Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. +* Modified Travis configuration in order to test the compatibility with other JDKs versions + +### [1.6.2] 2019.11.22 +#### Changed +* Removed warning leg message in case the constructor parameter names are not available in the compiled code. +* Removed `slf4j-api` dependency from the library jar. + +### [1.6.1] 2019.11.18 +### Added +* Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. +#### Changed +* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). + +### [1.6.0.2] 2019.10.30 +### Removed +* Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` +* The following deprecated classes has been removed: + * `com.hotels.beans.model.FieldMapping` + * `com.hotels.beans.model.FieldTransformer` + * `com.hotels.beans.Transformer` +### Added +* New specific exception in case the Field Transformation function defined is not valid +* Implemented a new functionality that allows to transform also Map object applying transformation function and mappings +#### Changed +* `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` +* Updated `hibernate-validator` version to `6.1.0.Final` (was `6.0.17.Final`). + +### [1.5.1] 2019.09.02 +#### Changed +* **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** + ```xml + + com.hotels.beans + bull-bean-transformer + x.y.z + + ``` +* Module `bean-utils-library` has been relocated into `bull-bean-transformer`. +* The following classes has been deprecated, please find below the complete list and the new one to be used: + + | Deprecated | **New one** | + | :----------- | :----------- | + | `com.hotels.beans.model.FieldMapping` | `com.hotels.transformer.model.FieldMapping` | + | `com.hotels.beans.model.FieldTransformer` | `com.hotels.transformer.model.FieldTransformer` | + | `com.hotels.beans.Transformer` | `com.hotels.transformer.Transformer` | + +### [1.5.0] 2019.08.06 +#### Added +* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/ExpediaGroup/bull/issues/61)). +#### Changed +* Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled +* Modified Transformer initialization in order to create a `ConversionAnalyzer` instance only if the automatic conversion is enabled + +### [1.4.7.1] [1.4.7.2] [1.4.7.3] 2019.07.05 +#### Changed +* Changed sonatype credential + +### [1.4.7] 2019.07.03 +#### Added +* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/ExpediaGroup/bull/issues/73)). + +### [1.4.6] 2019.06.27 +#### Changed +* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/ExpediaGroup/bull/issues/70)). + +### [1.4.5] 2019.06.05 +#### Added +* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/ExpediaGroup/bull/issues/68)). +* Added check during project build in order to prevent the add different versions of the same dependency. +#### Changed +* Modified library in order to let it able to retrieve values from getters if a field does not exist (see: [Issue 66](https://github.com/ExpediaGroup/bull/issues/66)). + +### [1.4.4.1] 2019.05.29 +#### Changed +* Improved Javadoc +* Added reference to the articles published on **DZone** and **InfoQ** + +### [1.4.2] 2019.05.24 +#### Added +* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/ExpediaGroup/bull/issues/62)). +#### Fixed +* Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/ExpediaGroup/bull/issues/64)). + +### [1.4.1.1] 2019.05.24 +#### Changed +* Made the project multi module + +### [1.4.1] 2019.05.18 +#### Changed +* Removed deprecated method: `setValidationDisabled` +* Testing dependencies update + +### [1.4.0] 2019.05.13 +#### Changed +* **Modified project behaviour:** since this version the **"Bean Validation" is disabled by default**, to enable it, the following instruction needs to be executed: `transformer.setValidationEnabled(true);` + +### [1.3.2] 2019.05.11 +### Added +* Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/ExpediaGroup/bull/issues/57)). + +### [1.3.1] 2019.05.08 +#### Changed +* In order to improve the library performances the following Changed have been applied: + * Modified no args constructor invocation in order to use `LambdaMetafactory` + * Modified field value retrieval in order to use `LambdaMetafactory` + * Modified value retrieval/set from/to source/destination object in order to minimise the executed actions +* Updated `hotels-oss-parent` version to `4.0.1` (was `4.0.0`). + +### [1.3.0] 2019.04.28 +#### Added +* Added support for the transformation of Java Beans built through Builder + +### [1.2.7] 2019.04.18 +#### Changed +* Improved optional usage. +* Fixed a bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/ExpediaGroup/bull/issues/52)). + +### [1.2.6] 2019.04.06 +#### Added +* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/ExpediaGroup/bull/issues/44)). + +### [1.2.5] 2019.03.31 +#### Added +* Improved field value retrieval function. + +### [1.2.4] 2019.03.23 +#### Changed +* Added caching for method: `getDeclaredField` + +### [1.2.3] 2019.03.22 +#### Added +* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/ExpediaGroup/bull/issues/38)) +* Performance improvement + +### [1.2.2] 2019.03.20 +#### Changed +* Testing dependencies update + +### [1.2.1] 2019.03.05 +#### Added +* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/ExpediaGroup/bull/issues/24)) +* Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` + +### [1.2.0] 2019.02.25 +#### Added +* Added possibility to skip the object validation (see: [Issue 31](https://github.com/ExpediaGroup/bull/issues/31)) +* Provided documentation and samples for the above functionality +### Changed +- Updated `jdk` version to `11` (was `1.8`). +- Updated Travis configuration in order to work with java 11 +- Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created + +### [1.1.4] 2019.02.20 +#### Added +* Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/ExpediaGroup/bull/issues/27)). +* Added possibility to apply a transformation function on all fields matching with the given name without evaluating the full field path. +* Added samples and tests for the above functionality +#### Fixed +* Fixed issue that was preventing the `Set` transformation + +### [1.1.3] 2019.02.17 +#### Added +* Added static transformation functionality (see: [Issue 25](https://github.com/ExpediaGroup/bull/issues/25)). + +### [1.1.2] 2019.02 +#### Added +* Made the field name mapping more flexible adding the possibility to map destination object field with field contained into nested objects. +* Added samples and tests for the above functionality. +#### Changed +* Updated hibernate dependency: `org.hibernate.validator` (was `org.hibernate.validator`). +* Removed `parallel` execution where not needed because this could cause performance degradation. + +### [1.1.1] 2019.02.09 +#### Changed +* Improved exception messaging in order to simplify the troubleshooting process +* Improved readme file + +### [1.1.0] 2019.02.04 +#### Added +* Added dependency to: `slf4j-api` as no longer available from Spring. +- Added ValidationUtils class for raising an `IllegalArgumentException` in case any parameter is null. +#### Removed +* Removed dependency: `spring-boot-starter-validation` and imported one by one the required validation dependencies +* Removed dependency: `spring-boot-starter-cache` and imported one by one the required validation dependencies + +### [1.0.17] 2019.02.03 +#### Changed +* Improved package-info comments +#### Added +* Configured Travis in order to automatically release artifacts + +### [1.0.16] 2019.01.26 +#### Changed +* Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). +* Updated `hotels-oss-parent` version to `4.0.0` (was `2.3.5`). +#### Added +* Configured Travis in order to automatically build the application, perform a quality check and publish site. Travis build site available [here](https://travis-ci.org/ExpediaGroup/bull) +* Added build, test coverage and security badge to readme file. + +### [1.0.15] 2019.01.23 +#### Added +* Added GitHub site build with maven. + +### [1.0.14] 2019.01.18 +#### Added +* Added possibility to configure the transformer in order to set the default value for all destination's object fields that are not existing in the source object. + See [README.md](https://github.com/ExpediaGroup/bull/blob/master/README.md) for more details. +#### Changed +* Jumped to version `1.0.14` in order to be consequent to the previous library version hosted on a private repo. + +### [1.0.3] 2019.01.17 +#### Added +* Added changelog file. + +### [1.0.2] 2019.01.17 +#### Changed +* Removed not needed comments + +### [1.0.1] 2019.01.17 +#### Changed +* Added maven build info to the readme file. + +### [1.0.0] 2019.01.16 +#### Added +* First `BULL` release. diff --git a/CHANGELOG.md b/CHANGELOG.md index ac5d84018..99b85d9c4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,282 +13,4 @@ All notable changes to this project will be documented in this file. ### [2.0.0] 2021.06.18 #### Added * Increase the jdk version to 15 -* Enables the [Java Record](https://blogs.oracle.com/javamagazine/records-come-to-java) transformation - -### [1.7.7] 2021.06.23 -#### Changed -* Fixes an issue that was preventing the transformation of Object type fields - -### [1.7.6] 2021.01.11 -#### Added -* Provides new module `bull-bom` that includes all the project modules - -### [1.7.4] 2020.10.07 -#### Changed -* Provides new utilities methods - -### [1.7.3] 2020.06.09 -#### Changed -* Removes the deprecated method: `setDefaultValueSetEnabled` - -### [1.7.2] 2020.06.09 -#### Changed -* Deprecates the method: `setDefaultValueSetEnabled` and replaces it with: `setDefaultValueForMissingPrimitiveField` -* Updated `hibernate-validator` version to `6.1.5.Final` (was `6.1.4.Final`). - -### [1.7.1] 2020.03.21 -#### Added -* Implemented transformation of JavaBeans using custom Builder pattern (see: [Issue 144](https://github.com/ExpediaGroup/bull/issues/144)). -#### Changed -* Updated `hibernate-validator` version to `6.1.4.Final` (was `6.1.2.Final`). - -### [1.6.6] 2020.03.16 -#### Changed -* Updated `hotels-oss-parent` version to `5.0.0` (was `4.2.0`). -* Updated `commons-lang3` version to `3.10` (was `3.9`). - -### [1.6.5] 2020.01.21 -#### Changed -* Testing dependencies update - -### [1.6.4] 2019.12.24 -#### Added -* Implemented Wildcards types support (see: [Issue 111](https://github.com/ExpediaGroup/bull/issues/111)). -* Implemented transformation of a field declared with its interface. - -### [1.6.3.2] 2019.12.19 -#### Added -* Added method for retrieving the class getter methods. - -### [1.6.3.1] 2019.12.09 -#### Changed -* Testing dependencies update - -### [1.6.3] 2019.12.02 -### Added -* Added retry mechanism on the Bean injection in case the parameter names are not available in the compiled code. -* Modified Travis configuration in order to test the compatibility with other JDKs versions - -### [1.6.2] 2019.11.22 -#### Changed -* Removed warning leg message in case the constructor parameter names are not available in the compiled code. -* Removed `slf4j-api` dependency from the library jar. - -### [1.6.1] 2019.11.18 -### Added -* Added specific exception message in case the constructor invoke fails due to missing parameter name in the compiled code. -#### Changed -* Updated `hotels-oss-parent` version to `4.2.0` (was `4.1.0`). - -### [1.6.0.2] 2019.10.30 -### Removed -* Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` -* The following deprecated classes has been removed: - * `com.hotels.beans.model.FieldMapping` - * `com.hotels.beans.model.FieldTransformer` - * `com.hotels.beans.Transformer` -### Added -* New specific exception in case the Field Transformation function defined is not valid -* Implemented a new functionality that allows to transform also Map object applying transformation function and mappings -#### Changed -* `Transformer` class previously in charge of the Java Bean transformation has been moved to `BeanTransformer` -* Updated `hibernate-validator` version to `6.1.0.Final` (was `6.0.17.Final`). - -### [1.5.1] 2019.09.02 -#### Changed -* **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** - ```xml - - com.hotels.beans - bull-bean-transformer - x.y.z - - ``` -* Module `bean-utils-library` has been relocated into `bull-bean-transformer`. -* The following classes has been deprecated, please find below the complete list and the new one to be used: - - | Deprecated | **New one** | - | :----------- | :----------- | - | `com.hotels.beans.model.FieldMapping` | `com.hotels.transformer.model.FieldMapping` | - | `com.hotels.beans.model.FieldTransformer` | `com.hotels.transformer.model.FieldTransformer` | - | `com.hotels.beans.Transformer` | `com.hotels.transformer.Transformer` | - -### [1.5.0] 2019.08.06 -#### Added -* Implemented automatic conversion of basic types (see: [Issue 61](https://github.com/ExpediaGroup/bull/issues/61)). -#### Changed -* Modified Transformer initialization in order to create a `Validator` instance only if the validation is enabled -* Modified Transformer initialization in order to create a `ConversionAnalyzer` instance only if the automatic conversion is enabled - -### [1.4.7.1] [1.4.7.2] [1.4.7.3] 2019.07.05 -#### Changed -* Changed sonatype credential - -### [1.4.7] 2019.07.03 -#### Added -* Implemented possibility to disable the default value set for primitive types in case its value is null (see: [Issue 73](https://github.com/ExpediaGroup/bull/issues/73)). - -### [1.4.6] 2019.06.27 -#### Changed -* Improved exception messages in order to provide more details (see: [Issue 70](https://github.com/ExpediaGroup/bull/issues/70)). - -### [1.4.5] 2019.06.05 -#### Added -* Added new maven profile: `check-for-updates` for checking if any dependency can be updated (see: [Issue 68](https://github.com/ExpediaGroup/bull/issues/68)). -* Added check during project build in order to prevent the add different versions of the same dependency. -#### Changed -* Modified library in order to let it able to retrieve values from getters if a field does not exist (see: [Issue 66](https://github.com/ExpediaGroup/bull/issues/66)). - -### [1.4.4.1] 2019.05.29 -#### Changed -* Improved Javadoc -* Added reference to the articles published on **DZone** and **InfoQ** - -### [1.4.2] 2019.05.24 -#### Added -* Added possibility to define transformer function without arguments if not needed (see: [Issue 62](https://github.com/ExpediaGroup/bull/issues/62)). -#### Fixed -* Fixed a bug: FieldTransformer was receiving a default value instead of the source bean one (see: [Issue 64](https://github.com/ExpediaGroup/bull/issues/64)). - -### [1.4.1.1] 2019.05.24 -#### Changed -* Made the project multi module - -### [1.4.1] 2019.05.18 -#### Changed -* Removed deprecated method: `setValidationDisabled` -* Testing dependencies update - -### [1.4.0] 2019.05.13 -#### Changed -* **Modified project behaviour:** since this version the **"Bean Validation" is disabled by default**, to enable it, the following instruction needs to be executed: `transformer.setValidationEnabled(true);` - -### [1.3.2] 2019.05.11 -### Added -* Modified project structure in order to offer Java Bean validation feature against the defined constraints as public feature (see: [Issue 57](https://github.com/ExpediaGroup/bull/issues/57)). - -### [1.3.1] 2019.05.08 -#### Changed -* In order to improve the library performances the following Changed have been applied: - * Modified no args constructor invocation in order to use `LambdaMetafactory` - * Modified field value retrieval in order to use `LambdaMetafactory` - * Modified value retrieval/set from/to source/destination object in order to minimise the executed actions -* Updated `hotels-oss-parent` version to `4.0.1` (was `4.0.0`). - -### [1.3.0] 2019.04.28 -#### Added -* Added support for the transformation of Java Beans built through Builder - -### [1.2.7] 2019.04.18 -#### Changed -* Improved optional usage. -* Fixed a bug that was preventing the transformer function to return a null value (see: [Issue 52](https://github.com/ExpediaGroup/bull/issues/52)). - -### [1.2.6] 2019.04.06 -#### Added -* Implemented possibility to use static transformation with a given transformer (see: [Issue 44](https://github.com/ExpediaGroup/bull/issues/44)). - -### [1.2.5] 2019.03.31 -#### Added -* Improved field value retrieval function. - -### [1.2.4] 2019.03.23 -#### Changed -* Added caching for method: `getDeclaredField` - -### [1.2.3] 2019.03.22 -#### Added -* Implemented a new feature that allows to skip the transformation for a given set of fields (see: [Issue 38](https://github.com/ExpediaGroup/bull/issues/38)) -* Performance improvement - -### [1.2.2] 2019.03.20 -#### Changed -* Testing dependencies update - -### [1.2.1] 2019.03.05 -#### Added -* Implemented a new feature that allows the copy on an existing object instance (see: [Issue 24](https://github.com/ExpediaGroup/bull/issues/24)) -* Added profile: `fast` that skips the following plugin execution: `javadoc`, `checkstyle`, `pmd` and `jacoco` - -### [1.2.0] 2019.02.25 -#### Added -* Added possibility to skip the object validation (see: [Issue 31](https://github.com/ExpediaGroup/bull/issues/31)) -* Provided documentation and samples for the above functionality -### Changed -- Updated `jdk` version to `11` (was `1.8`). -- Updated Travis configuration in order to work with java 11 -- Modified Travis configuration in order to automatically create the GitHub site as soon as a tag is created - -### [1.1.4] 2019.02.20 -#### Added -* Added possibility to apply a transformation function only on a specific field (see: [Issue 27](https://github.com/ExpediaGroup/bull/issues/27)). -* Added possibility to apply a transformation function on all fields matching with the given name without evaluating the full field path. -* Added samples and tests for the above functionality -#### Fixed -* Fixed issue that was preventing the `Set` transformation - -### [1.1.3] 2019.02.17 -#### Added -* Added static transformation functionality (see: [Issue 25](https://github.com/ExpediaGroup/bull/issues/25)). - -### [1.1.2] 2019.02 -#### Added -* Made the field name mapping more flexible adding the possibility to map destination object field with field contained into nested objects. -* Added samples and tests for the above functionality. -#### Changed -* Updated hibernate dependency: `org.hibernate.validator` (was `org.hibernate.validator`). -* Removed `parallel` execution where not needed because this could cause performance degradation. - -### [1.1.1] 2019.02.09 -#### Changed -* Improved exception messaging in order to simplify the troubleshooting process -* Improved readme file - -### [1.1.0] 2019.02.04 -#### Added -* Added dependency to: `slf4j-api` as no longer available from Spring. -- Added ValidationUtils class for raising an `IllegalArgumentException` in case any parameter is null. -#### Removed -* Removed dependency: `spring-boot-starter-validation` and imported one by one the required validation dependencies -* Removed dependency: `spring-boot-starter-cache` and imported one by one the required validation dependencies - -### [1.0.17] 2019.02.03 -#### Changed -* Improved package-info comments -#### Added -* Configured Travis in order to automatically release artifacts - -### [1.0.16] 2019.01.26 -#### Changed -* Updated `spring-boot` version to `2.1.2.RELEASE` (was `2.1.0.RELEASE`). -* Updated `hotels-oss-parent` version to `4.0.0` (was `2.3.5`). -#### Added -* Configured Travis in order to automatically build the application, perform a quality check and publish site. Travis build site available [here](https://travis-ci.org/ExpediaGroup/bull) -* Added build, test coverage and security badge to readme file. - -### [1.0.15] 2019.01.23 -#### Added -* Added GitHub site build with maven. - -### [1.0.14] 2019.01.18 -#### Added -* Added possibility to configure the transformer in order to set the default value for all destination's object fields that are not existing in the source object. - See [README.md](https://github.com/ExpediaGroup/bull/blob/master/README.md) for more details. -#### Changed -* Jumped to version `1.0.14` in order to be consequent to the previous library version hosted on a private repo. - -### [1.0.3] 2019.01.17 -#### Added -* Added changelog file. - -### [1.0.2] 2019.01.17 -#### Changed -* Removed not needed comments - -### [1.0.1] 2019.01.17 -#### Changed -* Added maven build info to the readme file. - -### [1.0.0] 2019.01.16 -#### Added -* First `BULL` release. +* Enables the [Java Record](https://blogs.oracle.com/javamagazine/records-come-to-java) transformation \ No newline at end of file diff --git a/README.md b/README.md index 4036fd57a..6f643edd5 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,13 @@ It contains all the modules available in the project ``` -**The project provides two different builds**, one compatible with `jdk 8` (or above) and one with `jdk 11` or above. +**The project provides two different builds**, one compatible with `jdk 8` (or above), +one with `jdk 11` and on with `jdk 15` or above. -In case you need to integrate it in a `jdk 8` please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) file or [CHANGELOG](CHANGELOG.md) otherwise. +In case you need to integrate it in a: +* `jdk 8` please refer to [CHANGELOG-JDK8](CHANGELOG-JDK8.md) +* `jdk 11` please refer to [CHANGELOG-JDK11](CHANGELOG-JDK11.md) +* `jdk 15` [CHANGELOG](CHANGELOG.md) * #### Suggestions From a90d9e60cd8bc76d1e1d07e201c27ac71b19f767 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 08:39:30 +0200 Subject: [PATCH 1451/1786] divide the build in different job --- .github/workflows/github-default-actions.yml | 30 +++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 7b64f9db2..c4ada8b85 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -7,8 +7,8 @@ on: tags-ignore: - "*" jobs: - job: - name: "Build, test and quality check" + build: + name: "Build and test" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -18,11 +18,6 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - - name: "Extract build information" - id: build_info - run: | - echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} - echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "Set up JDK 15" uses: actions/setup-java@v2 with: @@ -33,6 +28,27 @@ jobs: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} run: | mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + quality-check: + name: "Quality check" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: "Extract build information" + id: build_info + run: | + echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} + echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} + - name: "Set up JDK 15" + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' - name: "Quality check" env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} From f58e95711972fb919fb7c08b9bc258692e9c0422 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 09:20:11 +0200 Subject: [PATCH 1452/1786] Adds the slack notifier --- .github/workflows/codeql-analysis.yml | 6 ---- .../github-default-jdk11-actions.yml | 29 +++++++++++++----- .github/workflows/slack-notify.yml | 19 ++++++++++++ docs/site/resources/images/bell.png | Bin 0 -> 2343 bytes 4 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/slack-notify.yml create mode 100644 docs/site/resources/images/bell.png diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 51990be8f..99e9d3da4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -43,12 +43,6 @@ jobs: uses: github/codeql-action/init@v1 with: languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - run: | ./mvnw clean verify - name: "Perform CodeQL Analysis" diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 1e183f7cb..341b30832 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -7,8 +7,8 @@ on: tags-ignore: - "*" jobs: - job: - name: "Build, test and quality check" + build: + name: "Build and test" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -18,11 +18,6 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - - name: "Extract build information" - id: build_info - run: | - echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} - echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "Set up JDK 11" uses: actions/setup-java@v2 with: @@ -33,6 +28,26 @@ jobs: COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} run: | mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + quality-check: + name: "Quality check" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: "Extract build information" + id: build_info + run: | + echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} + - name: "Set up JDK 11" + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' - name: "Quality check" env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml new file mode 100644 index 000000000..b301f19ab --- /dev/null +++ b/.github/workflows/slack-notify.yml @@ -0,0 +1,19 @@ +on: push +name: Slack Notification +jobs: + slackNotification: + name: "Slack Notification" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Slack Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_CHANNEL: releases + SLACK_COLOR: ${{ job.status }} + SLACK_ICON: https://raw.githubusercontent.com/ExpediaGroup/bull/master/docs/site/resources/images/bell.png + SLACK_TITLE: Message + SLACK_USERNAME: "bull-notifier" + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + SLACK_FOOTER: "Powered by BULL notifier" +} \ No newline at end of file diff --git a/docs/site/resources/images/bell.png b/docs/site/resources/images/bell.png new file mode 100644 index 0000000000000000000000000000000000000000..f574274d65a6ae2a8e45c348eb175278b1653a3f GIT binary patch literal 2343 zcmV+?3E1|DP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NKkx4{BRA>e5S$m9JRUQ7$eay^m z_uXB)Z5NiZmDU1XRPcpD0}_ZpsS;wNhD4M8;{(xvG1d5o#>Nm5`O~Tp5d+Z}0tVDb zh*2Jv_XeS*yWQ@v-L|{!K4)j=b?-gL@0^)C-DzfLXS%aBBt6N@J#+4Pe82ba{6;7? ze1Mzv0mg2iUm)QBEx}clfJ#k3rN&9)>Y16dDjbwPytf~OKm12x&%wE57u^26fV-yd z$BBA-A1cGp^uJD1n zsgUM;kUR>JJ_ebM1C1_(!|iSIC?MCxIMmEbkg;CaO?{kQAKtB4g_O)fP8~q-{+}Rc z4nU@9v{4sUG)9bzKx&C7NuoMnwQPsgeFyB$9h}n)N$UMf8g4@aWmQ{SkpzOoApD_U zA~^9kaybQIM~R1qYUyo>swBwUl!65n%py4TEawF9((94@*UOlH`5%y}B%HQRG=KIM zw0z;qaGIK{qU4+<5X=m~8@La0?j3@OK#|*aW0ZYzeMvU*g-XNO@I|C2uEWU(euB)A zcR62@0U=(2#{N&BXWt`;ZQd3RF8Mqs0#s%k*;n=u{9A^r8nK8)XtT=*lxk$Pei*r6 z5614l58h-v4@}r-*wPPwdIJ9BIAqQv_>bV?U;iDk^%pM*UcXqRq!s5CUut8`4gVG@ zLC%@w1W!X14pn5iMgr`$cVg=IkHec9<#HR5jhnD>-=pY#3L?4|*_jTc-hPed!1;lX=Fi=VNY_RJ zQE+I)VY6Zu63_h^GC3Cxm3`JMfq))IWp#Q`XqpI{1e6$T_;T@66VL&FHbYOPK~Zv! zi^A>8Ork!+q4xdlLhH`2!D?tMhr2jdSw6*Sg-(tKcog@!HsL~@{tLQx{{WeT zZz08xMf=e<5&zasay?5AUm{wqJuaAKzglQ(RJ^QyT#)paJVpw$c`b zoF9ake*g__eQ3PlQkn!M;SIvR=sE_*DuQAGLQMoH2A;a$H;2<6_zV(36RpGzdptQLkSer zCX7Yl@2XC$G>QAFvzTE>+o6OrZz)uE1`suS|!l4gqC%J!_B^ ziy(D`IJBh8G+s%OK0yd{CWTfcK+YY8_r}j5C*NSgKT~Qv{95#?JDgDV4FTn1(nPL5M-iAiuz56p3 zrJgBB!!pU1SS|1dl13G!8vPr&!5uzRd9fOt55b2|D+a}!$&Ww8^QjGOTUq>I z4Qb{bSnIAOfd|b@Mq;W3J&$nKu)4u)kRpV`GKtT$Iq@E~MrS`HKsz7pdGv4HKOc== zNzGHeX`{ksy~$}}oM1*A>tH2p!5|<3Fg^5j1` z|3-?5R8IdFYV8$pFS`dpd%rOnZA@WP#F&S97FgccB<~DH<-*A&PnH(RNfB%3D49^9 z8M#N-!S23^hgp#0FHk!is`^%z?pf*n(5KC6Lx9!!QONh7Cbvf+)_)$sv1bu-D_s_nTKnj)EzHv*|8~)~(#!fpgI Date: Wed, 14 Jul 2021 09:21:26 +0200 Subject: [PATCH 1453/1786] Adds the slack notifier --- docs/site/resources/images/bell.png | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/site/resources/images/bell.png diff --git a/docs/site/resources/images/bell.png b/docs/site/resources/images/bell.png new file mode 100644 index 000000000..e69de29bb From 68cee6b90453aebc2e3427093affe0f52d608453 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 09:24:00 +0200 Subject: [PATCH 1454/1786] fixes the slack notifier --- .github/workflows/slack-notify.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml index b301f19ab..053f0efb7 100644 --- a/.github/workflows/slack-notify.yml +++ b/.github/workflows/slack-notify.yml @@ -5,7 +5,6 @@ jobs: name: "Slack Notification" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - name: Slack Notification uses: rtCamp/action-slack-notify@v2 env: From f612b65e5d5c461a6b004112633dd250e0dafaad Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 09:29:56 +0200 Subject: [PATCH 1455/1786] removes the parenthesis --- .github/workflows/slack-notify.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml index 053f0efb7..8d6d07c40 100644 --- a/.github/workflows/slack-notify.yml +++ b/.github/workflows/slack-notify.yml @@ -14,5 +14,4 @@ jobs: SLACK_TITLE: Message SLACK_USERNAME: "bull-notifier" SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - SLACK_FOOTER: "Powered by BULL notifier" -} \ No newline at end of file + SLACK_FOOTER: "Powered by BULL notifier" \ No newline at end of file From e929bfc70b582dfa5bfd6c54372f70965f85646c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 09:30:43 +0200 Subject: [PATCH 1456/1786] updates the icon bell --- docs/site/resources/images/bell.png | Bin 0 -> 2343 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/site/resources/images/bell.png b/docs/site/resources/images/bell.png index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f574274d65a6ae2a8e45c348eb175278b1653a3f 100644 GIT binary patch literal 2343 zcmV+?3E1|DP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NKkx4{BRA>e5S$m9JRUQ7$eay^m z_uXB)Z5NiZmDU1XRPcpD0}_ZpsS;wNhD4M8;{(xvG1d5o#>Nm5`O~Tp5d+Z}0tVDb zh*2Jv_XeS*yWQ@v-L|{!K4)j=b?-gL@0^)C-DzfLXS%aBBt6N@J#+4Pe82ba{6;7? ze1Mzv0mg2iUm)QBEx}clfJ#k3rN&9)>Y16dDjbwPytf~OKm12x&%wE57u^26fV-yd z$BBA-A1cGp^uJD1n zsgUM;kUR>JJ_ebM1C1_(!|iSIC?MCxIMmEbkg;CaO?{kQAKtB4g_O)fP8~q-{+}Rc z4nU@9v{4sUG)9bzKx&C7NuoMnwQPsgeFyB$9h}n)N$UMf8g4@aWmQ{SkpzOoApD_U zA~^9kaybQIM~R1qYUyo>swBwUl!65n%py4TEawF9((94@*UOlH`5%y}B%HQRG=KIM zw0z;qaGIK{qU4+<5X=m~8@La0?j3@OK#|*aW0ZYzeMvU*g-XNO@I|C2uEWU(euB)A zcR62@0U=(2#{N&BXWt`;ZQd3RF8Mqs0#s%k*;n=u{9A^r8nK8)XtT=*lxk$Pei*r6 z5614l58h-v4@}r-*wPPwdIJ9BIAqQv_>bV?U;iDk^%pM*UcXqRq!s5CUut8`4gVG@ zLC%@w1W!X14pn5iMgr`$cVg=IkHec9<#HR5jhnD>-=pY#3L?4|*_jTc-hPed!1;lX=Fi=VNY_RJ zQE+I)VY6Zu63_h^GC3Cxm3`JMfq))IWp#Q`XqpI{1e6$T_;T@66VL&FHbYOPK~Zv! zi^A>8Ork!+q4xdlLhH`2!D?tMhr2jdSw6*Sg-(tKcog@!HsL~@{tLQx{{WeT zZz08xMf=e<5&zasay?5AUm{wqJuaAKzglQ(RJ^QyT#)paJVpw$c`b zoF9ake*g__eQ3PlQkn!M;SIvR=sE_*DuQAGLQMoH2A;a$H;2<6_zV(36RpGzdptQLkSer zCX7Yl@2XC$G>QAFvzTE>+o6OrZz)uE1`suS|!l4gqC%J!_B^ ziy(D`IJBh8G+s%OK0yd{CWTfcK+YY8_r}j5C*NSgKT~Qv{95#?JDgDV4FTn1(nPL5M-iAiuz56p3 zrJgBB!!pU1SS|1dl13G!8vPr&!5uzRd9fOt55b2|D+a}!$&Ww8^QjGOTUq>I z4Qb{bSnIAOfd|b@Mq;W3J&$nKu)4u)kRpV`GKtT$Iq@E~MrS`HKsz7pdGv4HKOc== zNzGHeX`{ksy~$}}oM1*A>tH2p!5|<3Fg^5j1` z|3-?5R8IdFYV8$pFS`dpd%rOnZA@WP#F&S97FgccB<~DH<-*A&PnH(RNfB%3D49^9 z8M#N-!S23^hgp#0FHk!is`^%z?pf*n(5KC6Lx9!!QONh7Cbvf+)_)$sv1bu-D_s_nTKnj)EzHv*|8~)~(#!fpgI Date: Wed, 14 Jul 2021 09:36:38 +0200 Subject: [PATCH 1457/1786] Trigger notification From 0a24e165e7c3d8e626be3f2db17bfcd241293841 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 09:45:02 +0200 Subject: [PATCH 1458/1786] Defines the event for which a notification needs to be sent on slack --- .github/workflows/slack-notify.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml index 8d6d07c40..97a29c45c 100644 --- a/.github/workflows/slack-notify.yml +++ b/.github/workflows/slack-notify.yml @@ -1,8 +1,15 @@ -on: push -name: Slack Notification +on: + issues: + types: [ opened, edited, milestoned ] + pull_request: + types: [ assigned, opened, synchronize, reopened ] + release: + types: [ published, created, released ] + deployment +name: "Slack Notifier" jobs: - slackNotification: - name: "Slack Notification" + slack-notification: + name: "Notify on Slack" runs-on: ubuntu-latest steps: - name: Slack Notification From 1ad1e29d417cf69f5db71ad7451433b4e8fc8e7a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 09:45:31 +0200 Subject: [PATCH 1459/1786] test notification --- .github/workflows/slack-notify.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml index 97a29c45c..4dede0974 100644 --- a/.github/workflows/slack-notify.yml +++ b/.github/workflows/slack-notify.yml @@ -6,6 +6,7 @@ on: release: types: [ published, created, released ] deployment + push name: "Slack Notifier" jobs: slack-notification: From fba846d56bebb5b674b8ace3efae1a362c8a9fa2 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 09:48:25 +0200 Subject: [PATCH 1460/1786] test notification --- .github/workflows/slack-notify.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml index 4dede0974..9b59153a3 100644 --- a/.github/workflows/slack-notify.yml +++ b/.github/workflows/slack-notify.yml @@ -1,12 +1,13 @@ on: + push: + branches: + - "*" issues: types: [ opened, edited, milestoned ] pull_request: types: [ assigned, opened, synchronize, reopened ] release: types: [ published, created, released ] - deployment - push name: "Slack Notifier" jobs: slack-notification: From 209724f7dedc97c2c48f581dc862b1c5ec040ecf Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 09:49:58 +0200 Subject: [PATCH 1461/1786] changes the notification event --- .github/workflows/codeql-analysis.yml | 2 ++ .github/workflows/slack-notify.yml | 1 + 2 files changed, 3 insertions(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 99e9d3da4..2c04c1abf 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -15,9 +15,11 @@ on: push: branches: - "*" + - "*/*" pull_request: branches: - "*" + - "*/*" jobs: analyze: name: Analyze diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml index 9b59153a3..7e618eba4 100644 --- a/.github/workflows/slack-notify.yml +++ b/.github/workflows/slack-notify.yml @@ -2,6 +2,7 @@ on: push: branches: - "*" + - "*/*" issues: types: [ opened, edited, milestoned ] pull_request: From b5255187a86bd7d43b990923b6312250dabc3576 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 09:50:45 +0200 Subject: [PATCH 1462/1786] finalized the notification events --- .github/workflows/slack-notify.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml index 7e618eba4..03b34e75d 100644 --- a/.github/workflows/slack-notify.yml +++ b/.github/workflows/slack-notify.yml @@ -1,8 +1,4 @@ on: - push: - branches: - - "*" - - "*/*" issues: types: [ opened, edited, milestoned ] pull_request: From e14f081f53e2d0ad4219fcab3b591ef58915f77b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 10:08:42 +0200 Subject: [PATCH 1463/1786] Replaces the parent pom: hotels-oss-parent to the new one: eg-oss-parent --- pom.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a164b15c8..19e32f89a 100644 --- a/pom.xml +++ b/pom.xml @@ -30,10 +30,11 @@ incredibly fast. It's the only library able to transform Mutable, Immutable and Mixed bean without any custom configuration. + - com.hotels - hotels-oss-parent - 6.2.1 + com.expediagroup + eg-oss-parent + 2.3.2 @@ -77,6 +78,7 @@ github 3.9.1 + [3.3.9,) 3.0.1 3.3.0 3.1.2 From 040c53c2787ee5bfe27103a533da90663e37ab35 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 10:14:03 +0200 Subject: [PATCH 1464/1786] Adds the missing maven dependency --- .github/workflows/slack-notify.yml | 3 +++ pom.xml | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml index 03b34e75d..4a5a93fb9 100644 --- a/.github/workflows/slack-notify.yml +++ b/.github/workflows/slack-notify.yml @@ -5,6 +5,9 @@ on: types: [ assigned, opened, synchronize, reopened ] release: types: [ published, created, released ] + push: + tags: + - "*" name: "Slack Notifier" jobs: slack-notification: diff --git a/pom.xml b/pom.xml index 19e32f89a..4c7a80296 100644 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,7 @@ 3.0.1 3.3.0 3.1.2 + 2.8.1 8.44 2.12.1 3.0.0-M4 From 140ecef44ef16a76f248faf94a7b756cb3b4e1ba Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 10:21:03 +0200 Subject: [PATCH 1465/1786] Adds the missing dependencies --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 4c7a80296..819172c8b 100644 --- a/pom.xml +++ b/pom.xml @@ -87,6 +87,7 @@ 2.12.1 3.0.0-M4 1.6.8 + 3.1.2 false From 17791aa8d0e0b5956a6fc15d71477ceaaa76bbc5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 10:38:15 +0200 Subject: [PATCH 1466/1786] minor change --- .github/workflows/github-release-actions.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 941d75a68..ed96ce10b 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -23,6 +23,11 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} + - name: "Project version set" + env: + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} - name: "Set up JDK 15" uses: actions/setup-java@v2 with: @@ -35,11 +40,6 @@ jobs: gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase settings-path: ${{ github.workspace }} - - name: "Project version set" - env: - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} - run: | - mvn versions:set -D newVersion=${TAG_NAME} - name: "Quality check" env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} From 5c45484d3579c9a39c0db234c81dc7bea2759977 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 15:26:11 +0200 Subject: [PATCH 1467/1786] testing the github pages release with a a token --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index ed96ce10b..e29425150 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -55,7 +55,7 @@ jobs: - name: "Deploy GitHub Pages" uses: peaceiris/actions-gh-pages@v3 with: - github_token: ${{ secrets.GITHUB_TOKEN }} + personal_token: ${{ secrets.SITE_BUILD_TOKEN }} publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com From efdbcb839553f85c0eab22309d9a91bd3f7cec20 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 15:41:37 +0200 Subject: [PATCH 1468/1786] testing notification --- .github/workflows/github-release-actions.yml | 14 ++++++++++- .github/workflows/slack-notify.yml | 26 -------------------- 2 files changed, 13 insertions(+), 27 deletions(-) delete mode 100644 .github/workflows/slack-notify.yml diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index e29425150..41538704f 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -23,6 +23,17 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} + - name: "Send Slack Notification" + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_CHANNEL: releases + SLACK_COLOR: ${{ job.status }} + SLACK_ICON: https://raw.githubusercontent.com/ExpediaGroup/bull/master/docs/site/resources/images/bell.png + SLACK_TITLE: "New BULL release available" + SLACK_MESSAGE: "BULL version:" + ${{ steps.build_info.outputs.TAG_NAME }} "available" + SLACK_USERNAME: "bull-notifier" + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + SLACK_FOOTER: "Powered by BULL notifier" - name: "Project version set" env: TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} @@ -65,4 +76,5 @@ jobs: HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} run: | - mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file + mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true + diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml deleted file mode 100644 index 4a5a93fb9..000000000 --- a/.github/workflows/slack-notify.yml +++ /dev/null @@ -1,26 +0,0 @@ -on: - issues: - types: [ opened, edited, milestoned ] - pull_request: - types: [ assigned, opened, synchronize, reopened ] - release: - types: [ published, created, released ] - push: - tags: - - "*" -name: "Slack Notifier" -jobs: - slack-notification: - name: "Notify on Slack" - runs-on: ubuntu-latest - steps: - - name: Slack Notification - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_CHANNEL: releases - SLACK_COLOR: ${{ job.status }} - SLACK_ICON: https://raw.githubusercontent.com/ExpediaGroup/bull/master/docs/site/resources/images/bell.png - SLACK_TITLE: Message - SLACK_USERNAME: "bull-notifier" - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - SLACK_FOOTER: "Powered by BULL notifier" \ No newline at end of file From 0a676af6c82810af3e1f7ebb956d2658ba1e5138 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 15:43:09 +0200 Subject: [PATCH 1469/1786] testing notification --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 41538704f..6925d4cb1 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -30,7 +30,7 @@ jobs: SLACK_COLOR: ${{ job.status }} SLACK_ICON: https://raw.githubusercontent.com/ExpediaGroup/bull/master/docs/site/resources/images/bell.png SLACK_TITLE: "New BULL release available" - SLACK_MESSAGE: "BULL version:" + ${{ steps.build_info.outputs.TAG_NAME }} "available" + SLACK_MESSAGE: "BULL version: ${{ steps.build_info.outputs.TAG_NAME }} available" SLACK_USERNAME: "bull-notifier" SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} SLACK_FOOTER: "Powered by BULL notifier" From 5552c3fb61510af169ded003172831f555b97882 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 15:48:45 +0200 Subject: [PATCH 1470/1786] testing notification --- .github/workflows/github-release-actions.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 6925d4cb1..ccefb3866 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -29,8 +29,8 @@ jobs: SLACK_CHANNEL: releases SLACK_COLOR: ${{ job.status }} SLACK_ICON: https://raw.githubusercontent.com/ExpediaGroup/bull/master/docs/site/resources/images/bell.png - SLACK_TITLE: "New BULL release available" - SLACK_MESSAGE: "BULL version: ${{ steps.build_info.outputs.TAG_NAME }} available" + SLACK_TITLE: "BULL version: ${{ steps.build_info.outputs.TAG_NAME }} available." + SLACK_MESSAGE: "Check out the implemented changes at: https://github.com/ExpediaGroup/bull/blob/master/CHANGELOG.md." SLACK_USERNAME: "bull-notifier" SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} SLACK_FOOTER: "Powered by BULL notifier" From c50212d6e6f25b1a222445a1fa6ecf383137cc12 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 15:58:51 +0200 Subject: [PATCH 1471/1786] format the notification --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index ccefb3866..cd533aa78 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -30,7 +30,7 @@ jobs: SLACK_COLOR: ${{ job.status }} SLACK_ICON: https://raw.githubusercontent.com/ExpediaGroup/bull/master/docs/site/resources/images/bell.png SLACK_TITLE: "BULL version: ${{ steps.build_info.outputs.TAG_NAME }} available." - SLACK_MESSAGE: "Check out the implemented changes at: https://github.com/ExpediaGroup/bull/blob/master/CHANGELOG.md." + SLACK_MESSAGE: "" SLACK_USERNAME: "bull-notifier" SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} SLACK_FOOTER: "Powered by BULL notifier" From f02892a06c952a8d7f243d9d48ce0efd8c0daf49 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 16:01:57 +0200 Subject: [PATCH 1472/1786] format the notification --- .../github-jdk11-release-actions.yml | 13 +++++++++- .github/workflows/github-release-actions.yml | 24 +++++++++---------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 884f8b424..6fa28ad7f 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -58,4 +58,15 @@ jobs: HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} run: | - mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true \ No newline at end of file + mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true + - name: "Send Slack Notification" + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_CHANNEL: releases + SLACK_COLOR: ${{ job.status }} + SLACK_ICON: https://raw.githubusercontent.com/ExpediaGroup/bull/master/docs/site/resources/images/bell.png + SLACK_TITLE: "BULL version: ${{ steps.build_info.outputs.TAG_NAME }} available." + SLACK_MESSAGE: "" + SLACK_USERNAME: "bull-notifier" + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + SLACK_FOOTER: "Powered by BULL notifier" \ No newline at end of file diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index cd533aa78..5eff4cd03 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -23,17 +23,6 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - - name: "Send Slack Notification" - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_CHANNEL: releases - SLACK_COLOR: ${{ job.status }} - SLACK_ICON: https://raw.githubusercontent.com/ExpediaGroup/bull/master/docs/site/resources/images/bell.png - SLACK_TITLE: "BULL version: ${{ steps.build_info.outputs.TAG_NAME }} available." - SLACK_MESSAGE: "" - SLACK_USERNAME: "bull-notifier" - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - SLACK_FOOTER: "Powered by BULL notifier" - name: "Project version set" env: TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} @@ -66,7 +55,7 @@ jobs: - name: "Deploy GitHub Pages" uses: peaceiris/actions-gh-pages@v3 with: - personal_token: ${{ secrets.SITE_BUILD_TOKEN }} + personal_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com @@ -77,4 +66,15 @@ jobs: GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} run: | mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true + - name: "Send Slack Notification" + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_CHANNEL: releases + SLACK_COLOR: ${{ job.status }} + SLACK_ICON: https://raw.githubusercontent.com/ExpediaGroup/bull/master/docs/site/resources/images/bell.png + SLACK_TITLE: "BULL version: ${{ steps.build_info.outputs.TAG_NAME }} available." + SLACK_MESSAGE: "" + SLACK_USERNAME: "bull-notifier" + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + SLACK_FOOTER: "Powered by BULL notifier" From eace88c85245bf66a0416633bb052209572c4e66 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 16:07:20 +0200 Subject: [PATCH 1473/1786] format the notification --- .github/workflows/github-release-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 5eff4cd03..d286c7cf4 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -55,7 +55,7 @@ jobs: - name: "Deploy GitHub Pages" uses: peaceiris/actions-gh-pages@v3 with: - personal_token: ${{ secrets.GITHUB_TOKEN }} + personal_token: ${{ secrets.SITE_BUILD_TOKEN }} publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com From 4f2b59f83b450249a7f372e01cdaea4bb0e97c84 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 16:21:08 +0200 Subject: [PATCH 1474/1786] testing release in different job --- .github/workflows/github-release-actions.yml | 77 ++++++++++++++++---- 1 file changed, 62 insertions(+), 15 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index d286c7cf4..56937fc15 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -6,8 +6,18 @@ on: tags-ignore: - "*-jdk11" jobs: - job: - name: "BULL Release" + build-info-extraction: + name: "Build info extraction" + runs-on: ubuntu-latest + steps: + - name: "Extract build information" + id: build_info + run: | + echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} + echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} + echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} + quality-check: + name: "Quality check" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -17,15 +27,9 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - - name: "Extract build information" - id: build_info - run: | - echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} - echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - name: "Project version set" env: - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + TAG_NAME: ${{ jobs.build-info-extraction.steps.build_info.outputs.TAG_NAME }} run: | mvn versions:set -D newVersion=${TAG_NAME} - name: "Set up JDK 15" @@ -33,12 +37,6 @@ jobs: with: java-version: '15' distribution: 'adopt' - server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy - server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy - # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin - gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import - gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase settings-path: ${{ github.workspace }} - name: "Quality check" env: @@ -47,6 +45,27 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q + site-build: + name: "Site Build" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: "Project version set" + env: + TAG_NAME: ${{ jobs.build-info-extraction.steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} + - name: "Set up JDK 15" + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' - name: "Site build" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -59,6 +78,34 @@ jobs: publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com + artifact-release: + name: "Publish artifact" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + - name: "Project version set" + env: + TAG_NAME: ${{ jobs.build-info-extraction.steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} + - name: "Set up JDK 15" + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' + server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml + server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy + server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy + # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase + settings-path: ${{ github.workspace }} - name: "Release artifacts" env: HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} From 7270d3b8b1bc05eab77778ed487cd9019c54c096 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 16:27:31 +0200 Subject: [PATCH 1475/1786] single job --- .github/workflows/github-release-actions.yml | 77 ++++---------------- 1 file changed, 15 insertions(+), 62 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 56937fc15..d286c7cf4 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -6,18 +6,8 @@ on: tags-ignore: - "*-jdk11" jobs: - build-info-extraction: - name: "Build info extraction" - runs-on: ubuntu-latest - steps: - - name: "Extract build information" - id: build_info - run: | - echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} - echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - quality-check: - name: "Quality check" + job: + name: "BULL Release" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -27,9 +17,15 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 + - name: "Extract build information" + id: build_info + run: | + echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} + echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} + echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - name: "Project version set" env: - TAG_NAME: ${{ jobs.build-info-extraction.steps.build_info.outputs.TAG_NAME }} + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | mvn versions:set -D newVersion=${TAG_NAME} - name: "Set up JDK 15" @@ -37,6 +33,12 @@ jobs: with: java-version: '15' distribution: 'adopt' + server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml + server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy + server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy + # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase settings-path: ${{ github.workspace }} - name: "Quality check" env: @@ -45,27 +47,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q - site-build: - name: "Site Build" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - name: "Project version set" - env: - TAG_NAME: ${{ jobs.build-info-extraction.steps.build_info.outputs.TAG_NAME }} - run: | - mvn versions:set -D newVersion=${TAG_NAME} - - name: "Set up JDK 15" - uses: actions/setup-java@v2 - with: - java-version: '15' - distribution: 'adopt' - name: "Site build" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -78,34 +59,6 @@ jobs: publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com - artifact-release: - name: "Publish artifact" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - name: "Project version set" - env: - TAG_NAME: ${{ jobs.build-info-extraction.steps.build_info.outputs.TAG_NAME }} - run: | - mvn versions:set -D newVersion=${TAG_NAME} - - name: "Set up JDK 15" - uses: actions/setup-java@v2 - with: - java-version: '15' - distribution: 'adopt' - server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy - server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy - # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin - gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import - gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase - settings-path: ${{ github.workspace }} - name: "Release artifacts" env: HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} From 462a83e3dcb436812ac24c7b7f91a496ea4d050e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 16:31:07 +0200 Subject: [PATCH 1476/1786] removes the empty lines --- .github/workflows/github-release-actions.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index d286c7cf4..7cad7a845 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -76,5 +76,4 @@ jobs: SLACK_MESSAGE: "" SLACK_USERNAME: "bull-notifier" SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - SLACK_FOOTER: "Powered by BULL notifier" - + SLACK_FOOTER: "Powered by BULL notifier" \ No newline at end of file From f73a99921434fba48220b9d8a044745a3053c9e6 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 14 Jul 2021 17:46:29 +0200 Subject: [PATCH 1477/1786] changes the site logo --- docs/site/markdown/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/site/markdown/index.md b/docs/site/markdown/index.md index 6105bddfc..80b416589 100644 --- a/docs/site/markdown/index.md +++ b/docs/site/markdown/index.md @@ -2,7 +2,7 @@ About -# ![bull-logo](images/BullBranding_03.png) +# ![bull-logo](images/BullBranding_04.png) # Overview From fe884397e1311df3a39a58ae915cba74b992a91f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 15 Jul 2021 10:59:43 +0200 Subject: [PATCH 1478/1786] Replaces the release token with the eg one --- .github/workflows/github-release-actions.yml | 4 +++- docs/site/site.xml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 7cad7a845..cc1794eab 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -11,6 +11,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -55,7 +57,7 @@ jobs: - name: "Deploy GitHub Pages" uses: peaceiris/actions-gh-pages@v3 with: - personal_token: ${{ secrets.SITE_BUILD_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com diff --git a/docs/site/site.xml b/docs/site/site.xml index c0a0849df..ed824cd14 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -14,7 +14,7 @@ ExpediaGroup/bull right - #cf2d35 + #00019B From d96b6ccb81e0e7db55ecc4407f2361dd74485d37 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 15 Jul 2021 11:04:23 +0200 Subject: [PATCH 1479/1786] testing using the personal token setting --- .github/workflows/github-release-actions.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index cc1794eab..6497bf46a 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -11,8 +11,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - with: - token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -57,7 +55,7 @@ jobs: - name: "Deploy GitHub Pages" uses: peaceiris/actions-gh-pages@v3 with: - github_token: ${{ secrets.GITHUB_TOKEN }} + personal_token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} publish_dir: ./target/site user_name: eg-oss-ci user_email: oss@expediagroup.com From 60da66f06f546fcf35202278289e9c20bb3e5171 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 15 Jul 2021 11:16:57 +0200 Subject: [PATCH 1480/1786] restores the old color --- docs/site/site.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/site/site.xml b/docs/site/site.xml index ed824cd14..c0a0849df 100644 --- a/docs/site/site.xml +++ b/docs/site/site.xml @@ -14,7 +14,7 @@ ExpediaGroup/bull right - #00019B + #cf2d35 From da493d9f84c66dab75679e00f950b353da5ff753 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 15 Jul 2021 12:14:59 +0200 Subject: [PATCH 1481/1786] minor improvements --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2c04c1abf..756cfd372 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -9,7 +9,7 @@ # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # -name: "CodeQL" +name: "Security check" on: push: @@ -22,7 +22,7 @@ on: - "*/*" jobs: analyze: - name: Analyze + name: "Analyze" runs-on: ubuntu-latest permissions: actions: read @@ -38,7 +38,7 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: Checkout repository + - name: "Checkout repository" uses: actions/checkout@v2 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" From b629c7987f1ea822ba2184784600b48d106aa60b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Jul 2021 02:11:58 +0000 Subject: [PATCH 1482/1786] Bump spotless-maven-plugin from 2.12.1 to 2.12.2 Bumps [spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.12.1 to 2.12.2. - [Release notes](https://github.com/diffplug/spotless/releases) - [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md) - [Commits](https://github.com/diffplug/spotless/compare/lib/2.12.1...maven/2.12.2) --- updated-dependencies: - dependency-name: com.diffplug.spotless:spotless-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 819172c8b..c2eca8136 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.1.2 2.8.1 8.44 - 2.12.1 + 2.12.2 3.0.0-M4 1.6.8 3.1.2 From 4b70b0c1fe92d9c0a346abd5b7c811147c5567c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Jul 2021 02:12:05 +0000 Subject: [PATCH 1483/1786] Bump slf4j-api from 1.7.31 to 1.7.32 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.31 to 1.7.32. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/commits) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 819172c8b..e64e2cb64 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 3.20.2 7.0.1.Final - 1.7.31 + 1.7.32 4.0.1 0.8.7 From bd97444a64ead67b94f6e4dfbe88540a1d37acbe Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 09:24:58 +0200 Subject: [PATCH 1484/1786] Test the build with the quality check and tests in a different step --- .github/workflows/github-default-actions.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index c4ada8b85..9e95dc825 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -8,7 +8,7 @@ on: - "*" jobs: build: - name: "Build and test" + name: "Build" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -23,13 +23,11 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: "Build and Test" - env: - COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + - name: "Build" run: | - mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + mvn clean install -B -DskipTests -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode quality-check: - name: "Quality check" + name: "Test and quality check" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -42,7 +40,6 @@ jobs: - name: "Extract build information" id: build_info run: | - echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "Set up JDK 15" uses: actions/setup-java@v2 @@ -55,5 +52,8 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} + COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} run: | - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn \ No newline at end of file + mvn test -P compatibility-mode + mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode + mvn sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode \ No newline at end of file From f6c7d3bf369d1d8d4f3535578f44a5947f6a1852 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 09:29:36 +0200 Subject: [PATCH 1485/1786] Test the build with the quality check and tests in a different step --- .github/workflows/github-default-actions.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 9e95dc825..70c0358f9 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -54,6 +54,5 @@ jobs: SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} run: | - mvn test -P compatibility-mode - mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode - mvn sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode \ No newline at end of file + mvn test sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode -P compatibility-mode + mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode \ No newline at end of file From b8e894004905836d09caee152d7b9c4e720d504e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 09:49:56 +0200 Subject: [PATCH 1486/1786] * Removes the security check from a different job and integrates it in the existing one * Splits the build, performing the test one time only to speed up the process --- .github/workflows/codeql-analysis.yml | 51 ------------------- .github/workflows/github-default-actions.yml | 41 ++++++++++++--- .../github-default-jdk11-actions.yml | 45 +++++++++++++--- .../github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 5 files changed, 74 insertions(+), 67 deletions(-) delete mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 756cfd372..000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,51 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "Security check" - -on: - push: - branches: - - "*" - - "*/*" - pull_request: - branches: - - "*" - - "*/*" -jobs: - analyze: - name: "Analyze" - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - strategy: - fail-fast: false - matrix: - language: [ 'java' ] - steps: - - name: "Set up JDK 15" - uses: actions/setup-java@v2 - with: - java-version: '15' - distribution: 'adopt' - - name: "Checkout repository" - uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - - name: "Initialize CodeQL" - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - - run: | - ./mvnw clean verify - - name: "Perform CodeQL Analysis" - uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 70c0358f9..348dd4a71 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -8,7 +8,7 @@ on: - "*" jobs: build: - name: "Build" + name: "Build and test" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -18,10 +18,10 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - - name: "Set up JDK 15" + - name: "JDK set-up" uses: actions/setup-java@v2 with: - java-version: '15' + java-version: '11' distribution: 'adopt' - name: "Build" run: | @@ -41,7 +41,7 @@ jobs: id: build_info run: | echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - - name: "Set up JDK 15" + - name: "JDK set-up" uses: actions/setup-java@v2 with: java-version: '15' @@ -54,5 +54,34 @@ jobs: SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} run: | - mvn test sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode -P compatibility-mode - mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode \ No newline at end of file + mvn verify -P compatibility-mode + mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode + mvn verify sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode + security-check: + name: "Security check" + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: [ 'java' ] + steps: + - name: "JDK 11 set-up" + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + - name: "Checkout repository" + uses: actions/checkout@v2 + # Initializes the CodeQL tools for scanning. + - name: "Initialize CodeQL" + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + - run: | + ./mvnw clean verify + - name: "Perform Analysis" + uses: github/codeql-action/analyze@v1 \ No newline at end of file diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 341b30832..af55d6631 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -18,18 +18,16 @@ jobs: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - - name: "Set up JDK 11" + - name: "JDK 11 set-up" uses: actions/setup-java@v2 with: java-version: '11' distribution: 'adopt' - - name: "Build and Test" - env: - COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + - name: "Build" run: | - mvn clean install jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode + mvn clean install -B -DskipTests -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode quality-check: - name: "Quality check" + name: "Test and quality check" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -43,7 +41,7 @@ jobs: id: build_info run: | echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - - name: "Set up JDK 11" + - name: "JDK 11 set-up" uses: actions/setup-java@v2 with: java-version: '11' @@ -54,5 +52,36 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} + COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} run: | - mvn install sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn \ No newline at end of file + mvn verify -P compatibility-mode + mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode + mvn verify sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode + security-check: + name: "Security check" + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: [ 'java' ] + steps: + - name: "JDK set-up" + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' + - name: "Checkout repository" + uses: actions/checkout@v2 + # Initializes the CodeQL tools for scanning. + - name: "Initialize CodeQL" + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + - run: | + ./mvnw clean verify + - name: "Perform Analysis" + uses: github/codeql-action/analyze@v1 \ No newline at end of file diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 6fa28ad7f..811e94d6b 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -23,7 +23,7 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - - name: "Set up JDK 11" + - name: "JDK 11 set-up" uses: actions/setup-java@v2 with: java-version: '11' diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 6497bf46a..bc88ff698 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -28,7 +28,7 @@ jobs: TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} run: | mvn versions:set -D newVersion=${TAG_NAME} - - name: "Set up JDK 15" + - name: "JDK set-up" uses: actions/setup-java@v2 with: java-version: '15' From 2b8054148ea5931ff13df5d0f97ab8926f12a6f1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 09:51:49 +0200 Subject: [PATCH 1487/1786] fix the jdk version setting the right one --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 348dd4a71..a8ece6750 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -21,7 +21,7 @@ jobs: - name: "JDK set-up" uses: actions/setup-java@v2 with: - java-version: '11' + java-version: '15' distribution: 'adopt' - name: "Build" run: | @@ -69,10 +69,10 @@ jobs: matrix: language: [ 'java' ] steps: - - name: "JDK 11 set-up" + - name: "JDK set-up" uses: actions/setup-java@v2 with: - java-version: '11' + java-version: '15' distribution: 'adopt' - name: "Checkout repository" uses: actions/checkout@v2 diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index af55d6631..daaf68b62 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -69,10 +69,10 @@ jobs: matrix: language: [ 'java' ] steps: - - name: "JDK set-up" + - name: "JDK 11 set-up" uses: actions/setup-java@v2 with: - java-version: '15' + java-version: '11' distribution: 'adopt' - name: "Checkout repository" uses: actions/checkout@v2 From f06fabb355536a7089b771de20202992c573d49a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 09:55:57 +0200 Subject: [PATCH 1488/1786] modifies the security scan --- .github/workflows/github-default-actions.yml | 8 ++------ .github/workflows/github-default-jdk11-actions.yml | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index a8ece6750..dc1f016d3 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -64,10 +64,6 @@ jobs: actions: read contents: read security-events: write - strategy: - fail-fast: false - matrix: - language: [ 'java' ] steps: - name: "JDK set-up" uses: actions/setup-java@v2 @@ -80,8 +76,8 @@ jobs: - name: "Initialize CodeQL" uses: github/codeql-action/init@v1 with: - languages: ${{ matrix.language }} + languages: 'java' - run: | - ./mvnw clean verify + mvn clean verify - name: "Perform Analysis" uses: github/codeql-action/analyze@v1 \ No newline at end of file diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index daaf68b62..17e1084a0 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -64,10 +64,6 @@ jobs: actions: read contents: read security-events: write - strategy: - fail-fast: false - matrix: - language: [ 'java' ] steps: - name: "JDK 11 set-up" uses: actions/setup-java@v2 @@ -80,8 +76,8 @@ jobs: - name: "Initialize CodeQL" uses: github/codeql-action/init@v1 with: - languages: ${{ matrix.language }} + languages: 'java' - run: | - ./mvnw clean verify + mvn clean verify - name: "Perform Analysis" uses: github/codeql-action/analyze@v1 \ No newline at end of file From e2d4801a35f1628a6229ed5d1e30a1e3047bdc10 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 10:01:48 +0200 Subject: [PATCH 1489/1786] merge the security scan into the quality check job --- .github/workflows/github-default-actions.yml | 30 ++++--------------- .../github-default-jdk11-actions.yml | 2 +- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index dc1f016d3..e41ea9aa0 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -8,7 +8,7 @@ on: - "*" jobs: build: - name: "Build and test" + name: "Build" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -46,6 +46,10 @@ jobs: with: java-version: '15' distribution: 'adopt' + - name: "Initialize CodeQL" + uses: github/codeql-action/init@v1 + with: + languages: 'java' - name: "Quality check" env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} @@ -57,27 +61,5 @@ jobs: mvn verify -P compatibility-mode mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode mvn verify sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode - security-check: - name: "Security check" - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - steps: - - name: "JDK set-up" - uses: actions/setup-java@v2 - with: - java-version: '15' - distribution: 'adopt' - - name: "Checkout repository" - uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - - name: "Initialize CodeQL" - uses: github/codeql-action/init@v1 - with: - languages: 'java' - - run: | - mvn clean verify - - name: "Perform Analysis" + - name: "Security check" uses: github/codeql-action/analyze@v1 \ No newline at end of file diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 17e1084a0..f40fce8a7 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -8,7 +8,7 @@ on: - "*" jobs: build: - name: "Build and test" + name: "Build" runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 From 6b78ad603cfa40ad67f15f623e86bbeae93cb656 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 10:08:15 +0200 Subject: [PATCH 1490/1786] restores the security check in a different step --- .github/workflows/github-default-actions.yml | 28 +++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index e41ea9aa0..32ecbbd2b 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -46,10 +46,6 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: "Initialize CodeQL" - uses: github/codeql-action/init@v1 - with: - languages: 'java' - name: "Quality check" env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} @@ -62,4 +58,28 @@ jobs: mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode mvn verify sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode - name: "Security check" + uses: github/codeql-action/analyze@v1 + security-check: + name: "Security check" + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - name: "JDK set-up" + uses: actions/setup-java@v2 + with: + java-version: '15' + distribution: 'adopt' + - name: "Checkout repository" + uses: actions/checkout@v2 + # Initializes the CodeQL tools for scanning. + - name: "Initialize CodeQL" + uses: github/codeql-action/init@v1 + with: + languages: 'java' + - run: | + mvn clean verify + - name: "Perform Analysis" uses: github/codeql-action/analyze@v1 \ No newline at end of file From dd03b592a543b3ee8a68c6a47aeba34d5f28f1f7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 10:14:38 +0200 Subject: [PATCH 1491/1786] removes the additional test phase --- .github/workflows/github-default-actions.yml | 2 +- .github/workflows/github-default-jdk11-actions.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 32ecbbd2b..6c1ed15b5 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -56,7 +56,7 @@ jobs: run: | mvn verify -P compatibility-mode mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode - mvn verify sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode + mvn sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode - name: "Security check" uses: github/codeql-action/analyze@v1 security-check: diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index f40fce8a7..3735fd2b9 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -56,7 +56,7 @@ jobs: run: | mvn verify -P compatibility-mode mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode - mvn verify sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode + mvn sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode security-check: name: "Security check" runs-on: ubuntu-latest From 20694e2fafd38071f3ec005f0ca8ee8385bcd506 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 10:17:00 +0200 Subject: [PATCH 1492/1786] removes the additional test phase --- .github/workflows/github-default-actions.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 6c1ed15b5..ab3f4573e 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -57,8 +57,6 @@ jobs: mvn verify -P compatibility-mode mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode mvn sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode - - name: "Security check" - uses: github/codeql-action/analyze@v1 security-check: name: "Security check" runs-on: ubuntu-latest From 9e6a5afb5c47c7fda10a67e693f0174acac3db1d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 10:18:46 +0200 Subject: [PATCH 1493/1786] simplifies the security check step --- .github/workflows/github-default-actions.yml | 2 +- .github/workflows/github-default-jdk11-actions.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index ab3f4573e..a0c95f700 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -78,6 +78,6 @@ jobs: with: languages: 'java' - run: | - mvn clean verify + mvn clean install -B -DskipTests -P compatibility-mode - name: "Perform Analysis" uses: github/codeql-action/analyze@v1 \ No newline at end of file diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 3735fd2b9..f1dd7827d 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -78,6 +78,6 @@ jobs: with: languages: 'java' - run: | - mvn clean verify + mvn clean install -B -DskipTests -P compatibility-mode - name: "Perform Analysis" uses: github/codeql-action/analyze@v1 \ No newline at end of file From e31785351e0d9a3e0239057c25473a9c4198db5f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 10:20:45 +0200 Subject: [PATCH 1494/1786] adds the maven cache in the security check step --- .github/workflows/github-default-actions.yml | 6 ++++++ .github/workflows/github-default-jdk11-actions.yml | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index a0c95f700..c32d10e92 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -65,6 +65,12 @@ jobs: contents: read security-events: write steps: + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 - name: "JDK set-up" uses: actions/setup-java@v2 with: diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index f1dd7827d..6e9448904 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -65,6 +65,12 @@ jobs: contents: read security-events: write steps: + - name: "Cache Maven repository" + uses: actions/cache@v2.1.6 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 - name: "JDK 11 set-up" uses: actions/setup-java@v2 with: From bf71197e905fcb4d3610a0f24abf2512a84d925d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 21 Jul 2021 10:23:09 +0200 Subject: [PATCH 1495/1786] skip any code check during the security build --- .github/workflows/github-default-actions.yml | 2 +- .github/workflows/github-default-jdk11-actions.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index c32d10e92..a3cb79298 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -84,6 +84,6 @@ jobs: with: languages: 'java' - run: | - mvn clean install -B -DskipTests -P compatibility-mode + mvn clean install -B -DskipTests -P fast - name: "Perform Analysis" uses: github/codeql-action/analyze@v1 \ No newline at end of file diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 6e9448904..73927fb89 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -84,6 +84,6 @@ jobs: with: languages: 'java' - run: | - mvn clean install -B -DskipTests -P compatibility-mode + mvn clean install -B -DskipTests -P fast - name: "Perform Analysis" uses: github/codeql-action/analyze@v1 \ No newline at end of file From b2b34a00dea5617e4e16a8087b1b38dcc6510906 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 23 Jul 2021 15:29:29 +0200 Subject: [PATCH 1496/1786] Modifies the minimum maven version --- .mvn/wrapper/maven-wrapper.properties | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 2feaca7f9..672b84c60 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,4 +1,4 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip wrapper.url=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar # Path where the maven-wrapper.jar will be saved to. diff --git a/pom.xml b/pom.xml index 86162157b..92bfa4156 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ github 3.9.1 - [3.3.9,) + [3.8.1,) 3.0.1 3.3.0 3.1.2 From 5979a4de783528066c9839f9974e21931fa709be Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 23 Jul 2021 15:55:33 +0200 Subject: [PATCH 1497/1786] Modifies the package name --- CHANGELOG-JDK11.md | 27 ++++++--- CHANGELOG-JDK8.md | 18 +++--- CHANGELOG.md | 10 ++++ README.md | 19 +++--- bull-bean-transformer/pom.xml | 8 +-- .../beans/BeanUtils.java | 16 ++--- .../beans/package-info.java | 2 +- .../beans/populator/ArrayPopulator.java | 4 +- .../beans/populator/CollectionPopulator.java | 4 +- .../beans/populator/ICollectionPopulator.java | 2 +- .../beans/populator/MapPopulator.java | 10 ++-- .../beans/populator/OptionalPopulator.java | 4 +- .../beans/populator/Populator.java | 15 +++-- .../beans/populator/PopulatorFactory.java | 4 +- .../beans/populator/package-info.java | 2 +- .../transformer/AbstractBeanTransformer.java | 14 ++--- .../beans/transformer/BeanTransformer.java | 11 ++-- .../beans/transformer/TransformerImpl.java | 26 ++++---- .../beans/transformer/package-info.java | 2 +- .../src/main/resources/logback.xml | 6 +- .../beans/BeanUtilsTest.java | 18 +++--- .../beans/package-info.java | 2 +- .../beans/performance/PerformanceTest.java | 24 ++++---- .../beans/performance/package-info.java | 2 +- .../beans/populator/ArrayPopulatorTest.java | 6 +- .../beans/populator/PopulatorFactoryTest.java | 6 +- .../beans/populator/package-info.java | 2 +- .../AbstractBeanTransformerTest.java | 6 +- .../transformer/BeanTransformerTest.java | 29 ++++----- .../BuilderObjectTransformationTest.java | 10 ++-- .../ImmutableObjectTransformationTest.java | 59 +++++++++---------- .../MixedObjectTransformationTest.java | 20 +++---- .../MutableObjectTransformationTest.java | 30 +++++----- .../RecordObjectTransformationTest.java | 6 +- .../beans/transformer/package-info.java | 2 +- .../src/test/resources/logback-test.xml | 6 +- bull-bom/pom.xml | 10 ++-- bull-common/pom.xml | 4 +- .../transformer/AbstractTransformer.java | 18 +++--- .../transformer/Transformer.java | 6 +- .../annotation/ConstructorArg.java | 2 +- .../transformer/annotation/package-info.java | 2 +- .../transformer/base/Defaults.java | 18 +++--- .../transformer/base/package-info.java | 2 +- .../transformer/cache/CacheManager.java | 2 +- .../cache/CacheManagerFactory.java | 4 +- .../transformer/cache/package-info.java | 2 +- .../transformer/constant/ClassType.java | 2 +- .../transformer/constant/Filters.java | 2 +- .../transformer/constant/MethodPrefix.java | 2 +- .../transformer/constant/Punctuation.java | 2 +- .../transformer/constant/package-info.java | 2 +- .../error/InstanceCreationException.java | 2 +- .../error/InvalidBeanException.java | 2 +- .../error/InvalidFunctionException.java | 2 +- .../error/MissingFieldException.java | 2 +- .../error/MissingMethodException.java | 2 +- .../transformer/error/package-info.java | 2 +- .../transformer/model/EmptyValue.java | 2 +- .../transformer/model/FieldMapping.java | 2 +- .../transformer/model/FieldTransformer.java | 4 +- .../transformer/model/ItemType.java | 2 +- .../transformer/model/MapElemType.java | 2 +- .../transformer/model/MapType.java | 2 +- .../model/TransformerSettings.java | 6 +- .../transformer/model/package-info.java | 2 +- .../transformer/package-info.java | 2 +- .../transformer/utils/ClassUtils.java | 37 ++++++------ .../transformer/utils/ReflectionUtils.java | 26 ++++---- .../transformer/utils/package-info.java | 2 +- .../transformer/validator/Validator.java | 6 +- .../transformer/validator/ValidatorImpl.java | 18 +++--- .../transformer/validator/package-info.java | 2 +- .../beans/package-info.java | 2 +- .../beans/sample/AbstractClass.java | 2 +- .../beans/sample/FromFoo.java | 2 +- .../beans/sample/FromFooAdvFields.java | 4 +- .../beans/sample/FromFooMap.java | 2 +- .../beans/sample/FromFooNoField.java | 2 +- .../sample/FromFooOnlyPrimitiveTypes.java | 2 +- .../beans/sample/FromFooSimple.java | 2 +- .../sample/FromFooSimpleBooleanField.java | 2 +- .../beans/sample/FromFooSimpleNoGetters.java | 2 +- .../beans/sample/FromFooSubClass.java | 2 +- .../sample/FromFooWithPrimitiveFields.java | 2 +- .../beans/sample/FromSubFoo.java | 2 +- .../beans/sample/ISubClass.java | 2 +- .../sample/immutable/ImmutableFlatToFoo.java | 2 +- .../sample/immutable/ImmutableToFoo.java | 2 +- .../immutable/ImmutableToFooAdvFields.java | 6 +- .../ImmutableToFooCustomAnnotation.java | 4 +- .../immutable/ImmutableToFooDiffFields.java | 2 +- .../ImmutableToFooDiffTypesFields.java | 2 +- .../sample/immutable/ImmutableToFooMap.java | 2 +- ...ImmutableToFooMissingCustomAnnotation.java | 4 +- .../ImmutableToFooNoConstructors.java | 2 +- .../ImmutableToFooNotExistingFields.java | 2 +- .../immutable/ImmutableToFooSimple.java | 2 +- .../ImmutableToFooSimpleBoolean.java | 2 +- .../ImmutableToFooSimpleWrongTypes.java | 2 +- .../immutable/ImmutableToFooSubClass.java | 2 +- .../immutable/ImmutableToFooWithBuilder.java | 4 +- .../sample/immutable/ImmutableToSubFoo.java | 4 +- .../ImmutableToSubFooCustomAnnotation.java | 4 +- .../beans/sample/immutable/package-info.java | 2 +- .../beans/sample/mixed/MixedToFoo.java | 4 +- .../sample/mixed/MixedToFooDiffFields.java | 6 +- .../MixedToFooMissingAllArgsConstructor.java | 4 +- .../mixed/MixedToFooMissingConstructor.java | 2 +- .../sample/mixed/MixedToFooMissingField.java | 2 +- .../mixed/MixedToFooNotExistingFields.java | 2 +- .../sample/mixed/MixedToFooStaticField.java | 2 +- .../sample/mixed/MixedToFooWithBuilder.java | 4 +- .../mixed/MutableToFooOnlyPrimitiveTypes.java | 2 +- .../beans/sample/mixed/package-info.java | 2 +- .../beans/sample/mutable/MutableToFoo.java | 2 +- .../sample/mutable/MutableToFooAdvFields.java | 6 +- .../sample/mutable/MutableToFooInvalid.java | 2 +- .../MutableToFooNotExistingFields.java | 2 +- .../sample/mutable/MutableToFooSimple.java | 2 +- .../mutable/MutableToFooSimpleNoSetters.java | 2 +- .../sample/mutable/MutableToFooSubClass.java | 2 +- .../mutable/MutableToFooWithBuilder.java | 2 +- ...leToFooWithBuilderMultipleConstructor.java | 2 +- .../mutable/MutableToFooWithWrongBuilder.java | 2 +- .../beans/sample/mutable/MutableToSubFoo.java | 4 +- .../beans/sample/mutable/package-info.java | 2 +- .../beans/sample/package-info.java | 2 +- .../beans/sample/record/FromFooRecord.java | 2 +- .../beans/sample/record/RecordToFoo.java | 2 +- .../transformer/AbstractTransformerTest.java | 27 ++++----- .../transformer/base/DefaultsTest.java | 4 +- .../transformer/base/package-info.java | 2 +- .../cache/CacheManagerFactoryTest.java | 2 +- .../transformer/cache/CacheManagerTest.java | 2 +- .../transformer/cache/package-info.java | 2 +- .../transformer/package-info.java | 2 +- .../transformer/utils/ClassUtilsTest.java | 52 ++++++++-------- .../utils/ReflectionUtilsTest.java | 48 ++++++++------- .../transformer/utils/package-info.java | 2 +- .../transformer/validator/ValidatorTest.java | 6 +- .../transformer/validator/package-info.java | 2 +- .../src/test/resources/logback-test.xml | 6 +- bull-converter/pom.xml | 6 +- .../beans/conversion/Converter.java | 8 ++- .../beans/conversion/ConverterImpl.java | 8 +-- .../analyzer/ConversionAnalyzer.java | 38 ++++++------ .../conversion/analyzer/package-info.java | 2 +- .../error/TypeConversionException.java | 2 +- .../beans/conversion/error/package-info.java | 2 +- .../beans/conversion/package-info.java | 2 +- .../processor/ConversionProcessor.java | 6 +- .../processor/ConversionProcessorFactory.java | 50 ++++++++-------- .../impl/BigDecimalConversionProcessor.java | 6 +- .../impl/BigIntegerConversionProcessor.java | 6 +- .../impl/BooleanConversionProcessor.java | 4 +- .../impl/ByteArrayConversionProcessor.java | 4 +- .../impl/ByteConversionProcessor.java | 4 +- .../impl/CharacterConversionProcessor.java | 6 +- .../impl/DoubleConversionProcessor.java | 6 +- .../impl/FloatConversionProcessor.java | 6 +- .../impl/IntegerConversionProcessor.java | 6 +- .../impl/LongConversionProcessor.java | 6 +- .../impl/ShortConversionProcessor.java | 6 +- .../impl/StringConversionProcessor.java | 4 +- .../processor/impl/package-info.java | 2 +- .../conversion/processor/package-info.java | 2 +- .../conversion/AbstractConversionTest.java | 2 +- .../beans/conversion/ConverterTest.java | 25 ++++---- .../analyzer/ConversionAnalyzerTest.java | 25 ++++---- .../conversion/analyzer/package-info.java | 2 +- .../beans/conversion/package-info.java | 2 +- .../ConversionProcessorFactoryTest.java | 32 +++++----- .../impl/BigDecimalConversionTest.java | 6 +- .../impl/BigIntegerConversionTest.java | 6 +- .../processor/impl/BooleanConversionTest.java | 4 +- .../impl/ByteArrayConversionTest.java | 4 +- .../processor/impl/ByteConversionTest.java | 4 +- .../impl/CharacterConversionTest.java | 6 +- .../processor/impl/DoubleConversionTest.java | 6 +- .../processor/impl/FloatConversionTest.java | 6 +- .../processor/impl/IntegerConversionTest.java | 6 +- .../processor/impl/LongConversionTest.java | 6 +- .../processor/impl/ShortConversionTest.java | 6 +- .../processor/impl/StringConversionTest.java | 4 +- .../processor/impl/package-info.java | 2 +- .../conversion/processor/package-info.java | 2 +- bull-map-transformer/pom.xml | 8 +-- .../map/MapUtils.java | 6 +- .../map/package-info.java | 2 +- .../transformer/AbstractMapTransformer.java | 10 ++-- .../map/transformer/MapTransformer.java | 8 +-- .../map/transformer/MapTransformerImpl.java | 12 ++-- .../model/MapTransformerSettings.java | 6 +- .../map/transformer/model/package-info.java | 2 +- .../map/transformer/package-info.java | 2 +- .../src/main/resources/logback.xml | 6 +- .../map/MapUtilsTest.java | 4 +- .../map/package-info.java | 2 +- .../map/transformer/MapTransformerTest.java | 22 +++---- .../map/transformer/package-info.java | 2 +- .../test/resources/config/logback-test.xml | 6 +- bull-report/pom.xml | 12 ++-- docs/site/markdown/kotlin.md | 2 +- .../site/markdown/transformer/bean/builder.md | 4 +- .../site/markdown/transformer/bean/samples.md | 3 +- .../site/markdown/transformer/bean/testing.md | 14 ++--- .../markdown/transformer/mapTransformer.md | 2 +- pom.xml | 10 ++-- 209 files changed, 730 insertions(+), 705 deletions(-) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/BeanUtils.java (85%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/package-info.java (95%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/populator/ArrayPopulator.java (95%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/populator/CollectionPopulator.java (96%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/populator/ICollectionPopulator.java (97%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/populator/MapPopulator.java (93%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/populator/OptionalPopulator.java (94%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/populator/Populator.java (89%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/populator/PopulatorFactory.java (95%) rename bull-bean-transformer/src/{test/java/com/hotels => main/java/com/expediagroup}/beans/populator/package-info.java (93%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/transformer/AbstractBeanTransformer.java (92%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/transformer/BeanTransformer.java (92%) rename bull-bean-transformer/src/main/java/com/{hotels => expediagroup}/beans/transformer/TransformerImpl.java (97%) rename bull-bean-transformer/src/{test/java/com/hotels => main/java/com/expediagroup}/beans/transformer/package-info.java (93%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/BeanUtilsTest.java (90%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/package-info.java (95%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/performance/PerformanceTest.java (92%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/performance/package-info.java (93%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/populator/ArrayPopulatorTest.java (96%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/populator/PopulatorFactoryTest.java (94%) rename bull-bean-transformer/src/{main/java/com/hotels => test/java/com/expediagroup}/beans/populator/package-info.java (93%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/transformer/AbstractBeanTransformerTest.java (89%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/transformer/BeanTransformerTest.java (96%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/transformer/BuilderObjectTransformationTest.java (89%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/transformer/ImmutableObjectTransformationTest.java (92%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/transformer/MixedObjectTransformationTest.java (91%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/transformer/MutableObjectTransformationTest.java (94%) rename bull-bean-transformer/src/test/java/com/{hotels => expediagroup}/beans/transformer/RecordObjectTransformationTest.java (91%) rename bull-bean-transformer/src/{main/java/com/hotels => test/java/com/expediagroup}/beans/transformer/package-info.java (93%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/AbstractTransformer.java (89%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/Transformer.java (92%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/annotation/ConstructorArg.java (97%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/annotation/package-info.java (92%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/base/Defaults.java (70%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/base/package-info.java (93%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/cache/CacheManager.java (98%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/cache/CacheManagerFactory.java (92%) rename bull-common/src/{test/java/com/hotels => main/java/com/expediagroup}/transformer/cache/package-info.java (93%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/constant/ClassType.java (96%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/constant/Filters.java (97%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/constant/MethodPrefix.java (95%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/constant/Punctuation.java (96%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/constant/package-info.java (93%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/error/InstanceCreationException.java (96%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/error/InvalidBeanException.java (97%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/error/InvalidFunctionException.java (96%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/error/MissingFieldException.java (96%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/error/MissingMethodException.java (97%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/error/package-info.java (93%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/model/EmptyValue.java (94%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/model/FieldMapping.java (95%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/model/FieldTransformer.java (96%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/model/ItemType.java (96%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/model/MapElemType.java (94%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/model/MapType.java (94%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/model/TransformerSettings.java (95%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/model/package-info.java (93%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/package-info.java (94%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/utils/ClassUtils.java (96%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/utils/ReflectionUtils.java (97%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/utils/package-info.java (93%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/validator/Validator.java (92%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/validator/ValidatorImpl.java (85%) rename bull-common/src/main/java/com/{hotels => expediagroup}/transformer/validator/package-info.java (92%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/package-info.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/AbstractClass.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFoo.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFooAdvFields.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFooMap.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFooNoField.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFooOnlyPrimitiveTypes.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFooSimple.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFooSimpleBooleanField.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFooSimpleNoGetters.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFooSubClass.java (97%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromFooWithPrimitiveFields.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/FromSubFoo.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/ISubClass.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableFlatToFoo.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFoo.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooAdvFields.java (90%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooCustomAnnotation.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooDiffFields.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooDiffTypesFields.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooMap.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java (91%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooNoConstructors.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooNotExistingFields.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooSimple.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooSimpleBoolean.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooSubClass.java (97%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToFooWithBuilder.java (93%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToSubFoo.java (91%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java (93%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/immutable/package-info.java (92%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/MixedToFoo.java (91%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/MixedToFooDiffFields.java (90%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java (91%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/MixedToFooMissingConstructor.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/MixedToFooMissingField.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/MixedToFooNotExistingFields.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/MixedToFooStaticField.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/MixedToFooWithBuilder.java (92%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mixed/package-info.java (93%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFoo.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFooAdvFields.java (90%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFooInvalid.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFooNotExistingFields.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFooSimple.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFooSimpleNoSetters.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFooSubClass.java (95%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFooWithBuilder.java (97%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java (97%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToFooWithWrongBuilder.java (97%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/MutableToSubFoo.java (91%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/mutable/package-info.java (93%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/package-info.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/record/FromFooRecord.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/beans/sample/record/RecordToFoo.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/AbstractTransformerTest.java (90%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/base/DefaultsTest.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/base/package-info.java (93%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/cache/CacheManagerFactoryTest.java (97%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/cache/CacheManagerTest.java (98%) rename bull-common/src/{main/java/com/hotels => test/java/com/expediagroup}/transformer/cache/package-info.java (93%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/package-info.java (94%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/utils/ClassUtilsTest.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/utils/ReflectionUtilsTest.java (96%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/utils/package-info.java (93%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/validator/ValidatorTest.java (97%) rename bull-common/src/test/java/com/{hotels => expediagroup}/transformer/validator/package-info.java (93%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/Converter.java (88%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/ConverterImpl.java (89%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/analyzer/ConversionAnalyzer.java (77%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/analyzer/package-info.java (92%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/error/TypeConversionException.java (95%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/error/package-info.java (92%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/package-info.java (93%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/ConversionProcessor.java (92%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/ConversionProcessorFactory.java (59%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/BigDecimalConversionProcessor.java (94%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/BigIntegerConversionProcessor.java (94%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/BooleanConversionProcessor.java (95%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/ByteArrayConversionProcessor.java (95%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/ByteConversionProcessor.java (95%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/CharacterConversionProcessor.java (94%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/DoubleConversionProcessor.java (93%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/FloatConversionProcessor.java (93%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/IntegerConversionProcessor.java (93%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/LongConversionProcessor.java (93%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/ShortConversionProcessor.java (93%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/StringConversionProcessor.java (95%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/package-info.java (91%) rename bull-converter/src/main/java/com/{hotels => expediagroup}/beans/conversion/processor/package-info.java (92%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/AbstractConversionTest.java (97%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/ConverterTest.java (97%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/analyzer/ConversionAnalyzerTest.java (87%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/analyzer/package-info.java (92%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/package-info.java (93%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/ConversionProcessorFactoryTest.java (83%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/BigDecimalConversionTest.java (96%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/BigIntegerConversionTest.java (96%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/BooleanConversionTest.java (99%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/ByteArrayConversionTest.java (98%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/ByteConversionTest.java (97%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/CharacterConversionTest.java (96%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/DoubleConversionTest.java (96%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/FloatConversionTest.java (96%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/IntegerConversionTest.java (96%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/LongConversionTest.java (96%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/ShortConversionTest.java (96%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/StringConversionTest.java (97%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/impl/package-info.java (92%) rename bull-converter/src/test/java/com/{hotels => expediagroup}/beans/conversion/processor/package-info.java (92%) rename bull-map-transformer/src/main/java/com/{hotels => expediagroup}/map/MapUtils.java (85%) rename bull-map-transformer/src/main/java/com/{hotels => expediagroup}/map/package-info.java (95%) rename bull-map-transformer/src/main/java/com/{hotels => expediagroup}/map/transformer/AbstractMapTransformer.java (90%) rename bull-map-transformer/src/main/java/com/{hotels => expediagroup}/map/transformer/MapTransformer.java (95%) rename bull-map-transformer/src/main/java/com/{hotels => expediagroup}/map/transformer/MapTransformerImpl.java (93%) rename bull-map-transformer/src/main/java/com/{hotels => expediagroup}/map/transformer/model/MapTransformerSettings.java (89%) rename bull-map-transformer/src/main/java/com/{hotels => expediagroup}/map/transformer/model/package-info.java (92%) rename bull-map-transformer/src/main/java/com/{hotels => expediagroup}/map/transformer/package-info.java (93%) rename bull-map-transformer/src/test/java/com/{hotels => expediagroup}/map/MapUtilsTest.java (94%) rename bull-map-transformer/src/test/java/com/{hotels => expediagroup}/map/package-info.java (95%) rename bull-map-transformer/src/test/java/com/{hotels => expediagroup}/map/transformer/MapTransformerTest.java (93%) rename bull-map-transformer/src/test/java/com/{hotels => expediagroup}/map/transformer/package-info.java (93%) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index 8f6951aa8..1c9016f02 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -2,12 +2,22 @@ All notable changes to this project will be documented in this file. +### [2.0.0-jdk11] 2021.07.23 + +#### Adds + +* Renames the package from `com.hotels` to `com.expediagroup` + ### [1.7.7] 2021.06.23 + #### Changed + * Fixes an issue that was preventing the transformation of Object type fields ### [1.7.6] 2021.01.11 + #### Added + * Provides new module `bull-bom` that includes all the project modules ### [1.7.4] 2020.10.07 @@ -69,11 +79,12 @@ All notable changes to this project will be documented in this file. ### [1.6.0.2] 2019.10.30 ### Removed + * Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` * The following deprecated classes has been removed: - * `com.hotels.beans.model.FieldMapping` - * `com.hotels.beans.model.FieldTransformer` - * `com.hotels.beans.Transformer` + * `com.expediagroup.beans.model.FieldMapping` + * `com.expediagroup.beans.model.FieldTransformer` + * `com.expediagroup.beans.Transformer` ### Added * New specific exception in case the Field Transformation function defined is not valid * Implemented a new functionality that allows to transform also Map object applying transformation function and mappings @@ -86,7 +97,7 @@ All notable changes to this project will be documented in this file. * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.6.0`, use `bull-bean-transformer` instead.** ```xml - com.hotels.beans + com.expediagroup.beans bull-bean-transformer x.y.z @@ -95,10 +106,10 @@ All notable changes to this project will be documented in this file. * The following classes has been deprecated, please find below the complete list and the new one to be used: | Deprecated | **New one** | - | :----------- | :----------- | - | `com.hotels.beans.model.FieldMapping` | `com.hotels.transformer.model.FieldMapping` | - | `com.hotels.beans.model.FieldTransformer` | `com.hotels.transformer.model.FieldTransformer` | - | `com.hotels.beans.Transformer` | `com.hotels.transformer.Transformer` | + | :----------- | :----------- | + | `com.expediagroup.beans.model.FieldMapping` | `FieldMapping` | + | `com.expediagroup.beans.model.FieldTransformer` | `FieldTransformer` | + | `com.expediagroup.beans.Transformer` | `Transformer` | ### [1.5.0] 2019.08.06 #### Added diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index a07f0c9ab..1e1b65771 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -71,9 +71,9 @@ All notable changes to this project will be documented in this file. ### Removed * Removed deprecated module `bean-utils-library`, the new one is: `bean-bean-transformer` * The following deprecated classes has been removed: - * `com.hotels.beans.model.FieldMapping` - * `com.hotels.beans.model.FieldTransformer` - * `com.hotels.beans.Transformer` + * `com.expediagroup.beans.model.FieldMapping` + * `com.expediagroup.beans.model.FieldTransformer` + * `com.expediagroup.beans.Transformer` ### Added * New specific exception in case the Field Transformation function defined is not valid * Implemented a new functionality that allows to transform also Map object applying transformation function and mappings @@ -87,7 +87,7 @@ All notable changes to this project will be documented in this file. * **The module `bean-utils-library` has been deprecated and will be no longer available since version `1.1.25`, use `bull-bean-transformer` instead.** ```xml - com.hotels.beans + com.expediagroup.beans bull-bean-transformer x.y.z @@ -95,11 +95,11 @@ All notable changes to this project will be documented in this file. * Module `bean-utils-library` has been relocated into `bull-bean-transformer`. * The following classes has been deprecated, please find below the complete list and the new one to be used: - | Deprecated | **New one** | - | :----------- | :----------- | - | `com.hotels.beans.model.FieldMapping` | `com.hotels.transformer.model.FieldMapping` | - | `com.hotels.beans.model.FieldTransformer` | `com.hotels.transformer.model.FieldTransformer` | - | `com.hotels.beans.Transformer` | `com.hotels.transformer.Transformer` | + | Deprecated | **New one** | + | :----------- | :----------- | + | `com.expediagroup.beans.model.FieldMapping` | `FieldMapping` | + | `com.expediagroup.beans.model.FieldTransformer` | `FieldTransformer` | + | `com.expediagroup.beans.Transformer` | `Transformer` | ### [1.1.23] 2019.08.06 #### Added diff --git a/CHANGELOG.md b/CHANGELOG.md index 99b85d9c4..230704864 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,22 @@ All notable changes to this project will be documented in this file. +### [2.1.0] 2021.07.23 + +#### Adds + +* Renames the package from `com.hotels` to `com.expediagroup` + ### [2.0.1.1] 2021.06.24 + #### Adds + * Adds the javadoc generation to the release ### [2.0.1] 2021.06.23 + #### Changed + * Fixes an issue that was preventing the transformation of Object type fields ### [2.0.0] 2021.06.18 diff --git a/README.md b/README.md index 6f643edd5..49a06f887 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho ## Start using -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer/badge.svg?subject=maven-central&color=blue)](https://maven-badges.herokuapp.com/maven-central/com.hotels.beans/bull-bean-transformer) -[![Javadocs](http://www.javadoc.io/badge/com.hotels.beans/bull-bean-transformer.svg?color=blue)](http://www.javadoc.io/doc/com.hotels.beans/bull-bean-transformer) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.expediagroup.beans/bull-bean-transformer/badge.svg?subject=maven-central&color=blue)](https://maven-badges.herokuapp.com/maven-central/com.expediagroup.beans/bull-bean-transformer) +[![Javadocs](http://www.javadoc.io/badge/com.expediagroup.beans/bull-bean-transformer.svg?color=blue)](http://www.javadoc.io/doc/com.expediagroup.beans/bull-bean-transformer) [![Build Status](https://github.com/ExpediaGroup/bull/actions/workflows/github-default-actions.yml/badge.svg?branch=master)](https://github.com/ExpediaGroup/bull/actions) [![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) @@ -26,8 +26,9 @@ All BULL modules are available on Maven Central: It contains all the modules available in the project ```xml + - com.hotels.beans + com.expediagroup.beans bull-bom x.y.z @@ -36,8 +37,9 @@ It contains all the modules available in the project * ### Bean Transformer ```xml + - com.hotels.beans + com.expediagroup.beans bull-bean-transformer x.y.z @@ -46,8 +48,9 @@ It contains all the modules available in the project * ### `Map` Transformer ```xml + - com.hotels.beans + com.expediagroup.beans bull-map-transformer x.y.z @@ -677,7 +680,7 @@ public class ItemType { return this; } - public com.hotels.transformer.model.ItemType build() { + public ItemType build() { return new ItemType(this.objectClass, this.genericClass); } } @@ -721,7 +724,7 @@ public class ItemType { return this; } - public com.hotels.transformer.model.ItemType build() { + public ItemType build() { return new ItemType(this); } } @@ -754,7 +757,7 @@ var toBean = beanUtils.getTransformer().transform(fromBean, RecordToFoo.class); * the class's fields that have to be copied must not be static -More sample beans can be found in the test package: `com.hotels.beans.sample` +More sample beans can be found in the test package: `com.expediagroup.beans.sample` ## Third-party library comparison diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 620929f22..e16f87b69 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -6,20 +6,20 @@ jar - com.hotels.beans + com.expediagroup.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT - com.hotels.beans + com.expediagroup.beans bull-converter ${project.version} - com.hotels.beans + com.expediagroup.beans bull-common ${project.version} test-jar diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java similarity index 85% rename from bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java index f414391a4..8a1ca0485 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans; +package com.expediagroup.beans; -import static com.hotels.transformer.validator.Validator.notNull; +import static com.expediagroup.transformer.validator.Validator.notNull; import java.util.function.Function; -import com.hotels.beans.conversion.Converter; -import com.hotels.beans.conversion.ConverterImpl; -import com.hotels.beans.transformer.BeanTransformer; -import com.hotels.beans.transformer.TransformerImpl; -import com.hotels.transformer.validator.Validator; -import com.hotels.transformer.validator.ValidatorImpl; +import com.expediagroup.beans.conversion.Converter; +import com.expediagroup.beans.conversion.ConverterImpl; +import com.expediagroup.beans.transformer.BeanTransformer; +import com.expediagroup.beans.transformer.TransformerImpl; +import com.expediagroup.transformer.validator.Validator; +import com.expediagroup.transformer.validator.ValidatorImpl; /** * Set of Bean utilities. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java similarity index 95% rename from bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java index fd4196d47..2f247262c 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java @@ -16,4 +16,4 @@ /** * Bean transformer main package. */ -package com.hotels.beans; +package com.expediagroup.beans; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java similarity index 95% rename from bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java index 9e39e3c88..ebc087bdd 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; import static java.util.Arrays.stream; import java.lang.reflect.Field; -import com.hotels.beans.transformer.BeanTransformer; +import com.expediagroup.beans.transformer.BeanTransformer; /** * Populator for primitive types array. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java similarity index 96% rename from bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java index 29f6d66f6..52c66ab6b 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/CollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; import static java.util.Objects.isNull; import static java.util.stream.Collectors.toList; @@ -24,7 +24,7 @@ import java.util.Set; import java.util.stream.Collector; -import com.hotels.beans.transformer.BeanTransformer; +import com.expediagroup.beans.transformer.BeanTransformer; /** * Populator for Collections types object {@link java.util.Collections}. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java similarity index 97% rename from bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java index 3d0164a30..247b6cf2b 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/ICollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; /** * Interface class containing the methods needed for the collection related object types. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java similarity index 93% rename from bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java index c444fc5a9..39de10f70 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java @@ -13,17 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; import static java.util.stream.Collectors.toMap; import java.lang.reflect.Field; import java.util.Map; -import com.hotels.beans.transformer.BeanTransformer; -import com.hotels.transformer.model.ItemType; -import com.hotels.transformer.model.MapElemType; -import com.hotels.transformer.model.MapType; +import com.expediagroup.beans.transformer.BeanTransformer; +import com.expediagroup.transformer.model.ItemType; +import com.expediagroup.transformer.model.MapElemType; +import com.expediagroup.transformer.model.MapType; /** * Populator for Map types object {@link Map}. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java similarity index 94% rename from bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java index 0a25446ef..3134dab32 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; import static java.util.Optional.ofNullable; import java.lang.reflect.Field; import java.util.Optional; -import com.hotels.beans.transformer.BeanTransformer; +import com.expediagroup.beans.transformer.BeanTransformer; /** * Populator for {@link Optional} type. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java similarity index 89% rename from bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java index 5e02e5e41..d388ec054 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java @@ -13,16 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.populator; - -import static com.hotels.beans.populator.PopulatorFactory.getPopulator; +package com.expediagroup.beans.populator; import java.lang.reflect.Field; import java.util.Optional; -import com.hotels.beans.transformer.BeanTransformer; -import com.hotels.transformer.utils.ClassUtils; -import com.hotels.transformer.utils.ReflectionUtils; +import com.expediagroup.beans.BeanUtils; +import com.expediagroup.beans.transformer.BeanTransformer; +import com.expediagroup.transformer.utils.ClassUtils; +import com.expediagroup.transformer.utils.ReflectionUtils; /** * Populator for collection or map objects. @@ -75,7 +74,7 @@ public final O getPopulatedObject(final Class targetClass, final String f } /** - * Wrapper method for {@link com.hotels.beans.BeanUtils} transform method. + * Wrapper method for {@link BeanUtils} transform method. * @param sourceObj the source object * @param targetClass the destination object class * @param the Source object type @@ -102,7 +101,7 @@ final K transform(final T sourceObj, final Class targetClass, final Cl if (classUtils.isPrimitiveOrSpecialType(sourceObj.getClass())) { res = (K) sourceObj; } else { - final Optional optPopulator = getPopulator(targetClass, sourceObj.getClass(), transformer); + final Optional optPopulator = PopulatorFactory.getPopulator(targetClass, sourceObj.getClass(), transformer); res = (K) optPopulator .map(populator -> ((ICollectionPopulator) populator).getPopulatedObject(targetClass, targetClass, sourceObj, nestedGenericClass)) .orElseGet(() -> transformer.transform(sourceObj, targetClass)); diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java similarity index 95% rename from bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java index 1f0f3a08e..323970b41 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/PopulatorFactory.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; import static java.util.Optional.empty; import static java.util.Optional.of; @@ -24,7 +24,7 @@ import java.util.Map; import java.util.Optional; -import com.hotels.beans.transformer.BeanTransformer; +import com.expediagroup.beans.transformer.BeanTransformer; import lombok.NoArgsConstructor; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java similarity index 93% rename from bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java index ac5c3a4c8..1e14f7cef 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java @@ -16,4 +16,4 @@ /** * Populator objects package. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java similarity index 92% rename from bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java index 303d7aa09..5e413df94 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java @@ -13,17 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; import static java.util.Arrays.asList; -import static com.hotels.transformer.validator.Validator.notNull; +import static com.expediagroup.transformer.validator.Validator.notNull; -import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; -import com.hotels.transformer.AbstractTransformer; -import com.hotels.transformer.model.TransformerSettings; -import com.hotels.transformer.validator.Validator; -import com.hotels.transformer.validator.ValidatorImpl; +import com.expediagroup.beans.conversion.analyzer.ConversionAnalyzer; +import com.expediagroup.transformer.AbstractTransformer; +import com.expediagroup.transformer.model.TransformerSettings; +import com.expediagroup.transformer.validator.Validator; +import com.expediagroup.transformer.validator.ValidatorImpl; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java similarity index 92% rename from bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java index 64effed6b..146d48ba4 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; -import com.hotels.transformer.Transformer; +import com.expediagroup.transformer.Transformer; +import com.expediagroup.transformer.error.MissingFieldException; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. @@ -45,9 +46,9 @@ public interface BeanTransformer extends Transformer { /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. - * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. + * If set to true the default value is set, if false if it raises a: {@link MissingFieldException} in case of missing fields. * @param useDefaultValue true in case the default value should be set, false if it should raise a: - * {@link com.hotels.transformer.error.MissingFieldException} in case of missing field. + * {@link MissingFieldException} in case of missing field. * @return the {@link BeanTransformer} instance */ BeanTransformer setDefaultValueForMissingField(boolean useDefaultValue); @@ -61,7 +62,7 @@ public interface BeanTransformer extends Transformer { /** * It allows to configure the transformer in order to apply a transformation function on all fields matching the given name without keeping in consideration their full path. - * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. + * If set to true the default value is set, if false if it raises a: {@link MissingFieldException} in case of missing fields. * @param useFlatTransformation indicates if the transformer function has to be performed on all fields matching the given name without keeping in consideration their full * path. * @return the {@link BeanTransformer} instance diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java similarity index 97% rename from bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java index 110e8a67e..2b1959630 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; import static java.util.Arrays.stream; import static java.util.Objects.isNull; @@ -26,14 +26,14 @@ import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static com.hotels.beans.populator.PopulatorFactory.getPopulator; -import static com.hotels.transformer.base.Defaults.defaultValue; -import static com.hotels.transformer.constant.ClassType.MIXED; -import static com.hotels.transformer.constant.ClassType.MUTABLE; -import static com.hotels.transformer.constant.Punctuation.COMMA; -import static com.hotels.transformer.constant.Punctuation.DOT; -import static com.hotels.transformer.constant.Punctuation.LPAREN; -import static com.hotels.transformer.constant.Punctuation.RPAREN; +import static com.expediagroup.beans.populator.PopulatorFactory.getPopulator; +import static com.expediagroup.transformer.base.Defaults.defaultValue; +import static com.expediagroup.transformer.constant.ClassType.MIXED; +import static com.expediagroup.transformer.constant.ClassType.MUTABLE; +import static com.expediagroup.transformer.constant.Punctuation.COMMA; +import static com.expediagroup.transformer.constant.Punctuation.DOT; +import static com.expediagroup.transformer.constant.Punctuation.LPAREN; +import static com.expediagroup.transformer.constant.Punctuation.RPAREN; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -42,10 +42,10 @@ import java.util.Optional; import java.util.function.Consumer; -import com.hotels.transformer.annotation.ConstructorArg; -import com.hotels.transformer.error.InvalidBeanException; -import com.hotels.transformer.error.MissingFieldException; -import com.hotels.transformer.model.FieldTransformer; +import com.expediagroup.transformer.annotation.ConstructorArg; +import com.expediagroup.transformer.error.InvalidBeanException; +import com.expediagroup.transformer.error.MissingFieldException; +import com.expediagroup.transformer.model.FieldTransformer; /** * Utility methods for populating Mutable, Immutable and Hybrid JavaBeans properties via reflection. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java similarity index 93% rename from bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java rename to bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java index dec4cd967..5d8b45b2f 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java @@ -16,4 +16,4 @@ /** * Bean transformer package. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; diff --git a/bull-bean-transformer/src/main/resources/logback.xml b/bull-bean-transformer/src/main/resources/logback.xml index 25d935bb3..7f3fe5d81 100644 --- a/bull-bean-transformer/src/main/resources/logback.xml +++ b/bull-bean-transformer/src/main/resources/logback.xml @@ -31,9 +31,9 @@ - - - + + + diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java similarity index 90% rename from bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java index 914cdfc60..f06cebc32 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans; +package com.expediagroup.beans; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.openMocks; @@ -29,13 +29,13 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.Converter; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.immutable.ImmutableToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooSimple; -import com.hotels.beans.transformer.BeanTransformer; -import com.hotels.transformer.error.InvalidBeanException; +import com.expediagroup.beans.conversion.Converter; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.immutable.ImmutableToFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; +import com.expediagroup.beans.sample.immutable.ImmutableToFooSimple; +import com.expediagroup.beans.transformer.BeanTransformer; +import com.expediagroup.transformer.error.InvalidBeanException; /** * Unit test for {@link BeanUtils}. @@ -149,7 +149,7 @@ public void testValidateThrowsExceptionIfTheGivenBeanIsInvalid() { } /** - * Test that a {@link com.hotels.beans.conversion.Converter} is correctly returned. + * Test that a {@link Converter} is correctly returned. */ @Test public void testGetPrimitiveTypeConverterWorksProperly() { diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/package-info.java similarity index 95% rename from bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/package-info.java index 0d9a9f245..552bfb1f8 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/package-info.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/package-info.java @@ -16,4 +16,4 @@ /** * Test package. */ -package com.hotels.beans; +package com.expediagroup.beans; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/performance/PerformanceTest.java similarity index 92% rename from bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/performance/PerformanceTest.java index 64e30cefb..5f1c2b8e7 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/PerformanceTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/performance/PerformanceTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.performance; +package com.expediagroup.beans.performance; import static java.lang.String.valueOf; import static java.lang.Thread.sleep; @@ -37,17 +37,17 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.BeanUtils; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSubClass; -import com.hotels.beans.sample.FromSubFoo; -import com.hotels.beans.sample.immutable.ImmutableToFooSimple; -import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.beans.sample.mixed.MixedToFoo; -import com.hotels.beans.sample.mutable.MutableToFooSimple; -import com.hotels.beans.sample.mutable.MutableToFooSubClass; -import com.hotels.beans.transformer.BeanTransformer; +import com.expediagroup.beans.BeanUtils; +import com.expediagroup.beans.sample.FromFoo; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.FromFooSubClass; +import com.expediagroup.beans.sample.FromSubFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToFooSimple; +import com.expediagroup.beans.sample.immutable.ImmutableToFooSubClass; +import com.expediagroup.beans.sample.mixed.MixedToFoo; +import com.expediagroup.beans.sample.mutable.MutableToFooSimple; +import com.expediagroup.beans.sample.mutable.MutableToFooSubClass; +import com.expediagroup.beans.transformer.BeanTransformer; import lombok.extern.slf4j.Slf4j; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/performance/package-info.java similarity index 93% rename from bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/performance/package-info.java index 1500243ac..f38fa2647 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/performance/package-info.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/performance/package-info.java @@ -16,4 +16,4 @@ /** * Performance test package. */ -package com.hotels.beans.performance; +package com.expediagroup.beans.performance; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/populator/ArrayPopulatorTest.java similarity index 96% rename from bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/populator/ArrayPopulatorTest.java index b89818b2e..6cf9d059c 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/ArrayPopulatorTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/populator/ArrayPopulatorTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; @@ -30,8 +30,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.mixed.MixedToFooStaticField; -import com.hotels.beans.transformer.BeanTransformer; +import com.expediagroup.beans.sample.mixed.MixedToFooStaticField; +import com.expediagroup.beans.transformer.BeanTransformer; /** * Unit test for class: {@link ArrayPopulator}. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/populator/PopulatorFactoryTest.java similarity index 94% rename from bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/populator/PopulatorFactoryTest.java index 658ad838f..47a87e904 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/populator/PopulatorFactoryTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/populator/PopulatorFactoryTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; import static java.util.Objects.nonNull; @@ -30,8 +30,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.transformer.BeanTransformer; +import com.expediagroup.beans.sample.FromFoo; +import com.expediagroup.beans.transformer.BeanTransformer; /** * Unit test for class: {@link PopulatorFactory}. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/populator/package-info.java similarity index 93% rename from bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/populator/package-info.java index ac5c3a4c8..1e14f7cef 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/populator/package-info.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/populator/package-info.java @@ -16,4 +16,4 @@ /** * Populator objects package. */ -package com.hotels.beans.populator; +package com.expediagroup.beans.populator; diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/AbstractBeanTransformerTest.java similarity index 89% rename from bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/AbstractBeanTransformerTest.java index ddfbd4869..b6af0607b 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/AbstractBeanTransformerTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; import static org.mockito.MockitoAnnotations.openMocks; @@ -21,8 +21,8 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; -import com.hotels.transformer.AbstractTransformerTest; -import com.hotels.transformer.utils.ReflectionUtils; +import com.expediagroup.transformer.AbstractTransformerTest; +import com.expediagroup.transformer.utils.ReflectionUtils; /** * Unit test for {@link BeanTransformer}. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java similarity index 96% rename from bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java index 51112976a..4a6ac4e4a 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; import static java.math.BigInteger.ZERO; import static java.util.Optional.empty; @@ -38,18 +38,19 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.mutable.MutableToFoo; -import com.hotels.beans.sample.mutable.MutableToFooAdvFields; -import com.hotels.transformer.cache.CacheManager; -import com.hotels.transformer.error.InvalidBeanException; -import com.hotels.transformer.error.MissingFieldException; -import com.hotels.transformer.model.FieldMapping; -import com.hotels.transformer.model.FieldTransformer; -import com.hotels.transformer.model.TransformerSettings; -import com.hotels.transformer.utils.ClassUtils; -import com.hotels.transformer.utils.ReflectionUtils; +import com.expediagroup.beans.conversion.analyzer.ConversionAnalyzer; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.mutable.MutableToFoo; +import com.expediagroup.beans.sample.mutable.MutableToFooAdvFields; +import com.expediagroup.transformer.cache.CacheManager; +import com.expediagroup.transformer.error.InvalidBeanException; +import com.expediagroup.transformer.error.MissingFieldException; +import com.expediagroup.transformer.model.FieldMapping; +import com.expediagroup.transformer.model.FieldTransformer; +import com.expediagroup.transformer.model.TransformerSettings; +import com.expediagroup.transformer.utils.ClassUtils; +import com.expediagroup.transformer.utils.ReflectionUtils; +import com.expediagroup.transformer.validator.Validator; /** * Unit test for class: {@link BeanTransformer}. @@ -426,7 +427,7 @@ private void restoreUnderTestObject() { } /** - * Tests that an instance fo {@link com.hotels.transformer.validator.Validator} is created only if the validation is enabled. + * Tests that an instance fo {@link Validator} is created only if the validation is enabled. * @param testCaseDescription the test case description * @param validationEnabled true if the validation is enabled, false otherwise * @param expectedNull the expected result diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BuilderObjectTransformationTest.java similarity index 89% rename from bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BuilderObjectTransformationTest.java index 02665713c..d6d74b25a 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/BuilderObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BuilderObjectTransformationTest.java @@ -13,17 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; import static org.assertj.core.api.Assertions.assertThat; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.immutable.ImmutableToFooWithBuilder; -import com.hotels.beans.sample.mixed.MixedToFooWithBuilder; -import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; -import com.hotels.beans.sample.mutable.MutableToFooWithBuilderMultipleConstructor; +import com.expediagroup.beans.sample.immutable.ImmutableToFooWithBuilder; +import com.expediagroup.beans.sample.mixed.MixedToFooWithBuilder; +import com.expediagroup.beans.sample.mutable.MutableToFooWithBuilder; +import com.expediagroup.beans.sample.mutable.MutableToFooWithBuilderMultipleConstructor; /** * Unit test for all {@link BeanTransformer} functions related to Object based on Builder Pattern. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java similarity index 92% rename from bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java index da48bfaab..7d614d519 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; -import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -35,33 +34,33 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.BeanUtils; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooAdvFields; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSimpleBooleanField; -import com.hotels.beans.sample.immutable.ImmutableFlatToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; -import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooDiffFields; -import com.hotels.beans.sample.immutable.ImmutableToFooDiffTypesFields; -import com.hotels.beans.sample.immutable.ImmutableToFooMap; -import com.hotels.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooNotExistingFields; -import com.hotels.beans.sample.immutable.ImmutableToFooSimple; -import com.hotels.beans.sample.immutable.ImmutableToFooSimpleBoolean; -import com.hotels.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; -import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.transformer.AbstractTransformerTest; -import com.hotels.transformer.annotation.ConstructorArg; -import com.hotels.transformer.cache.CacheManager; -import com.hotels.transformer.error.InvalidBeanException; -import com.hotels.transformer.error.InvalidFunctionException; -import com.hotels.transformer.model.FieldMapping; -import com.hotels.transformer.model.FieldTransformer; -import com.hotels.transformer.utils.ClassUtils; -import com.hotels.transformer.utils.ReflectionUtils; +import com.expediagroup.beans.BeanUtils; +import com.expediagroup.beans.sample.FromFoo; +import com.expediagroup.beans.sample.FromFooAdvFields; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.FromFooSimpleBooleanField; +import com.expediagroup.beans.sample.immutable.ImmutableFlatToFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToFooAdvFields; +import com.expediagroup.beans.sample.immutable.ImmutableToFooCustomAnnotation; +import com.expediagroup.beans.sample.immutable.ImmutableToFooDiffFields; +import com.expediagroup.beans.sample.immutable.ImmutableToFooDiffTypesFields; +import com.expediagroup.beans.sample.immutable.ImmutableToFooMap; +import com.expediagroup.beans.sample.immutable.ImmutableToFooMissingCustomAnnotation; +import com.expediagroup.beans.sample.immutable.ImmutableToFooNotExistingFields; +import com.expediagroup.beans.sample.immutable.ImmutableToFooSimple; +import com.expediagroup.beans.sample.immutable.ImmutableToFooSimpleBoolean; +import com.expediagroup.beans.sample.immutable.ImmutableToFooSimpleWrongTypes; +import com.expediagroup.beans.sample.immutable.ImmutableToFooSubClass; +import com.expediagroup.transformer.AbstractTransformerTest; +import com.expediagroup.transformer.annotation.ConstructorArg; +import com.expediagroup.transformer.cache.CacheManager; +import com.expediagroup.transformer.error.InvalidBeanException; +import com.expediagroup.transformer.error.InvalidFunctionException; +import com.expediagroup.transformer.model.FieldMapping; +import com.expediagroup.transformer.model.FieldTransformer; +import com.expediagroup.transformer.utils.ClassUtils; +import com.expediagroup.transformer.utils.ReflectionUtils; /** * Unit test for all {@link BeanTransformer} functions related to Immutable Java Beans. @@ -410,7 +409,7 @@ public void testTransformationReturnsAMeaningfulException() { + "Error message: argument type mismatch"; String targetClassName = targetClass.getName(); String expectedExceptionMessage = - format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getName()); + String.format(expectedExceptionMessageFormat, targetClassName, targetClassName, targetClass.getSimpleName(), fromFooSimple.getClass().getName()); // WHEN ThrowingCallable actual = () -> underTest.transform(fromFooSimple, targetClass); diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java similarity index 91% rename from bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java index 088acbf68..f2af12eef 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; import static org.assertj.core.api.Assertions.assertThat; @@ -21,15 +21,15 @@ import org.testng.annotations.Test; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.mixed.MixedToFoo; -import com.hotels.beans.sample.mixed.MixedToFooDiffFields; -import com.hotels.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; -import com.hotels.beans.sample.mixed.MixedToFooMissingField; -import com.hotels.beans.sample.mixed.MixedToFooNotExistingFields; -import com.hotels.transformer.error.MissingFieldException; -import com.hotels.transformer.model.FieldMapping; -import com.hotels.transformer.model.FieldTransformer; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.mixed.MixedToFoo; +import com.expediagroup.beans.sample.mixed.MixedToFooDiffFields; +import com.expediagroup.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; +import com.expediagroup.beans.sample.mixed.MixedToFooMissingField; +import com.expediagroup.beans.sample.mixed.MixedToFooNotExistingFields; +import com.expediagroup.transformer.error.MissingFieldException; +import com.expediagroup.transformer.model.FieldMapping; +import com.expediagroup.transformer.model.FieldTransformer; /** * Unit test for all {@link BeanTransformer} functions related to Mixed type Java Beans. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java similarity index 94% rename from bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java index e89eda788..9b88ed446 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; import static java.lang.Integer.parseInt; @@ -34,20 +34,20 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.FromFooNoField; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSimpleNoGetters; -import com.hotels.beans.sample.mixed.MutableToFooOnlyPrimitiveTypes; -import com.hotels.beans.sample.mutable.MutableToFoo; -import com.hotels.beans.sample.mutable.MutableToFooInvalid; -import com.hotels.beans.sample.mutable.MutableToFooNotExistingFields; -import com.hotels.beans.sample.mutable.MutableToFooSimple; -import com.hotels.beans.sample.mutable.MutableToFooSimpleNoSetters; -import com.hotels.beans.sample.mutable.MutableToFooSubClass; -import com.hotels.transformer.error.InvalidBeanException; -import com.hotels.transformer.error.MissingFieldException; -import com.hotels.transformer.model.FieldTransformer; -import com.hotels.transformer.utils.ClassUtils; +import com.expediagroup.beans.sample.FromFooNoField; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.FromFooSimpleNoGetters; +import com.expediagroup.beans.sample.mixed.MutableToFooOnlyPrimitiveTypes; +import com.expediagroup.beans.sample.mutable.MutableToFoo; +import com.expediagroup.beans.sample.mutable.MutableToFooInvalid; +import com.expediagroup.beans.sample.mutable.MutableToFooNotExistingFields; +import com.expediagroup.beans.sample.mutable.MutableToFooSimple; +import com.expediagroup.beans.sample.mutable.MutableToFooSimpleNoSetters; +import com.expediagroup.beans.sample.mutable.MutableToFooSubClass; +import com.expediagroup.transformer.error.InvalidBeanException; +import com.expediagroup.transformer.error.MissingFieldException; +import com.expediagroup.transformer.model.FieldTransformer; +import com.expediagroup.transformer.utils.ClassUtils; /** * Unit test for all {@link BeanTransformer} functions related to Mutable type Java Beans. diff --git a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/RecordObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java similarity index 91% rename from bull-bean-transformer/src/test/java/com/hotels/beans/transformer/RecordObjectTransformationTest.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java index 53d07212f..70e59fd94 100644 --- a/bull-bean-transformer/src/test/java/com/hotels/beans/transformer/RecordObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; import static org.assertj.core.api.Assertions.assertThat; import org.testng.annotations.Test; -import com.hotels.beans.sample.record.FromFooRecord; -import com.hotels.beans.sample.record.RecordToFoo; +import com.expediagroup.beans.sample.record.FromFooRecord; +import com.expediagroup.beans.sample.record.RecordToFoo; /** * Unit test for all {@link BeanTransformer} functions related to a Java record. diff --git a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/package-info.java similarity index 93% rename from bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java rename to bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/package-info.java index dec4cd967..5d8b45b2f 100644 --- a/bull-bean-transformer/src/main/java/com/hotels/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/package-info.java @@ -16,4 +16,4 @@ /** * Bean transformer package. */ -package com.hotels.beans.transformer; +package com.expediagroup.beans.transformer; diff --git a/bull-bean-transformer/src/test/resources/logback-test.xml b/bull-bean-transformer/src/test/resources/logback-test.xml index bb3a219f1..f82e2a7d8 100644 --- a/bull-bean-transformer/src/test/resources/logback-test.xml +++ b/bull-bean-transformer/src/test/resources/logback-test.xml @@ -31,9 +31,9 @@ - - - + + + diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 402f677b5..8d022ceea 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -7,24 +7,24 @@ Contains all the modules available in the BULL project - com.hotels.beans + com.expediagroup.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT - com.hotels.beans + com.expediagroup.beans bull-bean-transformer ${project.version} - com.hotels.beans + com.expediagroup.beans bull-map-transformer ${project.version} - com.hotels.beans + com.expediagroup.beans bull-converter ${project.version} diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 81a35a788..911a9a566 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -7,9 +7,9 @@ Contains all classes required from more than one module - com.hotels.beans + com.expediagroup.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT diff --git a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java similarity index 89% rename from bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java rename to bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java index 759e25648..03c7a7c89 100644 --- a/bull-common/src/main/java/com/hotels/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java @@ -13,19 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer; +package com.expediagroup.transformer; -import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.transformer.validator.Validator.notNull; +import static com.expediagroup.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.expediagroup.transformer.validator.Validator.notNull; import java.util.Map; -import com.hotels.transformer.cache.CacheManager; -import com.hotels.transformer.model.FieldMapping; -import com.hotels.transformer.model.FieldTransformer; -import com.hotels.transformer.model.TransformerSettings; -import com.hotels.transformer.utils.ClassUtils; -import com.hotels.transformer.utils.ReflectionUtils; +import com.expediagroup.transformer.cache.CacheManager; +import com.expediagroup.transformer.model.FieldMapping; +import com.expediagroup.transformer.model.FieldTransformer; +import com.expediagroup.transformer.model.TransformerSettings; +import com.expediagroup.transformer.utils.ClassUtils; +import com.expediagroup.transformer.utils.ReflectionUtils; import lombok.Getter; diff --git a/bull-common/src/main/java/com/hotels/transformer/Transformer.java b/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java similarity index 92% rename from bull-common/src/main/java/com/hotels/transformer/Transformer.java rename to bull-common/src/main/java/com/expediagroup/transformer/Transformer.java index 5592e0fec..9eaaa8f92 100644 --- a/bull-common/src/main/java/com/hotels/transformer/Transformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer; +package com.expediagroup.transformer; -import com.hotels.transformer.model.FieldMapping; -import com.hotels.transformer.model.FieldTransformer; +import com.expediagroup.transformer.model.FieldMapping; +import com.expediagroup.transformer.model.FieldTransformer; /** * Utility methods for all objects transformation. diff --git a/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java b/bull-common/src/main/java/com/expediagroup/transformer/annotation/ConstructorArg.java similarity index 97% rename from bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java rename to bull-common/src/main/java/com/expediagroup/transformer/annotation/ConstructorArg.java index 5a7f2a966..acbdc650d 100644 --- a/bull-common/src/main/java/com/hotels/transformer/annotation/ConstructorArg.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/annotation/ConstructorArg.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.annotation; +package com.expediagroup.transformer.annotation; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; diff --git a/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java b/bull-common/src/main/java/com/expediagroup/transformer/annotation/package-info.java similarity index 92% rename from bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java rename to bull-common/src/main/java/com/expediagroup/transformer/annotation/package-info.java index ffe302a5a..234984e16 100644 --- a/bull-common/src/main/java/com/hotels/transformer/annotation/package-info.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/annotation/package-info.java @@ -16,4 +16,4 @@ /** * Annotations package. */ -package com.hotels.transformer.annotation; +package com.expediagroup.transformer.annotation; diff --git a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java b/bull-common/src/main/java/com/expediagroup/transformer/base/Defaults.java similarity index 70% rename from bull-common/src/main/java/com/hotels/transformer/base/Defaults.java rename to bull-common/src/main/java/com/expediagroup/transformer/base/Defaults.java index d3ec5b895..44ca1f144 100644 --- a/bull-common/src/main/java/com/hotels/transformer/base/Defaults.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/base/Defaults.java @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.base; +package com.expediagroup.transformer.base; import static java.lang.Boolean.FALSE; -import static com.hotels.transformer.utils.ClassUtils.isBoolean; -import static com.hotels.transformer.utils.ClassUtils.isByte; -import static com.hotels.transformer.utils.ClassUtils.isChar; -import static com.hotels.transformer.utils.ClassUtils.isDouble; -import static com.hotels.transformer.utils.ClassUtils.isFloat; -import static com.hotels.transformer.utils.ClassUtils.isInt; -import static com.hotels.transformer.utils.ClassUtils.isLong; -import static com.hotels.transformer.utils.ClassUtils.isShort; +import static com.expediagroup.transformer.utils.ClassUtils.isBoolean; +import static com.expediagroup.transformer.utils.ClassUtils.isByte; +import static com.expediagroup.transformer.utils.ClassUtils.isChar; +import static com.expediagroup.transformer.utils.ClassUtils.isDouble; +import static com.expediagroup.transformer.utils.ClassUtils.isFloat; +import static com.expediagroup.transformer.utils.ClassUtils.isInt; +import static com.expediagroup.transformer.utils.ClassUtils.isLong; +import static com.expediagroup.transformer.utils.ClassUtils.isShort; import lombok.experimental.UtilityClass; diff --git a/bull-common/src/main/java/com/hotels/transformer/base/package-info.java b/bull-common/src/main/java/com/expediagroup/transformer/base/package-info.java similarity index 93% rename from bull-common/src/main/java/com/hotels/transformer/base/package-info.java rename to bull-common/src/main/java/com/expediagroup/transformer/base/package-info.java index 63f078944..ce76efa06 100644 --- a/bull-common/src/main/java/com/hotels/transformer/base/package-info.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/base/package-info.java @@ -16,4 +16,4 @@ /** * Base package. */ -package com.hotels.transformer.base; +package com.expediagroup.transformer.base; diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java b/bull-common/src/main/java/com/expediagroup/transformer/cache/CacheManager.java similarity index 98% rename from bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java rename to bull-common/src/main/java/com/expediagroup/transformer/cache/CacheManager.java index 81c75651a..ac4a2cd66 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManager.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/cache/CacheManager.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.cache; +package com.expediagroup.transformer.cache; import static java.util.Objects.nonNull; import static java.util.Optional.ofNullable; diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java b/bull-common/src/main/java/com/expediagroup/transformer/cache/CacheManagerFactory.java similarity index 92% rename from bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java rename to bull-common/src/main/java/com/expediagroup/transformer/cache/CacheManagerFactory.java index 146f69b36..940c39b76 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/CacheManagerFactory.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/cache/CacheManagerFactory.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.cache; +package com.expediagroup.transformer.cache; -import static com.hotels.transformer.validator.Validator.notNull; +import static com.expediagroup.transformer.validator.Validator.notNull; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java b/bull-common/src/main/java/com/expediagroup/transformer/cache/package-info.java similarity index 93% rename from bull-common/src/test/java/com/hotels/transformer/cache/package-info.java rename to bull-common/src/main/java/com/expediagroup/transformer/cache/package-info.java index 7c47a942f..dce416840 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/package-info.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/cache/package-info.java @@ -16,4 +16,4 @@ /** * cache package. */ -package com.hotels.transformer.cache; +package com.expediagroup.transformer.cache; diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java b/bull-common/src/main/java/com/expediagroup/transformer/constant/ClassType.java similarity index 96% rename from bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java rename to bull-common/src/main/java/com/expediagroup/transformer/constant/ClassType.java index 050557489..7bc25bd4a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/ClassType.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/constant/ClassType.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.constant; +package com.expediagroup.transformer.constant; /** * Class type definition. diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java b/bull-common/src/main/java/com/expediagroup/transformer/constant/Filters.java similarity index 97% rename from bull-common/src/main/java/com/hotels/transformer/constant/Filters.java rename to bull-common/src/main/java/com/expediagroup/transformer/constant/Filters.java index 25374ae97..cc711c9fa 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Filters.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/constant/Filters.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.constant; +package com.expediagroup.transformer.constant; import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isStatic; diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java b/bull-common/src/main/java/com/expediagroup/transformer/constant/MethodPrefix.java similarity index 95% rename from bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java rename to bull-common/src/main/java/com/expediagroup/transformer/constant/MethodPrefix.java index cd207e8c7..0f4a455ec 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/MethodPrefix.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/constant/MethodPrefix.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.constant; +package com.expediagroup.transformer.constant; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java b/bull-common/src/main/java/com/expediagroup/transformer/constant/Punctuation.java similarity index 96% rename from bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java rename to bull-common/src/main/java/com/expediagroup/transformer/constant/Punctuation.java index e8b4b3c69..faa74556c 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/Punctuation.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/constant/Punctuation.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.constant; +package com.expediagroup.transformer.constant; import static lombok.AccessLevel.PRIVATE; diff --git a/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java b/bull-common/src/main/java/com/expediagroup/transformer/constant/package-info.java similarity index 93% rename from bull-common/src/main/java/com/hotels/transformer/constant/package-info.java rename to bull-common/src/main/java/com/expediagroup/transformer/constant/package-info.java index b875d2428..f27ef2962 100644 --- a/bull-common/src/main/java/com/hotels/transformer/constant/package-info.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/constant/package-info.java @@ -16,4 +16,4 @@ /** * Constants package. */ -package com.hotels.transformer.constant; +package com.expediagroup.transformer.constant; diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java b/bull-common/src/main/java/com/expediagroup/transformer/error/InstanceCreationException.java similarity index 96% rename from bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java rename to bull-common/src/main/java/com/expediagroup/transformer/error/InstanceCreationException.java index e3c71e779..2246d3e6a 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InstanceCreationException.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/error/InstanceCreationException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.error; +package com.expediagroup.transformer.error; /** * Instance creation exception class. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java b/bull-common/src/main/java/com/expediagroup/transformer/error/InvalidBeanException.java similarity index 97% rename from bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java rename to bull-common/src/main/java/com/expediagroup/transformer/error/InvalidBeanException.java index 00fd6676a..742990f58 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InvalidBeanException.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/error/InvalidBeanException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.error; +package com.expediagroup.transformer.error; /** * Invalid Bean exception class. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java b/bull-common/src/main/java/com/expediagroup/transformer/error/InvalidFunctionException.java similarity index 96% rename from bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java rename to bull-common/src/main/java/com/expediagroup/transformer/error/InvalidFunctionException.java index 62f27796d..36df20358 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/InvalidFunctionException.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/error/InvalidFunctionException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.error; +package com.expediagroup.transformer.error; /** * Invalid transformation function exception. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java b/bull-common/src/main/java/com/expediagroup/transformer/error/MissingFieldException.java similarity index 96% rename from bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java rename to bull-common/src/main/java/com/expediagroup/transformer/error/MissingFieldException.java index b9488d37a..8b448aa84 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/MissingFieldException.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/error/MissingFieldException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.error; +package com.expediagroup.transformer.error; /** * Exception thrown if not the field not exists in the source object and no mapping has been specified. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java b/bull-common/src/main/java/com/expediagroup/transformer/error/MissingMethodException.java similarity index 97% rename from bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java rename to bull-common/src/main/java/com/expediagroup/transformer/error/MissingMethodException.java index 1d6026dbd..c6a193808 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/MissingMethodException.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/error/MissingMethodException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.error; +package com.expediagroup.transformer.error; /** * Exception thrown if not a method not exists in the source object and no mapping has been specified. diff --git a/bull-common/src/main/java/com/hotels/transformer/error/package-info.java b/bull-common/src/main/java/com/expediagroup/transformer/error/package-info.java similarity index 93% rename from bull-common/src/main/java/com/hotels/transformer/error/package-info.java rename to bull-common/src/main/java/com/expediagroup/transformer/error/package-info.java index 064791726..1aef03572 100644 --- a/bull-common/src/main/java/com/hotels/transformer/error/package-info.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/error/package-info.java @@ -16,4 +16,4 @@ /** * Exceptions package. */ -package com.hotels.transformer.error; +package com.expediagroup.transformer.error; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java b/bull-common/src/main/java/com/expediagroup/transformer/model/EmptyValue.java similarity index 94% rename from bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java rename to bull-common/src/main/java/com/expediagroup/transformer/model/EmptyValue.java index 66c2ae32c..cbc6ce400 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/EmptyValue.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/EmptyValue.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.model; +package com.expediagroup.transformer.model; /** * Needed in order to put in cache an empty value. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java similarity index 95% rename from bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java rename to bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java index 60b500276..5700635c8 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.model; +package com.expediagroup.transformer.model; /** * Specifies the field's name mapping between the source object and destination one. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java similarity index 96% rename from bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java rename to bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java index 037b05c53..358328bbc 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/FieldTransformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.model; +package com.expediagroup.transformer.model; import static java.util.Objects.nonNull; @@ -22,7 +22,7 @@ import java.util.function.Function; import java.util.function.Supplier; -import com.hotels.transformer.error.InvalidFunctionException; +import com.expediagroup.transformer.error.InvalidFunctionException; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java b/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java similarity index 96% rename from bull-common/src/main/java/com/hotels/transformer/model/ItemType.java rename to bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java index 610c05187..9775f16d2 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/ItemType.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.model; +package com.expediagroup.transformer.model; import lombok.Builder; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java b/bull-common/src/main/java/com/expediagroup/transformer/model/MapElemType.java similarity index 94% rename from bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java rename to bull-common/src/main/java/com/expediagroup/transformer/model/MapElemType.java index 7addc2465..45f9bbb29 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/MapElemType.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/MapElemType.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.model; +package com.expediagroup.transformer.model; /** * Interface that identifies the contained object elem types. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/MapType.java b/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java similarity index 94% rename from bull-common/src/main/java/com/hotels/transformer/model/MapType.java rename to bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java index 00dda2c89..390399844 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/MapType.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.model; +package com.expediagroup.transformer.model; /** * Bean class for mapping the java.util.Map type. diff --git a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java b/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java similarity index 95% rename from bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java rename to bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java index f146e0bf0..a741533f3 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/TransformerSettings.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.model; +package com.expediagroup.transformer.model; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import com.expediagroup.transformer.error.MissingFieldException; + import lombok.Getter; import lombok.Setter; @@ -55,7 +57,7 @@ public class TransformerSettings { /** * It allows to configure the transformer in order to set a default value in case some field is missing in the source object. - * If set to true the default value is set, if false if it raises a: {@link com.hotels.transformer.error.MissingFieldException} in case of missing fields. + * If set to true the default value is set, if false if it raises a: {@link MissingFieldException} in case of missing fields. */ @Setter private boolean setDefaultValueForMissingField; diff --git a/bull-common/src/main/java/com/hotels/transformer/model/package-info.java b/bull-common/src/main/java/com/expediagroup/transformer/model/package-info.java similarity index 93% rename from bull-common/src/main/java/com/hotels/transformer/model/package-info.java rename to bull-common/src/main/java/com/expediagroup/transformer/model/package-info.java index ba9ebc1ed..370aaf722 100644 --- a/bull-common/src/main/java/com/hotels/transformer/model/package-info.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/package-info.java @@ -16,4 +16,4 @@ /** * Pojo package. */ -package com.hotels.transformer.model; +package com.expediagroup.transformer.model; diff --git a/bull-common/src/main/java/com/hotels/transformer/package-info.java b/bull-common/src/main/java/com/expediagroup/transformer/package-info.java similarity index 94% rename from bull-common/src/main/java/com/hotels/transformer/package-info.java rename to bull-common/src/main/java/com/expediagroup/transformer/package-info.java index 4404a5e40..baf9342f7 100644 --- a/bull-common/src/main/java/com/hotels/transformer/package-info.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/package-info.java @@ -16,4 +16,4 @@ /** * Transformer package. */ -package com.hotels.transformer; +package com.expediagroup.transformer; diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/expediagroup/transformer/utils/ClassUtils.java similarity index 96% rename from bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java rename to bull-common/src/main/java/com/expediagroup/transformer/utils/ClassUtils.java index e337d02f1..eecd7ba38 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/utils/ClassUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.utils; +package com.expediagroup.transformer.utils; import static java.lang.invoke.LambdaMetafactory.metafactory; import static java.lang.invoke.MethodHandles.lookup; @@ -33,15 +33,10 @@ import static java.util.Set.of; import static java.util.stream.Collectors.toList; -import static com.hotels.transformer.base.Defaults.defaultValue; -import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.transformer.constant.ClassType.IMMUTABLE; -import static com.hotels.transformer.constant.ClassType.MIXED; -import static com.hotels.transformer.constant.ClassType.MUTABLE; -import static com.hotels.transformer.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; -import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; -import static com.hotels.transformer.constant.Filters.IS_NOT_FINAL_FIELD; -import static com.hotels.transformer.validator.Validator.notNull; +import static com.expediagroup.transformer.constant.Filters.IS_FINAL_AND_NOT_STATIC_FIELD; +import static com.expediagroup.transformer.constant.Filters.IS_NOT_FINAL_AND_NOT_STATIC_FIELD; +import static com.expediagroup.transformer.constant.Filters.IS_NOT_FINAL_FIELD; +import static com.expediagroup.transformer.validator.Validator.notNull; import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; @@ -66,11 +61,13 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import com.hotels.transformer.cache.CacheManager; -import com.hotels.transformer.constant.ClassType; -import com.hotels.transformer.error.InstanceCreationException; -import com.hotels.transformer.error.InvalidBeanException; -import com.hotels.transformer.error.MissingMethodException; +import com.expediagroup.transformer.base.Defaults; +import com.expediagroup.transformer.cache.CacheManager; +import com.expediagroup.transformer.cache.CacheManagerFactory; +import com.expediagroup.transformer.constant.ClassType; +import com.expediagroup.transformer.error.InstanceCreationException; +import com.expediagroup.transformer.error.InvalidBeanException; +import com.expediagroup.transformer.error.MissingMethodException; /** * Reflection utils for Class objects. @@ -89,7 +86,7 @@ public final class ClassUtils { /** * CacheManager class {@link CacheManager}. */ - private static final CacheManager CACHE_MANAGER = getCacheManager("classUtils"); + private static final CacheManager CACHE_MANAGER = CacheManagerFactory.getCacheManager("classUtils"); /** * Primitive types list. @@ -731,13 +728,13 @@ public ClassType getClassType(final Class clazz) { final ClassType classType; boolean hasFinalFields = hasFinalFields(clazz); if (!hasFinalFields) { - classType = MUTABLE; + classType = ClassType.MUTABLE; } else { boolean hasNotFinalFields = hasNotFinalFields(clazz); if (hasNotFinalFields) { - classType = MIXED; + classType = ClassType.MIXED; } else { - classType = IMMUTABLE; + classType = ClassType.IMMUTABLE; } } CACHE_MANAGER.cacheObject(cacheKey, classType); @@ -795,7 +792,7 @@ private List getMethods(final Class clazz, final String cacheKeyPrefi public Object getDefaultTypeValue(final Class objectType) { final String cacheKey = "DefaultTypeValue-" + objectType.getName(); return CACHE_MANAGER.getFromCache(cacheKey, Object.class).orElseGet(() -> { - final Object defaultValue = isPrimitiveType(objectType) ? defaultValue(objectType) : null; + final Object defaultValue = isPrimitiveType(objectType) ? Defaults.defaultValue(objectType) : null; CACHE_MANAGER.cacheObject(cacheKey, defaultValue); return defaultValue; }); diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/expediagroup/transformer/utils/ReflectionUtils.java similarity index 97% rename from bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java rename to bull-common/src/main/java/com/expediagroup/transformer/utils/ReflectionUtils.java index 7ed9ddcc9..54dcd6386 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/utils/ReflectionUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.utils; +package com.expediagroup.transformer.utils; import static java.lang.invoke.LambdaMetafactory.metafactory; import static java.lang.invoke.MethodHandles.lookup; @@ -24,10 +24,10 @@ import static org.apache.commons.lang3.ArrayUtils.isEmpty; import static org.apache.commons.lang3.StringUtils.capitalize; -import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.transformer.constant.MethodPrefix.GET; -import static com.hotels.transformer.constant.MethodPrefix.IS; -import static com.hotels.transformer.constant.MethodPrefix.SET; +import static com.expediagroup.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.expediagroup.transformer.constant.MethodPrefix.GET; +import static com.expediagroup.transformer.constant.MethodPrefix.IS; +import static com.expediagroup.transformer.constant.MethodPrefix.SET; import java.lang.annotation.Annotation; import java.lang.invoke.CallSite; @@ -46,14 +46,14 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; -import com.hotels.transformer.cache.CacheManager; -import com.hotels.transformer.error.InvalidBeanException; -import com.hotels.transformer.error.MissingFieldException; -import com.hotels.transformer.error.MissingMethodException; -import com.hotels.transformer.model.EmptyValue; -import com.hotels.transformer.model.ItemType; -import com.hotels.transformer.model.MapElemType; -import com.hotels.transformer.model.MapType; +import com.expediagroup.transformer.cache.CacheManager; +import com.expediagroup.transformer.error.InvalidBeanException; +import com.expediagroup.transformer.error.MissingFieldException; +import com.expediagroup.transformer.error.MissingMethodException; +import com.expediagroup.transformer.model.EmptyValue; +import com.expediagroup.transformer.model.ItemType; +import com.expediagroup.transformer.model.MapElemType; +import com.expediagroup.transformer.model.MapType; /** * Reflection class utils. diff --git a/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java b/bull-common/src/main/java/com/expediagroup/transformer/utils/package-info.java similarity index 93% rename from bull-common/src/main/java/com/hotels/transformer/utils/package-info.java rename to bull-common/src/main/java/com/expediagroup/transformer/utils/package-info.java index ea1de7df2..943ddc08d 100644 --- a/bull-common/src/main/java/com/hotels/transformer/utils/package-info.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/utils/package-info.java @@ -16,4 +16,4 @@ /** * utilities package. */ -package com.hotels.transformer.utils; +package com.expediagroup.transformer.utils; diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java b/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java similarity index 92% rename from bull-common/src/main/java/com/hotels/transformer/validator/Validator.java rename to bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java index b0aa41f30..f38167fa1 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/Validator.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.validator; +package com.expediagroup.transformer.validator; import static java.util.Objects.isNull; @@ -22,6 +22,8 @@ import jakarta.validation.ConstraintViolation; +import com.expediagroup.transformer.error.InvalidBeanException; + /** * Java Bean validation class. * It offers the possibility to validate a given Java Bean against a set of defined constraints. @@ -47,7 +49,7 @@ public interface Validator { * Checks if an object is valid. * @param the object class * @param k the object to check - * @throws com.hotels.transformer.error.InvalidBeanException {@link com.hotels.transformer.error.InvalidBeanException} if the validation fails + * @throws InvalidBeanException {@link InvalidBeanException} if the validation fails */ void validate(K k); diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java b/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java similarity index 85% rename from bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java rename to bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java index 621a8ce54..e3a077c52 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.validator; +package com.expediagroup.transformer.validator; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; @@ -22,18 +22,16 @@ import static org.apache.commons.lang3.StringUtils.SPACE; -import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.transformer.constant.Punctuation.DOT; -import static com.hotels.transformer.constant.Punctuation.SEMICOLON; - import java.util.List; import java.util.Set; import java.util.function.Function; import jakarta.validation.ConstraintViolation; -import com.hotels.transformer.cache.CacheManager; -import com.hotels.transformer.error.InvalidBeanException; +import com.expediagroup.transformer.cache.CacheManager; +import com.expediagroup.transformer.cache.CacheManagerFactory; +import com.expediagroup.transformer.constant.Punctuation; +import com.expediagroup.transformer.error.InvalidBeanException; /** * Java Bean validation class. @@ -49,7 +47,7 @@ public class ValidatorImpl implements Validator { * Default constructor. */ public ValidatorImpl() { - this.cacheManager = getCacheManager("validatorImpl"); + this.cacheManager = CacheManagerFactory.getCacheManager("validatorImpl"); } /** @@ -79,7 +77,7 @@ public final void validate(final K k) { if (!constraintViolations.isEmpty()) { final String errors = constraintViolations.stream() .map(getConstraintViolationMessage()) - .collect(joining(SEMICOLON.getSymbol())); + .collect(joining(Punctuation.SEMICOLON.getSymbol())); throw new InvalidBeanException(errors); } } @@ -90,7 +88,7 @@ public final void validate(final K k) { */ private Function, String> getConstraintViolationMessage() { return cv -> cv.getRootBeanClass().getName() - + DOT.getSymbol() + + Punctuation.DOT.getSymbol() + cv.getPropertyPath() + SPACE + cv.getMessage(); diff --git a/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java b/bull-common/src/main/java/com/expediagroup/transformer/validator/package-info.java similarity index 92% rename from bull-common/src/main/java/com/hotels/transformer/validator/package-info.java rename to bull-common/src/main/java/com/expediagroup/transformer/validator/package-info.java index a9fcd3d49..d33ec4f56 100644 --- a/bull-common/src/main/java/com/hotels/transformer/validator/package-info.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/validator/package-info.java @@ -16,4 +16,4 @@ /** * validator package. */ -package com.hotels.transformer.validator; +package com.expediagroup.transformer.validator; diff --git a/bull-common/src/test/java/com/hotels/beans/package-info.java b/bull-common/src/test/java/com/expediagroup/beans/package-info.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/package-info.java rename to bull-common/src/test/java/com/expediagroup/beans/package-info.java index 10a91859c..e52e8ed06 100644 --- a/bull-common/src/test/java/com/hotels/beans/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/beans/package-info.java @@ -16,4 +16,4 @@ /** * Bean test package. */ -package com.hotels.beans; +package com.expediagroup.beans; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java b/bull-common/src/test/java/com/expediagroup/beans/sample/AbstractClass.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/AbstractClass.java index 4ec294538..53cf7b31d 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/AbstractClass.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/AbstractClass.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFoo.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFoo.java index eb10ea959..50cf368e0 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFoo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import java.math.BigInteger; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooAdvFields.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFooAdvFields.java index 4038375be..46ac47e6e 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooAdvFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooAdvFields.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; -import com.hotels.transformer.constant.ClassType; +import com.expediagroup.transformer.constant.ClassType; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooMap.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFooMap.java index 3370ebae7..0a0aaa9db 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooMap.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooMap.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import java.util.List; import java.util.Map; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooNoField.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFooNoField.java index c00dc8283..1a829f4eb 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooNoField.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooNoField.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import static java.lang.Boolean.TRUE; import static java.math.BigInteger.ONE; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooOnlyPrimitiveTypes.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFooOnlyPrimitiveTypes.java index 3e644bfb0..2cb3a6daa 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooOnlyPrimitiveTypes.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooOnlyPrimitiveTypes.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSimple.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSimple.java index 0bb877ef1..022b7b9e3 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimple.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSimple.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSimpleBooleanField.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSimpleBooleanField.java index ba7202fb7..c14150d70 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleBooleanField.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSimpleBooleanField.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSimpleNoGetters.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSimpleNoGetters.java index 2593b7c53..dc1709164 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSimpleNoGetters.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSimpleNoGetters.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSubClass.java similarity index 97% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSubClass.java index 368631a9e..81ae739c3 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooSubClass.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooSubClass.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooWithPrimitiveFields.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromFooWithPrimitiveFields.java index de100cc21..548623c8d 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromFooWithPrimitiveFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromFooWithPrimitiveFields.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/FromSubFoo.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/FromSubFoo.java index 0de1ae6d1..5f276a0a7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/FromSubFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/FromSubFoo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; import java.util.List; import java.util.Map; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java b/bull-common/src/test/java/com/expediagroup/beans/sample/ISubClass.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/ISubClass.java index cad09ce19..d1c295f92 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/ISubClass.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/ISubClass.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; /** * Sample interface for sub class Java Bean. diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableFlatToFoo.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableFlatToFoo.java index add3a1fee..c9589b105 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableFlatToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableFlatToFoo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java index b18cfe2a5..7ddb2845f 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.math.BigInteger; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooAdvFields.java similarity index 90% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooAdvFields.java index a489f60cd..26ee7f177 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooAdvFields.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.util.Collection; import java.util.List; @@ -21,8 +21,8 @@ import java.util.Map; import java.util.Optional; -import com.hotels.beans.sample.ISubClass; -import com.hotels.transformer.constant.ClassType; +import com.expediagroup.beans.sample.ISubClass; +import com.expediagroup.transformer.constant.ClassType; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java index 4bdd820d2..cd88fad67 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.math.BigInteger; import java.util.List; import jakarta.validation.constraints.NotNull; -import com.hotels.transformer.annotation.ConstructorArg; +import com.expediagroup.transformer.annotation.ConstructorArg; import lombok.ToString; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java similarity index 96% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java index ee9546a90..84c9bee01 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.math.BigInteger; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffTypesFields.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffTypesFields.java index c7ade2b4a..df3e455a1 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooDiffTypesFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffTypesFields.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMap.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMap.java index 16feda4c9..8a86ab3de 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMap.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMap.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.util.List; import java.util.Map; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java similarity index 91% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java index 4b28734b0..d7895f0b4 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import jakarta.validation.constraints.NotNull; -import com.hotels.transformer.annotation.ConstructorArg; +import com.expediagroup.transformer.annotation.ConstructorArg; import lombok.Getter; import lombok.ToString; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooNoConstructors.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooNoConstructors.java index 015ee0d21..7054177b1 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNoConstructors.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooNoConstructors.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import lombok.AccessLevel; import lombok.NoArgsConstructor; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooNotExistingFields.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooNotExistingFields.java index a9a276824..ecfbd8707 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooNotExistingFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooNotExistingFields.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSimple.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSimple.java index 349b161c8..715d51a4a 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimple.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSimple.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSimpleBoolean.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSimpleBoolean.java index 8a8836808..0cbc8f800 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleBoolean.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSimpleBoolean.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java index e2d14d828..1d42b81ed 100755 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java similarity index 97% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java index 2a2110ec2..cf35004c8 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooSubClass.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooWithBuilder.java similarity index 93% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooWithBuilder.java index 1ea11ae7f..037be7f38 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToFooWithBuilder.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooWithBuilder.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.math.BigInteger; import java.util.List; -import com.hotels.beans.sample.FromSubFoo; +import com.expediagroup.beans.sample.FromSubFoo; import lombok.Builder; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFoo.java similarity index 91% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFoo.java index 7df9fff36..8940284d6 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFoo.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.util.List; import java.util.Map; -import com.hotels.beans.sample.ISubClass; +import com.expediagroup.beans.sample.ISubClass; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java similarity index 93% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java index 7b5086781..7fb38968d 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; import java.util.List; import java.util.Map; import jakarta.validation.constraints.NotNull; -import com.hotels.transformer.annotation.ConstructorArg; +import com.expediagroup.transformer.annotation.ConstructorArg; import lombok.Getter; import lombok.ToString; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/package-info.java similarity index 92% rename from bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/immutable/package-info.java index 1a7e53c33..7b24b6da4 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/immutable/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/package-info.java @@ -16,4 +16,4 @@ /** * Immutable Bean package. */ -package com.hotels.beans.sample.immutable; +package com.expediagroup.beans.sample.immutable; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java similarity index 91% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java index a065bba49..cefee46e2 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; import java.math.BigInteger; import java.util.List; import jakarta.validation.constraints.NotNull; -import com.hotels.beans.sample.immutable.ImmutableToSubFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooDiffFields.java similarity index 90% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooDiffFields.java index 3e44fcd59..6d95782ba 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooDiffFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooDiffFields.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; import java.math.BigInteger; import java.util.List; -import com.hotels.beans.sample.immutable.ImmutableToSubFoo; -import com.hotels.transformer.annotation.ConstructorArg; +import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; +import com.expediagroup.transformer.annotation.ConstructorArg; import lombok.Getter; import lombok.Setter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java similarity index 91% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java index 3768a2f0e..3149a8d10 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; import java.math.BigInteger; import java.util.List; import jakarta.validation.constraints.NotNull; -import com.hotels.beans.sample.immutable.ImmutableToSubFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java index f5a2c77f5..18d6a0bf6 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingConstructor.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingField.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingField.java index 242b0ceb5..7768e3649 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooMissingField.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingField.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooNotExistingFields.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooNotExistingFields.java index 0bd72c532..fd1a0ee23 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooNotExistingFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooNotExistingFields.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooStaticField.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooStaticField.java index 123a856f7..08f23d9d0 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooStaticField.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooStaticField.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; import lombok.Getter; import lombok.Setter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooWithBuilder.java similarity index 92% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooWithBuilder.java index 252bc50e7..456c95d46 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MixedToFooWithBuilder.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooWithBuilder.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; import java.math.BigInteger; import java.util.List; -import com.hotels.beans.sample.immutable.ImmutableToSubFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; import lombok.Builder; import lombok.Getter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java index 16bddacba..d377c4f9b 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; import lombok.Getter; import lombok.Setter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/package-info.java similarity index 93% rename from bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mixed/package-info.java index f97e0572c..a9906d4a7 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mixed/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/package-info.java @@ -16,4 +16,4 @@ /** * Mixed Bean package. */ -package com.hotels.beans.sample.mixed; +package com.expediagroup.beans.sample.mixed; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFoo.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFoo.java index 564062775..33ee936b5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFoo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.math.BigInteger; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooAdvFields.java similarity index 90% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooAdvFields.java index eacce38a7..fd8987f46 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooAdvFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooAdvFields.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.util.Collection; import java.util.List; @@ -21,8 +21,8 @@ import java.util.Map; import java.util.Optional; -import com.hotels.beans.sample.ISubClass; -import com.hotels.transformer.constant.ClassType; +import com.expediagroup.beans.sample.ISubClass; +import com.expediagroup.transformer.constant.ClassType; import lombok.Getter; import lombok.Setter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooInvalid.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooInvalid.java index f8ab76fdd..e65a21919 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooInvalid.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooInvalid.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.math.BigInteger; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooNotExistingFields.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooNotExistingFields.java index 9a905a984..071913975 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooNotExistingFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooNotExistingFields.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooSimple.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooSimple.java index 61ff4d2a2..a8772e6ec 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimple.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooSimple.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooSimpleNoSetters.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooSimpleNoSetters.java index 9ca4a4265..6305c01cd 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSimpleNoSetters.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooSimpleNoSetters.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooSubClass.java similarity index 95% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooSubClass.java index 70fe6847b..4d7a3d397 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooSubClass.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooSubClass.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.math.BigDecimal; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooWithBuilder.java similarity index 97% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooWithBuilder.java index 3e9a99d14..a2977257e 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilder.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooWithBuilder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.math.BigInteger; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java similarity index 97% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java index 4a1bd26f5..43665e4ee 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooWithBuilderMultipleConstructor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.math.BigInteger; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooWithWrongBuilder.java similarity index 97% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooWithWrongBuilder.java index 473fe0905..e101a8053 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToFooWithWrongBuilder.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToFooWithWrongBuilder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.math.BigInteger; import java.util.List; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToSubFoo.java similarity index 91% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToSubFoo.java index 57bb7a002..7a09a0afd 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/MutableToSubFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/MutableToSubFoo.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; import java.util.List; import java.util.Map; -import com.hotels.beans.sample.ISubClass; +import com.expediagroup.beans.sample.ISubClass; import lombok.Getter; import lombok.Setter; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/package-info.java similarity index 93% rename from bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/mutable/package-info.java index fd4db2b73..7435d9094 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/mutable/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mutable/package-info.java @@ -16,4 +16,4 @@ /** * Mutable Bean package. */ -package com.hotels.beans.sample.mutable; +package com.expediagroup.beans.sample.mutable; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/package-info.java b/bull-common/src/test/java/com/expediagroup/beans/sample/package-info.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/package-info.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/package-info.java index b971ff916..46ded210d 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/package-info.java @@ -16,4 +16,4 @@ /** * Sample Bean object for test purpose. */ -package com.hotels.beans.sample; +package com.expediagroup.beans.sample; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/record/FromFooRecord.java b/bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/record/FromFooRecord.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java index ef439a1a6..1d0125db5 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/record/FromFooRecord.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.record; +package com.expediagroup.beans.sample.record; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java similarity index 94% rename from bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java rename to bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java index 5b95d3276..04a02e29e 100644 --- a/bull-common/src/test/java/com/hotels/beans/sample/record/RecordToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.sample.record; +package com.expediagroup.beans.sample.record; import java.math.BigInteger; diff --git a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java similarity index 90% rename from bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java rename to bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java index 322e08e94..6b58b4b2f 100644 --- a/bull-common/src/test/java/com/hotels/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java @@ -13,13 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer; +package com.expediagroup.transformer; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; -import static com.hotels.transformer.constant.ClassType.IMMUTABLE; - import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; @@ -30,18 +28,19 @@ import java.util.Optional; import java.util.UUID; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooAdvFields; -import com.hotels.beans.sample.FromFooMap; -import com.hotels.beans.sample.FromFooOnlyPrimitiveTypes; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSubClass; -import com.hotels.beans.sample.FromFooWithPrimitiveFields; -import com.hotels.beans.sample.FromSubFoo; -import com.hotels.transformer.utils.ReflectionUtils; +import com.expediagroup.beans.sample.FromFoo; +import com.expediagroup.beans.sample.FromFooAdvFields; +import com.expediagroup.beans.sample.FromFooMap; +import com.expediagroup.beans.sample.FromFooOnlyPrimitiveTypes; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.FromFooSubClass; +import com.expediagroup.beans.sample.FromFooWithPrimitiveFields; +import com.expediagroup.beans.sample.FromSubFoo; +import com.expediagroup.transformer.constant.ClassType; +import com.expediagroup.transformer.utils.ReflectionUtils; /** - * Unit test for {@link com.hotels.transformer.Transformer}. + * Unit test for {@link Transformer}. */ public abstract class AbstractTransformerTest { protected static final BigInteger ID = new BigInteger("1234"); @@ -147,7 +146,7 @@ private FromFooSubClass createFromFooSubClass() { */ @SuppressWarnings("unchecked") private FromFooAdvFields createFromFooAdvFields() { - return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, IMMUTABLE, Locale.ENGLISH.getLanguage(), + return new FromFooAdvFields(Optional.of(NAME), Optional.of(AGE), INDEX_NUMBER, ClassType.IMMUTABLE, Locale.ENGLISH.getLanguage(), PRICE, sourceFooSimpleList, (Collection) sourceFooSimpleList, SAMPLE_MAP, (Map) SAMPLE_MAP, fromSubFoo); } diff --git a/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/base/DefaultsTest.java similarity index 96% rename from bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java rename to bull-common/src/test/java/com/expediagroup/transformer/base/DefaultsTest.java index b77e10216..2f40ed831 100644 --- a/bull-common/src/test/java/com/hotels/transformer/base/DefaultsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/base/DefaultsTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.base; +package com.expediagroup.transformer.base; import static java.lang.Boolean.FALSE; @@ -23,7 +23,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.FromFoo; +import com.expediagroup.beans.sample.FromFoo; /** * Unit test for {@link Defaults}. diff --git a/bull-common/src/test/java/com/hotels/transformer/base/package-info.java b/bull-common/src/test/java/com/expediagroup/transformer/base/package-info.java similarity index 93% rename from bull-common/src/test/java/com/hotels/transformer/base/package-info.java rename to bull-common/src/test/java/com/expediagroup/transformer/base/package-info.java index bebd35f18..d6c482e9d 100644 --- a/bull-common/src/test/java/com/hotels/transformer/base/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/base/package-info.java @@ -16,4 +16,4 @@ /** * Base item package. */ -package com.hotels.transformer.base; +package com.expediagroup.transformer.base; diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java b/bull-common/src/test/java/com/expediagroup/transformer/cache/CacheManagerFactoryTest.java similarity index 97% rename from bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java rename to bull-common/src/test/java/com/expediagroup/transformer/cache/CacheManagerFactoryTest.java index 753876b78..306081d0f 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerFactoryTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/cache/CacheManagerFactoryTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.cache; +package com.expediagroup.transformer.cache; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.openMocks; diff --git a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java b/bull-common/src/test/java/com/expediagroup/transformer/cache/CacheManagerTest.java similarity index 98% rename from bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java rename to bull-common/src/test/java/com/expediagroup/transformer/cache/CacheManagerTest.java index bfe574236..378575bc3 100644 --- a/bull-common/src/test/java/com/hotels/transformer/cache/CacheManagerTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/cache/CacheManagerTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.cache; +package com.expediagroup.transformer.cache; import static org.assertj.core.api.Assertions.assertThat; diff --git a/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java b/bull-common/src/test/java/com/expediagroup/transformer/cache/package-info.java similarity index 93% rename from bull-common/src/main/java/com/hotels/transformer/cache/package-info.java rename to bull-common/src/test/java/com/expediagroup/transformer/cache/package-info.java index 7c47a942f..dce416840 100644 --- a/bull-common/src/main/java/com/hotels/transformer/cache/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/cache/package-info.java @@ -16,4 +16,4 @@ /** * cache package. */ -package com.hotels.transformer.cache; +package com.expediagroup.transformer.cache; diff --git a/bull-common/src/test/java/com/hotels/transformer/package-info.java b/bull-common/src/test/java/com/expediagroup/transformer/package-info.java similarity index 94% rename from bull-common/src/test/java/com/hotels/transformer/package-info.java rename to bull-common/src/test/java/com/expediagroup/transformer/package-info.java index 7cf32c101..5d58b42cf 100644 --- a/bull-common/src/test/java/com/hotels/transformer/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/package-info.java @@ -16,4 +16,4 @@ /** * Transformer test package. */ -package com.hotels.transformer; +package com.expediagroup.transformer; diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java similarity index 96% rename from bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java rename to bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java index fddb05dbe..f44d8939b 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.utils; +package com.expediagroup.transformer.utils; import static java.lang.reflect.Modifier.isFinal; import static java.util.Objects.nonNull; @@ -23,8 +23,6 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.openMocks; -import static com.hotels.transformer.utils.ClassUtils.BUILD_METHOD_NAME; - import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -50,28 +48,28 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.AbstractClass; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooAdvFields; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSimpleNoGetters; -import com.hotels.beans.sample.FromFooSubClass; -import com.hotels.beans.sample.immutable.ImmutableToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFooCustomAnnotation; -import com.hotels.beans.sample.immutable.ImmutableToFooSubClass; -import com.hotels.beans.sample.mixed.MixedToFoo; -import com.hotels.beans.sample.mixed.MixedToFooMissingConstructor; -import com.hotels.beans.sample.mixed.MixedToFooStaticField; -import com.hotels.beans.sample.mixed.MixedToFooWithBuilder; -import com.hotels.beans.sample.mutable.MutableToFoo; -import com.hotels.beans.sample.mutable.MutableToFooSubClass; -import com.hotels.beans.sample.mutable.MutableToFooWithBuilder; -import com.hotels.beans.sample.mutable.MutableToFooWithWrongBuilder; -import com.hotels.transformer.annotation.ConstructorArg; -import com.hotels.transformer.constant.ClassType; -import com.hotels.transformer.error.InstanceCreationException; -import com.hotels.transformer.error.InvalidBeanException; -import com.hotels.transformer.error.MissingMethodException; +import com.expediagroup.beans.sample.AbstractClass; +import com.expediagroup.beans.sample.FromFoo; +import com.expediagroup.beans.sample.FromFooAdvFields; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.FromFooSimpleNoGetters; +import com.expediagroup.beans.sample.FromFooSubClass; +import com.expediagroup.beans.sample.immutable.ImmutableToFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToFooCustomAnnotation; +import com.expediagroup.beans.sample.immutable.ImmutableToFooSubClass; +import com.expediagroup.beans.sample.mixed.MixedToFoo; +import com.expediagroup.beans.sample.mixed.MixedToFooMissingConstructor; +import com.expediagroup.beans.sample.mixed.MixedToFooStaticField; +import com.expediagroup.beans.sample.mixed.MixedToFooWithBuilder; +import com.expediagroup.beans.sample.mutable.MutableToFoo; +import com.expediagroup.beans.sample.mutable.MutableToFooSubClass; +import com.expediagroup.beans.sample.mutable.MutableToFooWithBuilder; +import com.expediagroup.beans.sample.mutable.MutableToFooWithWrongBuilder; +import com.expediagroup.transformer.annotation.ConstructorArg; +import com.expediagroup.transformer.constant.ClassType; +import com.expediagroup.transformer.error.InstanceCreationException; +import com.expediagroup.transformer.error.InvalidBeanException; +import com.expediagroup.transformer.error.MissingMethodException; /** * Unit test for {@link ClassUtils}. @@ -1036,8 +1034,8 @@ public void testGetBuildMethodReturnsTheBuildMethod() { // THEN assertThat(actual).isNotNull(); - assertThat(actual.getName()).isEqualTo(BUILD_METHOD_NAME); - assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, BUILD_METHOD_NAME); + assertThat(actual.getName()).isEqualTo(ClassUtils.BUILD_METHOD_NAME); + assertThat(actual).hasFieldOrPropertyWithValue(NAME_FIELD_NAME, ClassUtils.BUILD_METHOD_NAME); } /** diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java similarity index 96% rename from bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java rename to bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java index ed1a922b6..94292cf36 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.utils; +package com.expediagroup.transformer.utils; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; @@ -30,9 +30,6 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.openMocks; -import static com.hotels.transformer.constant.MethodPrefix.GET; -import static com.hotels.transformer.constant.MethodPrefix.IS; - import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -54,23 +51,24 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.FromFoo; -import com.hotels.beans.sample.FromFooMap; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.FromFooSimpleNoGetters; -import com.hotels.beans.sample.FromFooSubClass; -import com.hotels.beans.sample.FromSubFoo; -import com.hotels.beans.sample.immutable.ImmutableToFoo; -import com.hotels.beans.sample.immutable.ImmutableToFooAdvFields; -import com.hotels.beans.sample.immutable.ImmutableToSubFoo; -import com.hotels.beans.sample.mutable.MutableToFoo; -import com.hotels.beans.sample.mutable.MutableToFooAdvFields; -import com.hotels.beans.sample.mutable.MutableToFooSimple; -import com.hotels.transformer.error.MissingFieldException; -import com.hotels.transformer.error.MissingMethodException; -import com.hotels.transformer.model.ItemType; -import com.hotels.transformer.model.MapElemType; -import com.hotels.transformer.model.MapType; +import com.expediagroup.beans.sample.FromFoo; +import com.expediagroup.beans.sample.FromFooMap; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.FromFooSimpleNoGetters; +import com.expediagroup.beans.sample.FromFooSubClass; +import com.expediagroup.beans.sample.FromSubFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToFoo; +import com.expediagroup.beans.sample.immutable.ImmutableToFooAdvFields; +import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; +import com.expediagroup.beans.sample.mutable.MutableToFoo; +import com.expediagroup.beans.sample.mutable.MutableToFooAdvFields; +import com.expediagroup.beans.sample.mutable.MutableToFooSimple; +import com.expediagroup.transformer.constant.MethodPrefix; +import com.expediagroup.transformer.error.MissingFieldException; +import com.expediagroup.transformer.error.MissingMethodException; +import com.expediagroup.transformer.model.ItemType; +import com.expediagroup.transformer.model.MapElemType; +import com.expediagroup.transformer.model.MapType; /** * Unit tests fro class: {@link ReflectionUtils}. @@ -341,11 +339,11 @@ public void testGetGetterMethodPrefixWorksAsExpected(final String testCaseDescri */ @DataProvider private Object[][] dataGetGetterMethodPrefixTesting() throws Exception { - return new Object[][] { - {"Tests that the method returns the prefix: 'get' in case the returned class is a String ", String.class, GET.getPrefix()}, - {"Tests that the method returns the prefix: 'is' in case the returned class is a Boolean", Boolean.class, IS.getPrefix()}, + return new Object[][]{ + {"Tests that the method returns the prefix: 'get' in case the returned class is a String ", String.class, MethodPrefix.GET.getPrefix()}, + {"Tests that the method returns the prefix: 'is' in case the returned class is a Boolean", Boolean.class, MethodPrefix.IS.getPrefix()}, {"Tests that the method returns the prefix: 'is' in case the returned class is a primitive boolean", - FromFooSubClass.class.getDeclaredField(CHECK_FIELD_NAME).getType(), IS.getPrefix()} + FromFooSubClass.class.getDeclaredField(CHECK_FIELD_NAME).getType(), MethodPrefix.IS.getPrefix()} }; } diff --git a/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/package-info.java similarity index 93% rename from bull-common/src/test/java/com/hotels/transformer/utils/package-info.java rename to bull-common/src/test/java/com/expediagroup/transformer/utils/package-info.java index ea1de7df2..943ddc08d 100644 --- a/bull-common/src/test/java/com/hotels/transformer/utils/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/package-info.java @@ -16,4 +16,4 @@ /** * utilities package. */ -package com.hotels.transformer.utils; +package com.expediagroup.transformer.utils; diff --git a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java b/bull-common/src/test/java/com/expediagroup/transformer/validator/ValidatorTest.java similarity index 97% rename from bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java rename to bull-common/src/test/java/com/expediagroup/transformer/validator/ValidatorTest.java index a0b0d7d45..04dff114f 100644 --- a/bull-common/src/test/java/com/hotels/transformer/validator/ValidatorTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/validator/ValidatorTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.transformer.validator; +package com.expediagroup.transformer.validator; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; @@ -31,8 +31,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.sample.mixed.MixedToFoo; -import com.hotels.transformer.error.InvalidBeanException; +import com.expediagroup.beans.sample.mixed.MixedToFoo; +import com.expediagroup.transformer.error.InvalidBeanException; /** * Unit test for {@link Validator}. diff --git a/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java b/bull-common/src/test/java/com/expediagroup/transformer/validator/package-info.java similarity index 93% rename from bull-common/src/test/java/com/hotels/transformer/validator/package-info.java rename to bull-common/src/test/java/com/expediagroup/transformer/validator/package-info.java index b75b0dee1..cc1736cd3 100644 --- a/bull-common/src/test/java/com/hotels/transformer/validator/package-info.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/validator/package-info.java @@ -16,4 +16,4 @@ /** * validator test package. */ -package com.hotels.transformer.validator; +package com.expediagroup.transformer.validator; diff --git a/bull-common/src/test/resources/logback-test.xml b/bull-common/src/test/resources/logback-test.xml index bed93a3ed..24ffad312 100644 --- a/bull-common/src/test/resources/logback-test.xml +++ b/bull-common/src/test/resources/logback-test.xml @@ -31,9 +31,9 @@ - - - + + + diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 590fe2aa9..315fc2384 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -7,14 +7,14 @@ Provides the conversion related classes - com.hotels.beans + com.expediagroup.beans bean-utils-library-parent - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT - com.hotels.beans + com.expediagroup.beans bull-common ${project.version} diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java similarity index 88% rename from bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java index fae081373..4c1e7b8ba 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/Converter.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion; +package com.expediagroup.beans.conversion; import java.util.Optional; import java.util.function.Function; +import com.expediagroup.beans.conversion.error.TypeConversionException; + /** * It allows to convert any primitive type into another. */ @@ -35,10 +37,10 @@ public interface Converter { * Converts a given primitive value into the given primitive type. * @param valueToConvert the value to be converted * @param targetClass the destination field class - * @return the converted value * @param the value to convert type * @param the target object type - * @throws com.hotels.beans.conversion.error.TypeConversionException in case there is no converter for the given class + * @return the converted value + * @throws TypeConversionException in case there is no converter for the given class * @throws IllegalArgumentException in case the destination field type is null. */ K convertValue(T valueToConvert, Class targetClass); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/ConverterImpl.java similarity index 89% rename from bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/ConverterImpl.java index bf52709dd..a22984288 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/ConverterImpl.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/ConverterImpl.java @@ -13,17 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion; +package com.expediagroup.beans.conversion; import static java.util.Objects.isNull; -import static com.hotels.transformer.validator.Validator.notNull; +import static com.expediagroup.transformer.validator.Validator.notNull; import java.util.Optional; import java.util.function.Function; -import com.hotels.beans.conversion.analyzer.ConversionAnalyzer; -import com.hotels.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.analyzer.ConversionAnalyzer; +import com.expediagroup.beans.conversion.error.TypeConversionException; /** * This class provides method for converting a primitive input into another. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/analyzer/ConversionAnalyzer.java similarity index 77% rename from bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/analyzer/ConversionAnalyzer.java index ec578143a..13275934d 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzer.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/analyzer/ConversionAnalyzer.java @@ -13,32 +13,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.analyzer; +package com.expediagroup.beans.conversion.analyzer; import static java.util.Optional.empty; import static java.util.Optional.of; -import static com.hotels.beans.conversion.processor.ConversionProcessorFactory.getConversionProcessor; -import static com.hotels.transformer.cache.CacheManagerFactory.getCacheManager; -import static com.hotels.transformer.utils.ClassUtils.isBigDecimal; -import static com.hotels.transformer.utils.ClassUtils.isBigInteger; -import static com.hotels.transformer.utils.ClassUtils.isBoolean; -import static com.hotels.transformer.utils.ClassUtils.isByte; -import static com.hotels.transformer.utils.ClassUtils.isByteArray; -import static com.hotels.transformer.utils.ClassUtils.isChar; -import static com.hotels.transformer.utils.ClassUtils.isDouble; -import static com.hotels.transformer.utils.ClassUtils.isFloat; -import static com.hotels.transformer.utils.ClassUtils.isInt; -import static com.hotels.transformer.utils.ClassUtils.isLong; -import static com.hotels.transformer.utils.ClassUtils.isShort; -import static com.hotels.transformer.utils.ClassUtils.isString; +import static com.expediagroup.transformer.cache.CacheManagerFactory.getCacheManager; +import static com.expediagroup.transformer.utils.ClassUtils.isBigDecimal; +import static com.expediagroup.transformer.utils.ClassUtils.isBigInteger; +import static com.expediagroup.transformer.utils.ClassUtils.isBoolean; +import static com.expediagroup.transformer.utils.ClassUtils.isByte; +import static com.expediagroup.transformer.utils.ClassUtils.isByteArray; +import static com.expediagroup.transformer.utils.ClassUtils.isChar; +import static com.expediagroup.transformer.utils.ClassUtils.isDouble; +import static com.expediagroup.transformer.utils.ClassUtils.isFloat; +import static com.expediagroup.transformer.utils.ClassUtils.isInt; +import static com.expediagroup.transformer.utils.ClassUtils.isLong; +import static com.expediagroup.transformer.utils.ClassUtils.isShort; +import static com.expediagroup.transformer.utils.ClassUtils.isString; import java.util.Optional; import java.util.function.Function; -import com.hotels.beans.conversion.processor.ConversionProcessor; -import com.hotels.transformer.cache.CacheManager; -import com.hotels.transformer.utils.ClassUtils; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.processor.ConversionProcessorFactory; +import com.expediagroup.transformer.cache.CacheManager; +import com.expediagroup.transformer.utils.ClassUtils; /** * This class provides method for converting a primitive input into another. @@ -74,7 +74,7 @@ public Optional> getConversionFunction(final Class s Optional conversionFunction = empty(); if (!targetClass.getSimpleName().equalsIgnoreCase(sourceClass.getSimpleName()) && (classUtils.isPrimitiveType(sourceClass) || classUtils.isPrimitiveTypeArray(sourceClass))) { - conversionFunction = getConversionProcessor(targetClass) + conversionFunction = ConversionProcessorFactory.getConversionProcessor(targetClass) .flatMap(cp -> getTypeConversionFunction(cp, sourceClass)); } CACHE_MANAGER.cacheObject(cacheKey, conversionFunction); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/analyzer/package-info.java similarity index 92% rename from bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/analyzer/package-info.java index f1dc975b9..ca32fdab9 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/analyzer/package-info.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/analyzer/package-info.java @@ -16,4 +16,4 @@ /** * Type conversion Analyzer package. */ -package com.hotels.beans.conversion.analyzer; +package com.expediagroup.beans.conversion.analyzer; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/error/TypeConversionException.java similarity index 95% rename from bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/error/TypeConversionException.java index a918d7319..cd099e018 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/error/TypeConversionException.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/error/TypeConversionException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.error; +package com.expediagroup.beans.conversion.error; /** * Automatic type conversion exception class. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/error/package-info.java similarity index 92% rename from bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/error/package-info.java index 229077d97..65d3f6148 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/error/package-info.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/error/package-info.java @@ -16,4 +16,4 @@ /** * Converter module exceptions. */ -package com.hotels.beans.conversion.error; +package com.expediagroup.beans.conversion.error; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/package-info.java similarity index 93% rename from bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/package-info.java index 080261582..794e21190 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/package-info.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/package-info.java @@ -16,4 +16,4 @@ /** * Type Conversion package. */ -package com.hotels.beans.conversion; +package com.expediagroup.beans.conversion; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/ConversionProcessor.java similarity index 92% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/ConversionProcessor.java index 3162af14d..bd5f77107 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/ConversionProcessor.java @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor; +package com.expediagroup.beans.conversion.processor; import java.math.BigDecimal; import java.math.BigInteger; import java.util.function.Function; +import com.expediagroup.beans.conversion.error.TypeConversionException; + /** * Conversion methods for all primitive types. * @param indicates any primitive type object @@ -33,7 +35,7 @@ public interface ConversionProcessor { /** * Converts a byte[] type. * @return the converted value - * @throws com.hotels.beans.conversion.error.TypeConversionException if the number of bytes in the array is less + * @throws TypeConversionException if the number of bytes in the array is less * than the minimum required to create the destination type */ Function convertByteArray(); diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/ConversionProcessorFactory.java similarity index 59% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/ConversionProcessorFactory.java index bae715b30..a3f818bd8 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/ConversionProcessorFactory.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/ConversionProcessorFactory.java @@ -13,40 +13,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor; +package com.expediagroup.beans.conversion.processor; import static java.util.Optional.empty; import static java.util.Optional.of; -import static com.hotels.transformer.utils.ClassUtils.isBigDecimal; -import static com.hotels.transformer.utils.ClassUtils.isBigInteger; -import static com.hotels.transformer.utils.ClassUtils.isBoolean; -import static com.hotels.transformer.utils.ClassUtils.isByte; -import static com.hotels.transformer.utils.ClassUtils.isByteArray; -import static com.hotels.transformer.utils.ClassUtils.isChar; -import static com.hotels.transformer.utils.ClassUtils.isDouble; -import static com.hotels.transformer.utils.ClassUtils.isFloat; -import static com.hotels.transformer.utils.ClassUtils.isInt; -import static com.hotels.transformer.utils.ClassUtils.isLong; -import static com.hotels.transformer.utils.ClassUtils.isShort; -import static com.hotels.transformer.utils.ClassUtils.isString; +import static com.expediagroup.transformer.utils.ClassUtils.isBigDecimal; +import static com.expediagroup.transformer.utils.ClassUtils.isBigInteger; +import static com.expediagroup.transformer.utils.ClassUtils.isBoolean; +import static com.expediagroup.transformer.utils.ClassUtils.isByte; +import static com.expediagroup.transformer.utils.ClassUtils.isByteArray; +import static com.expediagroup.transformer.utils.ClassUtils.isChar; +import static com.expediagroup.transformer.utils.ClassUtils.isDouble; +import static com.expediagroup.transformer.utils.ClassUtils.isFloat; +import static com.expediagroup.transformer.utils.ClassUtils.isInt; +import static com.expediagroup.transformer.utils.ClassUtils.isLong; +import static com.expediagroup.transformer.utils.ClassUtils.isShort; +import static com.expediagroup.transformer.utils.ClassUtils.isString; import static lombok.AccessLevel.PRIVATE; import java.util.Optional; -import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; -import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; -import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; -import com.hotels.beans.conversion.processor.impl.ByteArrayConversionProcessor; -import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; -import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; -import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; -import com.hotels.beans.conversion.processor.impl.FloatConversionProcessor; -import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; -import com.hotels.beans.conversion.processor.impl.LongConversionProcessor; -import com.hotels.beans.conversion.processor.impl.ShortConversionProcessor; -import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BigDecimalConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BigIntegerConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BooleanConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.ByteArrayConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.ByteConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.CharacterConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.DoubleConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.FloatConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.IntegerConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.LongConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.ShortConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.StringConversionProcessor; import lombok.NoArgsConstructor; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/BigDecimalConversionProcessor.java similarity index 94% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/BigDecimalConversionProcessor.java index cd5aee8cc..5953c95ca 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/BigDecimalConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; @@ -25,8 +25,8 @@ import java.nio.BufferUnderflowException; import java.util.function.Function; -import com.hotels.beans.conversion.error.TypeConversionException; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link BigDecimal}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/BigIntegerConversionProcessor.java similarity index 94% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/BigIntegerConversionProcessor.java index c1a5f3546..f8b0c5551 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/BigIntegerConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; @@ -25,8 +25,8 @@ import java.nio.BufferUnderflowException; import java.util.function.Function; -import com.hotels.beans.conversion.error.TypeConversionException; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link BigInteger}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/BooleanConversionProcessor.java similarity index 95% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/BooleanConversionProcessor.java index b7e1a7abf..887a1b5cb 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/BooleanConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/BooleanConversionProcessor.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import java.math.BigDecimal; import java.math.BigInteger; import java.util.function.Function; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link Boolean}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/ByteArrayConversionProcessor.java similarity index 95% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/ByteArrayConversionProcessor.java index 06e5a3980..ac15ec116 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/ByteArrayConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; @@ -21,7 +21,7 @@ import java.math.BigInteger; import java.util.function.Function; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a byte[]. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/ByteConversionProcessor.java similarity index 95% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/ByteConversionProcessor.java index 42f174fe4..460efe8f9 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ByteConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/ByteConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; @@ -21,7 +21,7 @@ import java.math.BigInteger; import java.util.function.Function; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link Byte}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/CharacterConversionProcessor.java similarity index 94% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/CharacterConversionProcessor.java index 423d655ab..a468e7d8a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/CharacterConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/CharacterConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; import static java.nio.ByteBuffer.wrap; @@ -23,8 +23,8 @@ import java.nio.BufferUnderflowException; import java.util.function.Function; -import com.hotels.beans.conversion.error.TypeConversionException; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link Character}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/DoubleConversionProcessor.java similarity index 93% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/DoubleConversionProcessor.java index 34b8d6f50..05c396aa7 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/DoubleConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/DoubleConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; @@ -24,8 +24,8 @@ import java.nio.BufferUnderflowException; import java.util.function.Function; -import com.hotels.beans.conversion.error.TypeConversionException; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link Double}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/FloatConversionProcessor.java similarity index 93% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/FloatConversionProcessor.java index 7b801ba05..092815f39 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/FloatConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/FloatConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; @@ -24,8 +24,8 @@ import java.nio.BufferUnderflowException; import java.util.function.Function; -import com.hotels.beans.conversion.error.TypeConversionException; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link Float}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/IntegerConversionProcessor.java similarity index 93% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/IntegerConversionProcessor.java index 41934416f..13404fa60 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/IntegerConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/IntegerConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; import static java.nio.ByteBuffer.wrap; @@ -23,8 +23,8 @@ import java.nio.BufferUnderflowException; import java.util.function.Function; -import com.hotels.beans.conversion.error.TypeConversionException; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link Integer}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/LongConversionProcessor.java similarity index 93% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/LongConversionProcessor.java index b8f550d08..cd7d47a39 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/LongConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/LongConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; @@ -24,8 +24,8 @@ import java.nio.BufferUnderflowException; import java.util.function.Function; -import com.hotels.beans.conversion.error.TypeConversionException; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link Long}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/ShortConversionProcessor.java similarity index 93% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/ShortConversionProcessor.java index 821397fb2..5abb388f6 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/ShortConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/ShortConversionProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Boolean.TRUE; import static java.lang.Character.getNumericValue; @@ -24,8 +24,8 @@ import java.nio.BufferUnderflowException; import java.util.function.Function; -import com.hotels.beans.conversion.error.TypeConversionException; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link Short}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/StringConversionProcessor.java similarity index 95% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/StringConversionProcessor.java index 57a76ce7e..691f6915a 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/StringConversionProcessor.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/StringConversionProcessor.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import java.math.BigDecimal; import java.math.BigInteger; import java.util.function.Function; -import com.hotels.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; /** * Provides all method for converting any primitive type to a {@link String}. diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/package-info.java similarity index 91% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/package-info.java index 6981783d5..491168190 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/impl/package-info.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/impl/package-info.java @@ -16,4 +16,4 @@ /** * Implementations of processors package. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; diff --git a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/package-info.java similarity index 92% rename from bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java rename to bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/package-info.java index a8471c2f7..6d19e0f62 100644 --- a/bull-converter/src/main/java/com/hotels/beans/conversion/processor/package-info.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/processor/package-info.java @@ -16,4 +16,4 @@ /** * Type conversion processor package. */ -package com.hotels.beans.conversion.processor; +package com.expediagroup.beans.conversion.processor; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/AbstractConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/AbstractConversionTest.java index 3e961449b..2dc6de0f4 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/AbstractConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/AbstractConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion; +package com.expediagroup.beans.conversion; /** * Abstract class containing all methods/fields common to all Conversion test classes. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/ConverterTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/ConverterTest.java index 23323432e..c1414125a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/ConverterTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/ConverterTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion; +package com.expediagroup.beans.conversion; import static java.lang.Character.getNumericValue; import static java.math.BigInteger.ZERO; @@ -36,16 +36,17 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.error.TypeConversionException; -import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; -import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; -import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; -import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; -import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; -import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; -import com.hotels.beans.conversion.processor.impl.FloatConversionProcessor; -import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; -import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; +import com.expediagroup.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BigDecimalConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BigIntegerConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BooleanConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.ByteConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.CharacterConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.DoubleConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.FloatConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.IntegerConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.StringConversionProcessor; /** * Unit test for {@link Converter}. @@ -109,7 +110,7 @@ private Object[][] dataGetConversionFunctionEmptyCaseTesting() { * @param testCaseDescription the test case description * @param sourceFieldType source field class * @param destinationFieldType the destination field class - * @param expectedConversionFunction the expected {@link com.hotels.beans.conversion.processor.ConversionProcessor} instance + * @param expectedConversionFunction the expected {@link ConversionProcessor} instance */ @SuppressWarnings("unchecked") @Test(dataProvider = "dataGetConversionFunctionTesting") diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/analyzer/ConversionAnalyzerTest.java similarity index 87% rename from bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/analyzer/ConversionAnalyzerTest.java index 77891c652..fe6e2ed42 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/ConversionAnalyzerTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/analyzer/ConversionAnalyzerTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.analyzer; +package com.expediagroup.beans.conversion.analyzer; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.openMocks; @@ -29,16 +29,17 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; -import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; -import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; -import com.hotels.beans.conversion.processor.impl.ByteArrayConversionProcessor; -import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; -import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; -import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; -import com.hotels.beans.conversion.processor.impl.FloatConversionProcessor; -import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; -import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; +import com.expediagroup.beans.conversion.processor.ConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BigDecimalConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BigIntegerConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BooleanConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.ByteArrayConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.ByteConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.CharacterConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.DoubleConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.FloatConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.IntegerConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.StringConversionProcessor; /** * Unit test for {@link ConversionAnalyzer}. @@ -100,7 +101,7 @@ private Object[][] dataGetConversionFunctionEmptyCaseTesting() { * @param testCaseDescription the test case description * @param sourceFieldType source field class * @param destinationFieldType the destination field class - * @param expectedConversionFunction the expected {@link com.hotels.beans.conversion.processor.ConversionProcessor} instance + * @param expectedConversionFunction the expected {@link ConversionProcessor} instance */ @Test(dataProvider = "dataGetConversionFunctionTesting") public void testGetConversionFunctionReturnsTheExpectedConversionFunction(final String testCaseDescription, final Class sourceFieldType, diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/analyzer/package-info.java similarity index 92% rename from bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/analyzer/package-info.java index 96aa5bc46..84747a482 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/analyzer/package-info.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/analyzer/package-info.java @@ -16,4 +16,4 @@ /** * Type conversion Analyzer test package. */ -package com.hotels.beans.conversion.analyzer; +package com.expediagroup.beans.conversion.analyzer; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/package-info.java similarity index 93% rename from bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/package-info.java index f537bdde8..5ef657589 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/package-info.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/package-info.java @@ -16,4 +16,4 @@ /** * Type conversion test package. */ -package com.hotels.beans.conversion; +package com.expediagroup.beans.conversion; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/ConversionProcessorFactoryTest.java similarity index 83% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/ConversionProcessorFactoryTest.java index 68d009307..53eccacd7 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/ConversionProcessorFactoryTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/ConversionProcessorFactoryTest.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor; +package com.expediagroup.beans.conversion.processor; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.openMocks; import java.math.BigDecimal; @@ -23,23 +22,24 @@ import java.util.Optional; import org.apache.commons.lang3.tuple.Pair; +import org.assertj.core.api.Assertions; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.processor.impl.BigDecimalConversionProcessor; -import com.hotels.beans.conversion.processor.impl.BigIntegerConversionProcessor; -import com.hotels.beans.conversion.processor.impl.BooleanConversionProcessor; -import com.hotels.beans.conversion.processor.impl.ByteArrayConversionProcessor; -import com.hotels.beans.conversion.processor.impl.ByteConversionProcessor; -import com.hotels.beans.conversion.processor.impl.CharacterConversionProcessor; -import com.hotels.beans.conversion.processor.impl.DoubleConversionProcessor; -import com.hotels.beans.conversion.processor.impl.FloatConversionProcessor; -import com.hotels.beans.conversion.processor.impl.IntegerConversionProcessor; -import com.hotels.beans.conversion.processor.impl.LongConversionProcessor; -import com.hotels.beans.conversion.processor.impl.ShortConversionProcessor; -import com.hotels.beans.conversion.processor.impl.StringConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BigDecimalConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BigIntegerConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.BooleanConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.ByteArrayConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.ByteConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.CharacterConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.DoubleConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.FloatConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.IntegerConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.LongConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.ShortConversionProcessor; +import com.expediagroup.beans.conversion.processor.impl.StringConversionProcessor; /** * Unit test for {@link ConversionProcessorFactory}. @@ -70,7 +70,7 @@ public void testGetConversionProcessorReturnsNullInCaseNoProcessorExistsForTheGi Optional actual = underTest.getConversionProcessor(Pair.class); // THEN - assertThat(actual).isEmpty(); + Assertions.assertThat(actual).isEmpty(); } /** @@ -88,7 +88,7 @@ public void testGetConversionProcessorWorksAsExpected(final String testCaseDescr Optional actual = underTest.getConversionProcessor(targetClass); // THEN - assertThat(actual).containsInstanceOf(expectedResult); + Assertions.assertThat(actual).containsInstanceOf(expectedResult); } /** diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/BigDecimalConversionTest.java similarity index 96% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/BigDecimalConversionTest.java index bea3cca92..57cf763e5 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigDecimalConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/BigDecimalConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; import static java.math.BigDecimal.valueOf; @@ -30,8 +30,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; -import com.hotels.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.error.TypeConversionException; /** * Unit test for {@link BigDecimalConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/BigIntegerConversionTest.java similarity index 96% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/BigIntegerConversionTest.java index 63ef0a873..bf57a10d5 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BigIntegerConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/BigIntegerConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; import static java.math.BigInteger.valueOf; @@ -30,8 +30,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; -import com.hotels.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.error.TypeConversionException; /** * Unit test for {@link BigIntegerConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/BooleanConversionTest.java similarity index 99% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/BooleanConversionTest.java index 5428ccea8..c02b772b0 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/BooleanConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/BooleanConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.openMocks; @@ -26,7 +26,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.AbstractConversionTest; /** * Unit test for {@link BooleanConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/ByteArrayConversionTest.java similarity index 98% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/ByteArrayConversionTest.java index 5a8256d0f..82da5a615 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteArrayConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/ByteArrayConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.openMocks; @@ -26,7 +26,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.AbstractConversionTest; /** * Unit test for {@link ByteArrayConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/ByteConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/ByteConversionTest.java index c1e8c6c62..89a24b072 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ByteConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/ByteConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.openMocks; @@ -26,7 +26,7 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.AbstractConversionTest; /** * Unit test for {@link ByteConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/CharacterConversionTest.java similarity index 96% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/CharacterConversionTest.java index 8c46c1dc7..1a9a8a3b5 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/CharacterConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/CharacterConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.nio.ByteBuffer.wrap; @@ -28,8 +28,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; -import com.hotels.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.error.TypeConversionException; /** * Unit test for {@link CharacterConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/DoubleConversionTest.java similarity index 96% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/DoubleConversionTest.java index 92d1b35fe..9272e3d8e 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/DoubleConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/DoubleConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Double.valueOf; import static java.nio.ByteBuffer.wrap; @@ -29,8 +29,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; -import com.hotels.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.error.TypeConversionException; /** * Unit test for {@link DoubleConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/FloatConversionTest.java similarity index 96% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/FloatConversionTest.java index 4a75e6714..09d4ef441 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/FloatConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/FloatConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Float.valueOf; import static java.nio.ByteBuffer.wrap; @@ -29,8 +29,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; -import com.hotels.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.error.TypeConversionException; /** * Unit test for {@link FloatConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/IntegerConversionTest.java similarity index 96% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/IntegerConversionTest.java index 02f49ec44..29ec2027c 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/IntegerConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/IntegerConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.nio.ByteBuffer.wrap; @@ -28,8 +28,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; -import com.hotels.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.error.TypeConversionException; /** * Unit test for {@link IntegerConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/LongConversionTest.java similarity index 96% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/LongConversionTest.java index ce2141b54..637a498a0 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/LongConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/LongConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.nio.ByteBuffer.wrap; @@ -28,8 +28,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; -import com.hotels.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.error.TypeConversionException; /** * Unit test for {@link LongConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/ShortConversionTest.java similarity index 96% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/ShortConversionTest.java index 1aadb290f..18c6b32ea 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/ShortConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/ShortConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.Character.getNumericValue; import static java.lang.Short.valueOf; @@ -30,8 +30,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; -import com.hotels.beans.conversion.error.TypeConversionException; +import com.expediagroup.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.error.TypeConversionException; /** * Unit test for {@link ShortConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/StringConversionTest.java similarity index 97% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/StringConversionTest.java index 423b5c171..10653882a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/StringConversionTest.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/StringConversionTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; import static java.lang.String.valueOf; @@ -27,7 +27,7 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import com.hotels.beans.conversion.AbstractConversionTest; +import com.expediagroup.beans.conversion.AbstractConversionTest; /** * Unit test for {@link StringConversionProcessor}. diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/package-info.java similarity index 92% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/package-info.java index 594861183..0465c7ac2 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/impl/package-info.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/impl/package-info.java @@ -16,4 +16,4 @@ /** * Type conversion processor implementation test package. */ -package com.hotels.beans.conversion.processor.impl; +package com.expediagroup.beans.conversion.processor.impl; diff --git a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/package-info.java similarity index 92% rename from bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java rename to bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/package-info.java index 2c6cf639d..60fc53a7a 100644 --- a/bull-converter/src/test/java/com/hotels/beans/conversion/processor/package-info.java +++ b/bull-converter/src/test/java/com/expediagroup/beans/conversion/processor/package-info.java @@ -16,4 +16,4 @@ /** * Type conversion processor test package. */ -package com.hotels.beans.conversion.processor; +package com.expediagroup.beans.conversion.processor; diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0a74d1d39..2b7e6a682 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -8,19 +8,19 @@ bean-utils-library-parent - com.hotels.beans - 2.0.2-SNAPSHOT + com.expediagroup.beans + 2.1.0-SNAPSHOT - com.hotels.beans + com.expediagroup.beans bull-bean-transformer ${project.version} - com.hotels.beans + com.expediagroup.beans bull-common ${project.version} test-jar diff --git a/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java b/bull-map-transformer/src/main/java/com/expediagroup/map/MapUtils.java similarity index 85% rename from bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java rename to bull-map-transformer/src/main/java/com/expediagroup/map/MapUtils.java index 9880c86b1..2f48f21ff 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/MapUtils.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/MapUtils.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.map; +package com.expediagroup.map; -import com.hotels.map.transformer.MapTransformer; -import com.hotels.map.transformer.MapTransformerImpl; +import com.expediagroup.map.transformer.MapTransformer; +import com.expediagroup.map.transformer.MapTransformerImpl; /** * Set of Map utilities. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/package-info.java b/bull-map-transformer/src/main/java/com/expediagroup/map/package-info.java similarity index 95% rename from bull-map-transformer/src/main/java/com/hotels/map/package-info.java rename to bull-map-transformer/src/main/java/com/expediagroup/map/package-info.java index fdb860df0..ccc3c4b9a 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/package-info.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/package-info.java @@ -16,4 +16,4 @@ /** * Map transformer main package. */ -package com.hotels.map; +package com.expediagroup.map; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java similarity index 90% rename from bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java rename to bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java index 9cf8a763b..8557b83f6 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.map.transformer; +package com.expediagroup.map.transformer; import java.util.Map; -import com.hotels.beans.BeanUtils; -import com.hotels.map.transformer.model.MapTransformerSettings; -import com.hotels.transformer.AbstractTransformer; -import com.hotels.transformer.model.FieldTransformer; +import com.expediagroup.beans.BeanUtils; +import com.expediagroup.map.transformer.model.MapTransformerSettings; +import com.expediagroup.transformer.AbstractTransformer; +import com.expediagroup.transformer.model.FieldTransformer; /** * Utility methods for populating {@link java.util.Map} elements via reflection.. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/MapTransformer.java similarity index 95% rename from bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java rename to bull-map-transformer/src/main/java/com/expediagroup/map/transformer/MapTransformer.java index 82a1e134c..e5546b990 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformer.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/MapTransformer.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.map.transformer; +package com.expediagroup.map.transformer; import java.util.Map; -import com.hotels.beans.transformer.BeanTransformer; -import com.hotels.transformer.Transformer; -import com.hotels.transformer.model.FieldTransformer; +import com.expediagroup.beans.transformer.BeanTransformer; +import com.expediagroup.transformer.Transformer; +import com.expediagroup.transformer.model.FieldTransformer; /** * Utility methods for populating {@link java.util.Map} elements via reflection. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/MapTransformerImpl.java similarity index 93% rename from bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java rename to bull-map-transformer/src/main/java/com/expediagroup/map/transformer/MapTransformerImpl.java index dbb643906..161ba3059 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/MapTransformerImpl.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/MapTransformerImpl.java @@ -13,20 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.map.transformer; +package com.expediagroup.map.transformer; import static java.util.Objects.nonNull; import static java.util.stream.Collectors.toMap; -import static com.hotels.beans.populator.PopulatorFactory.getPopulator; -import static com.hotels.transformer.validator.Validator.notNull; +import static com.expediagroup.beans.populator.PopulatorFactory.getPopulator; +import static com.expediagroup.transformer.validator.Validator.notNull; import java.util.HashMap; import java.util.Map; -import com.hotels.beans.transformer.BeanTransformer; -import com.hotels.transformer.error.InvalidFunctionException; -import com.hotels.transformer.model.FieldTransformer; +import com.expediagroup.beans.transformer.BeanTransformer; +import com.expediagroup.transformer.error.InvalidFunctionException; +import com.expediagroup.transformer.model.FieldTransformer; /** * Utility methods for populating {@link java.util.Map} elements via reflection. diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java similarity index 89% rename from bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java rename to bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java index 2cf2a4123..2f56a242c 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/MapTransformerSettings.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.map.transformer.model; +package com.expediagroup.map.transformer.model; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import com.hotels.transformer.model.FieldTransformer; -import com.hotels.transformer.model.TransformerSettings; +import com.expediagroup.transformer.model.FieldTransformer; +import com.expediagroup.transformer.model.TransformerSettings; import lombok.Getter; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/package-info.java similarity index 92% rename from bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java rename to bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/package-info.java index 0dcb26136..8d1cda8e0 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/model/package-info.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/package-info.java @@ -16,4 +16,4 @@ /** * Pojo package. */ -package com.hotels.map.transformer.model; +package com.expediagroup.map.transformer.model; diff --git a/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/package-info.java similarity index 93% rename from bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java rename to bull-map-transformer/src/main/java/com/expediagroup/map/transformer/package-info.java index 2e87cae99..3ef88eccf 100644 --- a/bull-map-transformer/src/main/java/com/hotels/map/transformer/package-info.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/package-info.java @@ -16,4 +16,4 @@ /** * Map transformer package. */ -package com.hotels.map.transformer; +package com.expediagroup.map.transformer; diff --git a/bull-map-transformer/src/main/resources/logback.xml b/bull-map-transformer/src/main/resources/logback.xml index 26f67b0c5..741ee5b6d 100644 --- a/bull-map-transformer/src/main/resources/logback.xml +++ b/bull-map-transformer/src/main/resources/logback.xml @@ -31,9 +31,9 @@ - - - + + + diff --git a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java b/bull-map-transformer/src/test/java/com/expediagroup/map/MapUtilsTest.java similarity index 94% rename from bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java rename to bull-map-transformer/src/test/java/com/expediagroup/map/MapUtilsTest.java index b9cb40e61..56cc82b40 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/MapUtilsTest.java +++ b/bull-map-transformer/src/test/java/com/expediagroup/map/MapUtilsTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.map; +package com.expediagroup.map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.MockitoAnnotations.openMocks; @@ -22,7 +22,7 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import com.hotels.map.transformer.MapTransformer; +import com.expediagroup.map.transformer.MapTransformer; /** * Unit test for {@link MapUtils}. diff --git a/bull-map-transformer/src/test/java/com/hotels/map/package-info.java b/bull-map-transformer/src/test/java/com/expediagroup/map/package-info.java similarity index 95% rename from bull-map-transformer/src/test/java/com/hotels/map/package-info.java rename to bull-map-transformer/src/test/java/com/expediagroup/map/package-info.java index f699a513a..efc1d07b7 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/package-info.java +++ b/bull-map-transformer/src/test/java/com/expediagroup/map/package-info.java @@ -16,4 +16,4 @@ /** * Map Transformer Test package. */ -package com.hotels.map; +package com.expediagroup.map; diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java b/bull-map-transformer/src/test/java/com/expediagroup/map/transformer/MapTransformerTest.java similarity index 93% rename from bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java rename to bull-map-transformer/src/test/java/com/expediagroup/map/transformer/MapTransformerTest.java index 7d8c35bb8..6f1ed1b70 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/MapTransformerTest.java +++ b/bull-map-transformer/src/test/java/com/expediagroup/map/transformer/MapTransformerTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.hotels.map.transformer; +package com.expediagroup.map.transformer; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; @@ -35,16 +35,16 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import com.hotels.beans.BeanUtils; -import com.hotels.beans.sample.FromFooSimple; -import com.hotels.beans.sample.mutable.MutableToFooSimple; -import com.hotels.beans.transformer.BeanTransformer; -import com.hotels.map.transformer.model.MapTransformerSettings; -import com.hotels.transformer.AbstractTransformerTest; -import com.hotels.transformer.error.InvalidFunctionException; -import com.hotels.transformer.model.FieldMapping; -import com.hotels.transformer.model.FieldTransformer; -import com.hotels.transformer.model.TransformerSettings; +import com.expediagroup.beans.BeanUtils; +import com.expediagroup.beans.sample.FromFooSimple; +import com.expediagroup.beans.sample.mutable.MutableToFooSimple; +import com.expediagroup.beans.transformer.BeanTransformer; +import com.expediagroup.map.transformer.model.MapTransformerSettings; +import com.expediagroup.transformer.AbstractTransformerTest; +import com.expediagroup.transformer.error.InvalidFunctionException; +import com.expediagroup.transformer.model.FieldMapping; +import com.expediagroup.transformer.model.FieldTransformer; +import com.expediagroup.transformer.model.TransformerSettings; /** * Unit test for {@link MapTransformer}. diff --git a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java b/bull-map-transformer/src/test/java/com/expediagroup/map/transformer/package-info.java similarity index 93% rename from bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java rename to bull-map-transformer/src/test/java/com/expediagroup/map/transformer/package-info.java index 2e87cae99..3ef88eccf 100644 --- a/bull-map-transformer/src/test/java/com/hotels/map/transformer/package-info.java +++ b/bull-map-transformer/src/test/java/com/expediagroup/map/transformer/package-info.java @@ -16,4 +16,4 @@ /** * Map transformer package. */ -package com.hotels.map.transformer; +package com.expediagroup.map.transformer; diff --git a/bull-map-transformer/src/test/resources/config/logback-test.xml b/bull-map-transformer/src/test/resources/config/logback-test.xml index 3ab1d694f..f61116f01 100644 --- a/bull-map-transformer/src/test/resources/config/logback-test.xml +++ b/bull-map-transformer/src/test/resources/config/logback-test.xml @@ -31,9 +31,9 @@ - - - + + + diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 2d94162ac..49e648d7f 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -7,8 +7,8 @@ bean-utils-library-parent - com.hotels.beans - 2.0.2-SNAPSHOT + com.expediagroup.beans + 2.1.0-SNAPSHOT @@ -17,22 +17,22 @@ - com.hotels.beans + com.expediagroup.beans bull-common ${project.version} - com.hotels.beans + com.expediagroup.beans bull-converter ${project.version} - com.hotels.beans + com.expediagroup.beans bull-bean-transformer ${project.version} - com.hotels.beans + com.expediagroup.beans bull-map-transformer ${project.version} diff --git a/docs/site/markdown/kotlin.md b/docs/site/markdown/kotlin.md index b2a2e0d2b..48cc2b6e6 100644 --- a/docs/site/markdown/kotlin.md +++ b/docs/site/markdown/kotlin.md @@ -13,7 +13,7 @@ Add the project dependency into your `pom.xml` file: ```xml - com.hotels.beans + com.expediagroup.beans bull-bean-transformer x.y.z diff --git a/docs/site/markdown/transformer/bean/builder.md b/docs/site/markdown/transformer/bean/builder.md index 286e175f1..62f8fe312 100644 --- a/docs/site/markdown/transformer/bean/builder.md +++ b/docs/site/markdown/transformer/bean/builder.md @@ -41,7 +41,7 @@ public class ItemType { return this; } - public com.hotels.transformer.model.ItemType build() { + public com.expediagroup.transformer.model.ItemType build() { return new ItemType(this.objectClass, this.genericClass); } } @@ -85,7 +85,7 @@ public class ItemType { return this; } - public com.hotels.transformer.model.ItemType build() { + public com.expediagroup.transformer.model.ItemType build() { return new ItemType(this); } } diff --git a/docs/site/markdown/transformer/bean/samples.md b/docs/site/markdown/transformer/bean/samples.md index 50df7e1be..b4707bcad 100644 --- a/docs/site/markdown/transformer/bean/samples.md +++ b/docs/site/markdown/transformer/bean/samples.md @@ -494,4 +494,5 @@ And one line code as: var toBean = beanUtils.getTransformer().transform(fromBean, RecordToFoo.class); ``` -More sample beans can be found in the test package: `com.hotels.beans.sample` or on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) \ No newline at end of file +More sample beans can be found in the test package: `com.expediagroup.beans.sample` or on +DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) \ No newline at end of file diff --git a/docs/site/markdown/transformer/bean/testing.md b/docs/site/markdown/transformer/bean/testing.md index d5e92b9e1..0603d646b 100644 --- a/docs/site/markdown/transformer/bean/testing.md +++ b/docs/site/markdown/transformer/bean/testing.md @@ -79,9 +79,9 @@ import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; -import com.hotels.beans.transformer.BeanUtils; -import com.hotels.transformer.Transformer; -import com.hotels.transformer.error.InvalidBeanException; +import com.expediagroup.beans.transformer.BeanUtils; +import com.expediagroup.transformer.Transformer; +import com.expediagroup.transformer.error.InvalidBeanException; /** * Unit test for {@link SampleClass}. @@ -196,9 +196,9 @@ import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; -import com.hotels.beans.transformer.BeanUtils; -import com.hotels.transformer.Transformer; -import com.hotels.transformer.error.InvalidBeanException; +import com.expediagroup.beans.transformer.BeanUtils; +import com.expediagroup.transformer.Transformer; +import com.expediagroup.transformer.error.InvalidBeanException; /** * Unit test for {@link SampleClass}. @@ -315,7 +315,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; -import com.hotels.beans.transformer.BeanUtils; +import com.expediagroup.beans.transformer.BeanUtils; /** * Unit test for {@link SampleClass}. diff --git a/docs/site/markdown/transformer/mapTransformer.md b/docs/site/markdown/transformer/mapTransformer.md index 6a8958689..590048473 100644 --- a/docs/site/markdown/transformer/mapTransformer.md +++ b/docs/site/markdown/transformer/mapTransformer.md @@ -15,7 +15,7 @@ You can obtain BULL from Maven Central: ```xml - com.hotels.beans + com.expediagroup.beans bull-map-transformer x.y.z diff --git a/pom.xml b/pom.xml index 92bfa4156..b81e93297 100644 --- a/pom.xml +++ b/pom.xml @@ -18,10 +18,10 @@ 4.0.0 BULL - Bean Utils Light Library - com.hotels.beans + com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.0.2-SNAPSHOT + 2.1.0-SNAPSHOT pom 2019 @@ -521,9 +521,9 @@ ${test.coverage.check.skip} - com/hotels/transformer/** - com/hotels/beans/** - com/hotels/map/** + com/expediagroup/transformer/** + com/expediagroup/beans/** + com/expediagroup/map/** **/Test*.* From 76fe2ed75143b7c90188a919223d0de582abc21c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 23 Jul 2021 15:59:53 +0200 Subject: [PATCH 1498/1786] formatting fix --- CHANGELOG-JDK11.md | 6 ------ CHANGELOG.md | 6 ------ 2 files changed, 12 deletions(-) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index 1c9016f02..8fb0c0f79 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -3,21 +3,15 @@ All notable changes to this project will be documented in this file. ### [2.0.0-jdk11] 2021.07.23 - #### Adds - * Renames the package from `com.hotels` to `com.expediagroup` ### [1.7.7] 2021.06.23 - #### Changed - * Fixes an issue that was preventing the transformation of Object type fields ### [1.7.6] 2021.01.11 - #### Added - * Provides new module `bull-bom` that includes all the project modules ### [1.7.4] 2020.10.07 diff --git a/CHANGELOG.md b/CHANGELOG.md index 230704864..8422555c8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,21 +3,15 @@ All notable changes to this project will be documented in this file. ### [2.1.0] 2021.07.23 - #### Adds - * Renames the package from `com.hotels` to `com.expediagroup` ### [2.0.1.1] 2021.06.24 - #### Adds - * Adds the javadoc generation to the release ### [2.0.1] 2021.06.23 - #### Changed - * Fixes an issue that was preventing the transformation of Object type fields ### [2.0.0] 2021.06.18 From 5809cbfa4371d0212c83311b747f7c324dfcb94c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 23 Jul 2021 17:02:15 +0200 Subject: [PATCH 1499/1786] updates the key used for the artifact deploy --- .../github-jdk11-release-actions.yml | 20 +++++++++---------- .github/workflows/github-release-actions.yml | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 811e94d6b..a434fb21d 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -23,23 +23,23 @@ jobs: echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/} - - name: "JDK 11 set-up" + - name: "Project version set" + env: + TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} + run: | + mvn versions:set -D newVersion=${TAG_NAME} + - name: "JDK set-up" uses: actions/setup-java@v2 with: java-version: '11' distribution: 'adopt' server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy - server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy + server-username: SONATYPE_USERNAME # env variable for username in deploy + server-password: SONATYPE_PASSWORD # env variable for token in deploy # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase settings-path: ${{ github.workspace }} - - name: "Project version set" - env: - TAG_NAME: ${{ steps.build_info.outputs.TAG_NAME }} - run: | - mvn versions:set -D newVersion=${TAG_NAME} - name: "Quality check" env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} @@ -54,8 +54,8 @@ jobs: mvn site:site javadoc:aggregate -P site-release -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -q -DskipTests=true - name: "Release artifacts" env: - HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} - HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} run: | mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index bc88ff698..96d24ed06 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -34,8 +34,8 @@ jobs: java-version: '15' distribution: 'adopt' server-id: oss-sonatype # Value of the distributionManagement/repository/id field of the pom.xml - server-username: HCOM_SONATYPE_USERNAME # env variable for username in deploy - server-password: HCOM_SONATYPE_PASSWORD # env variable for token in deploy + server-username: SONATYPE_USERNAME # env variable for username in deploy + server-password: SONATYPE_PASSWORD # env variable for token in deploy # only signed artifacts will be released to maven central. this sets up things for the maven-gpg-plugin gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: GPG_PASSPHRASE # env variable for GPG private key passphrase @@ -61,8 +61,8 @@ jobs: user_email: oss@expediagroup.com - name: "Release artifacts" env: - HCOM_SONATYPE_USERNAME: ${{ secrets.HCOM_SONATYPE_USERNAME }} - HCOM_SONATYPE_PASSWORD: ${{ secrets.HCOM_SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} run: | mvn deploy --settings $GITHUB_WORKSPACE/settings.xml -B -U -P release -DskipTests=true From 4d304639a9f5b517dd49802cee309833b9c32386 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 23 Jul 2021 17:03:38 +0200 Subject: [PATCH 1500/1786] [maven-release-plugin] prepare release 2.1.0 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index e16f87b69..003c0442b 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.0-SNAPSHOT + 2.1.0 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 8d022ceea..46ff5373c 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.0-SNAPSHOT + 2.1.0 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 911a9a566..3d1aabac5 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.0-SNAPSHOT + 2.1.0 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 315fc2384..bd89c6250 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.0-SNAPSHOT + 2.1.0 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 2b7e6a682..fac0454d0 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.0-SNAPSHOT + 2.1.0 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 49e648d7f..ad7cc440e 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.0-SNAPSHOT + 2.1.0 diff --git a/pom.xml b/pom.xml index b81e93297..ba09a3b53 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.0-SNAPSHOT + 2.1.0 pom 2019 @@ -108,7 +108,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.1.0 From 05f43bc60d08a93182b107421f417d5de0ac3f54 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 23 Jul 2021 17:03:45 +0200 Subject: [PATCH 1501/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 003c0442b..7030473e2 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 46ff5373c..2f321b5e2 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 3d1aabac5..5d73415c1 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index bd89c6250..0f7910941 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index fac0454d0..0c49e825a 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index ad7cc440e..c13482418 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index ba09a3b53..2ced15009 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.0 + 2.1.1-SNAPSHOT pom 2019 @@ -108,7 +108,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.1.0 + HEAD From df09b9c344f9aad15ac374dc1d1ca81b0ce19ad8 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 23 Jul 2021 19:43:38 +0200 Subject: [PATCH 1502/1786] updates the license and change the readme image --- LICENSE-2.0.txt => LICENSE | 16 ++-------------- README.md | 4 ++-- 2 files changed, 4 insertions(+), 16 deletions(-) rename LICENSE-2.0.txt => LICENSE (94%) diff --git a/LICENSE-2.0.txt b/LICENSE similarity index 94% rename from LICENSE-2.0.txt rename to LICENSE index d64569567..c72ba86b5 100644 --- a/LICENSE-2.0.txt +++ b/LICENSE @@ -1,4 +1,3 @@ - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -176,18 +175,7 @@ END OF TERMS AND CONDITIONS - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] + Copyright 2019 Expedia, Inc Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -199,4 +187,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index 49a06f887..b903253bd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

      - BULL + BULL

      ## Bean Utils Light Library @@ -12,7 +12,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.expediagroup.beans/bull-bean-transformer/badge.svg?subject=maven-central&color=blue)](https://maven-badges.herokuapp.com/maven-central/com.expediagroup.beans/bull-bean-transformer) [![Javadocs](http://www.javadoc.io/badge/com.expediagroup.beans/bull-bean-transformer.svg?color=blue)](http://www.javadoc.io/doc/com.expediagroup.beans/bull-bean-transformer) [![Build Status](https://github.com/ExpediaGroup/bull/actions/workflows/github-default-actions.yml/badge.svg?branch=master)](https://github.com/ExpediaGroup/bull/actions) -[![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/chat-on%20slack-ff69b4.svg)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) +[![Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk](https://img.shields.io/badge/Slack-%23bull-ECB22E.svg?logo=data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNTQgNTQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNMTkuNzEyLjEzM2E1LjM4MSA1LjM4MSAwIDAgMC01LjM3NiA1LjM4NyA1LjM4MSA1LjM4MSAwIDAgMCA1LjM3NiA1LjM4Nmg1LjM3NlY1LjUyQTUuMzgxIDUuMzgxIDAgMCAwIDE5LjcxMi4xMzNtMCAxNC4zNjVINS4zNzZBNS4zODEgNS4zODEgMCAwIDAgMCAxOS44ODRhNS4zODEgNS4zODEgMCAwIDAgNS4zNzYgNS4zODdoMTQuMzM2YTUuMzgxIDUuMzgxIDAgMCAwIDUuMzc2LTUuMzg3IDUuMzgxIDUuMzgxIDAgMCAwLTUuMzc2LTUuMzg2IiBmaWxsPSIjMzZDNUYwIi8+PHBhdGggZD0iTTUzLjc2IDE5Ljg4NGE1LjM4MSA1LjM4MSAwIDAgMC01LjM3Ni01LjM4NiA1LjM4MSA1LjM4MSAwIDAgMC01LjM3NiA1LjM4NnY1LjM4N2g1LjM3NmE1LjM4MSA1LjM4MSAwIDAgMCA1LjM3Ni01LjM4N20tMTQuMzM2IDBWNS41MkE1LjM4MSA1LjM4MSAwIDAgMCAzNC4wNDguMTMzYTUuMzgxIDUuMzgxIDAgMCAwLTUuMzc2IDUuMzg3djE0LjM2NGE1LjM4MSA1LjM4MSAwIDAgMCA1LjM3NiA1LjM4NyA1LjM4MSA1LjM4MSAwIDAgMCA1LjM3Ni01LjM4NyIgZmlsbD0iIzJFQjY3RCIvPjxwYXRoIGQ9Ik0zNC4wNDggNTRhNS4zODEgNS4zODEgMCAwIDAgNS4zNzYtNS4zODcgNS4zODEgNS4zODEgMCAwIDAtNS4zNzYtNS4zODZoLTUuMzc2djUuMzg2QTUuMzgxIDUuMzgxIDAgMCAwIDM0LjA0OCA1NG0wLTE0LjM2NWgxNC4zMzZhNS4zODEgNS4zODEgMCAwIDAgNS4zNzYtNS4zODYgNS4zODEgNS4zODEgMCAwIDAtNS4zNzYtNS4zODdIMzQuMDQ4YTUuMzgxIDUuMzgxIDAgMCAwLTUuMzc2IDUuMzg3IDUuMzgxIDUuMzgxIDAgMCAwIDUuMzc2IDUuMzg2IiBmaWxsPSIjRUNCMjJFIi8+PHBhdGggZD0iTTAgMzQuMjQ5YTUuMzgxIDUuMzgxIDAgMCAwIDUuMzc2IDUuMzg2IDUuMzgxIDUuMzgxIDAgMCAwIDUuMzc2LTUuMzg2di01LjM4N0g1LjM3NkE1LjM4MSA1LjM4MSAwIDAgMCAwIDM0LjI1bTE0LjMzNi0uMDAxdjE0LjM2NEE1LjM4MSA1LjM4MSAwIDAgMCAxOS43MTIgNTRhNS4zODEgNS4zODEgMCAwIDAgNS4zNzYtNS4zODdWMzQuMjVhNS4zODEgNS4zODEgMCAwIDAtNS4zNzYtNS4zODcgNS4zODEgNS4zODEgMCAwIDAtNS4zNzYgNS4zODciIGZpbGw9IiNFMDFFNUEiLz48L2c+PC9zdmc+&labelColor=611f69)](https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk) [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://opensource.expediagroup.com/bull/) [![Coverage Status](https://coveralls.io/repos/github/ExpediaGroup/bull/badge.svg?branch=master)](https://coveralls.io/github/ExpediaGroup/bull?branch=master) From 4b59654c77e3b4404186a1c1c57ec26193dcfc2f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 23 Jul 2021 19:46:55 +0200 Subject: [PATCH 1503/1786] updates the license and change the readme image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b903253bd..ca566a49b 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://opensource.expediagroup.com/bull/) [![Coverage Status](https://coveralls.io/repos/github/ExpediaGroup/bull/badge.svg?branch=master)](https://coveralls.io/github/ExpediaGroup/bull?branch=master) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) -![GitHub license](https://img.shields.io/github/license/ExpediaGroup/bull.svg) +[![License](https://img.shields.io/badge/License-Apache%202.0-lightgrey.svg)](https://opensource.org/licenses/Apache-2.0) All BULL modules are available on Maven Central: From 58fb12026855c773337105e38bd0a24498c5e8b9 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 25 Jul 2021 15:19:16 +0200 Subject: [PATCH 1504/1786] updates the license link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca566a49b..ca5a84a54 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![GitHub site](https://img.shields.io/badge/GitHub-site-blue.svg)](https://opensource.expediagroup.com/bull/) [![Coverage Status](https://coveralls.io/repos/github/ExpediaGroup/bull/badge.svg?branch=master)](https://coveralls.io/github/ExpediaGroup/bull?branch=master) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) -[![License](https://img.shields.io/badge/License-Apache%202.0-lightgrey.svg)](https://opensource.org/licenses/Apache-2.0) +[![License](https://img.shields.io/github/license/ExpediaGroup/bull.svg)](https://img.shields.io/github/license/ExpediaGroup/bull.svg) All BULL modules are available on Maven Central: From c0b91100bd0615830d49edf0b43dbba9054ac8c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jul 2021 02:09:59 +0000 Subject: [PATCH 1505/1786] Bump eg-oss-parent from 2.3.2 to 2.4.0 Bumps [eg-oss-parent](https://github.com/ExpediaGroup/eg-oss-parent) from 2.3.2 to 2.4.0. - [Release notes](https://github.com/ExpediaGroup/eg-oss-parent/releases) - [Changelog](https://github.com/ExpediaGroup/eg-oss-parent/blob/main/CHANGELOG.md) - [Commits](https://github.com/ExpediaGroup/eg-oss-parent/compare/eg-oss-parent-2.3.2...eg-oss-parent-2.4.0) --- updated-dependencies: - dependency-name: com.expediagroup:eg-oss-parent dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2ced15009..631f56df6 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ com.expediagroup eg-oss-parent - 2.3.2 + 2.4.0 From acdd81941402948ccc5a4ff9150c1e3d14bc41cb Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 26 Jul 2021 16:35:19 +0200 Subject: [PATCH 1506/1786] modifies the spotless plugin usage --- pom.xml | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index 631f56df6..f9c97568d 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ com.expediagroup eg-oss-parent - 2.4.0 + 2.4.1-SNAPSHOT @@ -84,7 +84,6 @@ 3.1.2 2.8.1 8.44 - 2.12.2 3.0.0-M4 1.6.8 3.1.2 @@ -98,9 +97,10 @@ false true false - \#java,\#javax,\#jakarta,\#org,\#,\#com,,\#lombok,java,javax,jakarta,org,,com,,lombok - - false + + \#java,\#javax,\#jakarta,\#org,\#,\#com,\#com.expedia,\#com.expediagroup,\#com.hotels,,\#lombok,java,javax,jakarta,org,,com,com.expedia,com.expediagroup,com.hotels,lombok + + false
      @@ -229,7 +229,7 @@ false true true - true + true
      @@ -251,7 +251,7 @@ true false - true + true true @@ -284,7 +284,7 @@ compatibility-mode true - true + true @@ -309,7 +309,7 @@ false true true - true + true
      @@ -760,30 +760,6 @@ org.apache.maven.plugins maven-enforcer-plugin - - - com.diffplug.spotless - spotless-maven-plugin - ${maven.spotless.plugin.version} - - - process-sources - - apply - - - - - ${spotless.maven.plugin.skip} - - - - - ${import.order} - - - - From 96462fd810bf89345ae2aed9bbe420ac3f165ef4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 27 Jul 2021 16:31:10 +0200 Subject: [PATCH 1507/1786] upgrade the eg-oss-parent version --- CHANGELOG-JDK11.md | 10 ++++++++++ CHANGELOG-JDK8.md | 2 +- CHANGELOG.md | 10 ++++++++++ pom.xml | 2 +- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index 8fb0c0f79..fdc28ff96 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -2,12 +2,22 @@ All notable changes to this project will be documented in this file. +### [2.0.1-jdk11] TBD + +#### Changed + +* Updated `eg-oss-parent` version to `2.4.1` (was `2.4.0`). + ### [2.0.0-jdk11] 2021.07.23 + #### Adds + * Renames the package from `com.hotels` to `com.expediagroup` ### [1.7.7] 2021.06.23 + #### Changed + * Fixes an issue that was preventing the transformation of Object type fields ### [1.7.6] 2021.01.11 diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 1e1b65771..4bf8b64d9 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. ### [1.7.6-jdk8] 2020.06.23 #### Changed -* * Fixes an issue that was preventing the transformation of Object type fields +* Fixes an issue that was preventing the transformation of Object type fields ### [1.7.4-jdk8] 2020.12.24 #### Changed diff --git a/CHANGELOG.md b/CHANGELOG.md index 8422555c8..bafc0a26d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,22 @@ All notable changes to this project will be documented in this file. +### [2.1.1] TBD + +#### Changed + +* Updated `eg-oss-parent` version to `2.4.1` (was `2.4.0`). + ### [2.1.0] 2021.07.23 + #### Adds + * Renames the package from `com.hotels` to `com.expediagroup` ### [2.0.1.1] 2021.06.24 + #### Adds + * Adds the javadoc generation to the release ### [2.0.1] 2021.06.23 diff --git a/pom.xml b/pom.xml index f9c97568d..d62f6ecee 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ com.expediagroup eg-oss-parent - 2.4.1-SNAPSHOT + 2.4.1 From 5abb0dfb939a076b2e64a991a0698d95ba0c4568 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Aug 2021 02:10:45 +0000 Subject: [PATCH 1508/1786] Bump checkstyle from 8.44 to 8.45 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 8.44 to 8.45. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-8.44...checkstyle-8.45) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d62f6ecee..e8eee6de2 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ 3.3.0 3.1.2 2.8.1 - 8.44 + 8.45 3.0.0-M4 1.6.8 3.1.2 From 9956a3c06b1eb4d2a967beb5a11f5f832cf42594 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Aug 2021 02:13:58 +0000 Subject: [PATCH 1509/1786] Bump checkstyle from 8.45 to 8.45.1 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 8.45 to 8.45.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-8.45...checkstyle-8.45.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e8eee6de2..27092d0a1 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ 3.3.0 3.1.2 2.8.1 - 8.45 + 8.45.1 3.0.0-M4 1.6.8 3.1.2 From 9f560c7e8c1eec947fbfb11df168ebf10584faa2 Mon Sep 17 00:00:00 2001 From: Anna Sconocchia Date: Mon, 9 Aug 2021 09:32:45 +0200 Subject: [PATCH 1510/1786] Adds the jboss-logging lib as it was causing enforcing rule breaches --- bull-common/pom.xml | 10 ++++++++++ pom.xml | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 5d73415c1..807386dde 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -21,6 +21,16 @@ org.hibernate.validator hibernate-validator + + + org.jboss.logging + jboss-logging + + + + + org.jboss.logging + jboss-logging org.glassfish diff --git a/pom.xml b/pom.xml index 27092d0a1..d1ac92d20 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,7 @@ 3.20.2 7.0.1.Final + 3.4.2.Final 1.7.32 4.0.1 @@ -143,6 +144,11 @@ hibernate-validator ${hibernate-validator.version} + + org.jboss.logging + jboss-logging + ${jboss-logging.version} + org.glassfish jakarta.el From d426474e63dac4e6b1fd63f3ad797832c2a8118f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Aug 2021 02:10:09 +0000 Subject: [PATCH 1511/1786] Bump mockito-core from 3.11.2 to 3.12.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.11.2 to 3.12.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.11.2...v3.12.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d1ac92d20..09c978067 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.20 3.12.0 - 3.11.2 + 3.12.0 7.4.0 3.20.2 From a90d02c0a766e7f3a2142127b58161ba5832c158 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 02:12:52 +0000 Subject: [PATCH 1512/1786] Bump mockito-core from 3.12.0 to 3.12.1 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.12.0 to 3.12.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.12.0...v3.12.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 09c978067..b5e445478 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.20 3.12.0 - 3.12.0 + 3.12.1 7.4.0 3.20.2 From c8a58a741a4cf46b5a1d5f62d4fb031cb13d5e5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Aug 2021 02:12:32 +0000 Subject: [PATCH 1513/1786] Bump mockito-core from 3.12.1 to 3.12.3 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.12.1 to 3.12.3. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.12.1...v3.12.3) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b5e445478..1ad62e474 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.20 3.12.0 - 3.12.1 + 3.12.3 7.4.0 3.20.2 From c479d3d13c19b21ba34887f13399b4c2c8b97179 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Aug 2021 11:10:47 +0200 Subject: [PATCH 1514/1786] Adds the auto rebase of outdated pull request from dependabot --- .github/dependabot.yml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f2c64a184..9248c1cf1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,15 +1,16 @@ # dependabot configuration available at: https://docs.github.com/en/code-security/supply-chain-security/configuration-options-for-dependency-updates version: 2 updates: -- package-ecosystem: maven - directory: "/" - schedule: - interval: daily - time: "02:00" - open-pull-requests-limit: 10 - target-branch: develop - reviewers: - - fborriello - labels: - - configuration - - update \ No newline at end of file + - package-ecosystem: maven + directory: "/" + schedule: + interval: daily + time: "02:00" + open-pull-requests-limit: 10 + target-branch: develop + reviewers: + - fborriello + labels: + - configuration + - update + rebase-strategy: "auto" \ No newline at end of file From bc469ee8dac2f4a71c271a5caaa7b9ed95a06e82 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Aug 2021 11:21:39 +0200 Subject: [PATCH 1515/1786] Adds the auto retry on the test step --- .github/workflows/github-default-actions.yml | 15 +++++++++------ .../workflows/github-default-jdk11-actions.yml | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index a3cb79298..7ca9a6136 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -26,7 +26,7 @@ jobs: - name: "Build" run: | mvn clean install -B -DskipTests -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode - quality-check: + test-and-quality-check: name: "Test and quality check" runs-on: ubuntu-latest steps: @@ -46,17 +46,20 @@ jobs: with: java-version: '15' distribution: 'adopt' - - name: "Quality check" + - name: "Test and Quality check" + uses: nick-invision/retry@v2 + with: + max_attempts: 3 + command: | + mvn verify -P compatibility-mode + mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode + mvn sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - run: | - mvn verify -P compatibility-mode - mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode - mvn sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode security-check: name: "Security check" runs-on: ubuntu-latest diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 73927fb89..73b78f57a 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -26,7 +26,7 @@ jobs: - name: "Build" run: | mvn clean install -B -DskipTests -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -P compatibility-mode - quality-check: + test-and-quality-check: name: "Test and quality check" runs-on: ubuntu-latest steps: From 437f4e7c38f1a4b4db759ede656bcd3c83c83a95 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Aug 2021 11:22:44 +0200 Subject: [PATCH 1516/1786] adds the timeout property --- .github/workflows/github-default-actions.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 7ca9a6136..591fab60c 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -50,6 +50,7 @@ jobs: uses: nick-invision/retry@v2 with: max_attempts: 3 + timeout_minutes: 5 command: | mvn verify -P compatibility-mode mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode From 10c967121e543caa7708467aa238f6844640d490 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Aug 2021 11:25:43 +0200 Subject: [PATCH 1517/1786] test a failure --- .../src/test/java/com/expediagroup/beans/BeanUtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java index f06cebc32..6d3070cff 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java @@ -70,7 +70,7 @@ public void testGetTransformerWorksProperly() { final BeanTransformer transformer = underTest.getTransformer(); // THEN - assertThat(transformer).isNotNull(); + assertThat(transformer).isNull(); } /** From 17848ef4e9be87a6dd039b01cce6f3c6ccd5456a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Aug 2021 11:30:59 +0200 Subject: [PATCH 1518/1786] executes the testing and quality check on a single line --- .github/workflows/github-default-actions.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 591fab60c..db5d7cefd 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -51,10 +51,9 @@ jobs: with: max_attempts: 3 timeout_minutes: 5 + retry_on: error command: | - mvn verify -P compatibility-mode - mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode - mvn sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode + mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From 5785c002e8c900e68795e985e5088a13eecfa311 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 25 Aug 2021 11:35:29 +0200 Subject: [PATCH 1519/1786] restores the test as it was and applies the change on the jdk11 step --- .github/workflows/github-default-jdk11-actions.yml | 13 ++++++++----- .../java/com/expediagroup/beans/BeanUtilsTest.java | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 73b78f57a..5f5946396 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -46,17 +46,20 @@ jobs: with: java-version: '11' distribution: 'adopt' - - name: "Quality check" + - name: "Test and Quality check" + uses: nick-invision/retry@v2 + with: + max_attempts: 3 + timeout_minutes: 5 + retry_on: error + command: | + mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - run: | - mvn verify -P compatibility-mode - mvn jacoco:report-aggregate coveralls:report -DrepoToken=$COVERALLS_TOKEN -P compatibility-mode - mvn sonar:sonar -Dsonar.projectKey=BULL -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.branch.name=$SOURCE_BRANCH -P compatibility-mode security-check: name: "Security check" runs-on: ubuntu-latest diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java index 6d3070cff..f06cebc32 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/BeanUtilsTest.java @@ -70,7 +70,7 @@ public void testGetTransformerWorksProperly() { final BeanTransformer transformer = underTest.getTransformer(); // THEN - assertThat(transformer).isNull(); + assertThat(transformer).isNotNull(); } /** From 1e9364ac2cfe957d21a671240947adfae3db8a48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Sep 2021 02:14:57 +0000 Subject: [PATCH 1520/1786] Bump checkstyle from 8.45.1 to 9.0 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 8.45.1 to 9.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-8.45.1...checkstyle-9.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1ad62e474..5339dd486 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.3.0 3.1.2 2.8.1 - 8.45.1 + 9.0 3.0.0-M4 1.6.8 3.1.2 From 1b6e91a19b84edf08ced94dc8d9991e1667f0462 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Sep 2021 04:23:52 +0000 Subject: [PATCH 1521/1786] Bump mockito-core from 3.12.3 to 3.12.4 Bumps [mockito-core](https://github.com/mockito/mockito) from 3.12.3 to 3.12.4. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.12.3...v3.12.4) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5339dd486..359f2134c 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.20 3.12.0 - 3.12.3 + 3.12.4 7.4.0 3.20.2 From a60d727762be86fe0d48b61e88fcdd529f6808e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Sep 2021 02:13:42 +0000 Subject: [PATCH 1522/1786] Bump jakarta.el from 4.0.1 to 4.0.2 Bumps [jakarta.el](https://github.com/eclipse-ee4j/el-ri) from 4.0.1 to 4.0.2. - [Release notes](https://github.com/eclipse-ee4j/el-ri/releases) - [Commits](https://github.com/eclipse-ee4j/el-ri/commits) --- updated-dependencies: - dependency-name: org.glassfish:jakarta.el dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 359f2134c..f8da00e54 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 7.0.1.Final 3.4.2.Final 1.7.32 - 4.0.1 + 4.0.2 0.8.7 1.0 From ea2ba6832b8419cb4fc2e5160f36975c30a90c20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Sep 2021 02:16:04 +0000 Subject: [PATCH 1523/1786] Bump maven-javadoc-plugin from 3.3.0 to 3.3.1 Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.0...maven-javadoc-plugin-3.3.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f8da00e54..bb7e68210 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ [3.8.1,) 3.0.1 - 3.3.0 + 3.3.1 3.1.2 2.8.1 9.0 From 0ecb307d4f4e52e6043f2f1f901601b4ced1cf4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Sep 2021 02:11:22 +0000 Subject: [PATCH 1524/1786] Bump assertj-core from 3.20.2 to 3.21.0 Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.20.2 to 3.21.0. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.20.2...assertj-core-3.21.0) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bb7e68210..533593938 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 3.12.4 7.4.0 - 3.20.2 + 3.21.0 7.0.1.Final 3.4.2.Final From 057749a46a9eb4a1431e8377e6d8acad4bde0578 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Oct 2021 02:22:56 +0000 Subject: [PATCH 1525/1786] Bump checkstyle from 9.0 to 9.0.1 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.0 to 9.0.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.0...checkstyle-9.0.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 533593938..e9bb69758 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.3.1 3.1.2 2.8.1 - 9.0 + 9.0.1 3.0.0-M4 1.6.8 3.1.2 From 679d05b965a751e361570defe5927698645a82ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Oct 2021 02:17:47 +0000 Subject: [PATCH 1526/1786] Bump lombok from 1.18.20 to 1.18.22 Bumps [lombok](https://github.com/projectlombok/lombok) from 1.18.20 to 1.18.22. - [Release notes](https://github.com/projectlombok/lombok/releases) - [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/projectlombok/lombok/compare/v1.18.20...v1.18.22) --- updated-dependencies: - dependency-name: org.projectlombok:lombok dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9bb69758..7c700f2db 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 15 ${jdk.version} ${jdk.version} - 1.18.20 + 1.18.22 3.12.0 3.12.4 From 47d82c07efc3dfd19ee1bd7f5d15f55b19ee9700 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 7 Oct 2021 06:32:11 +0200 Subject: [PATCH 1527/1786] Bump lombok from 1.18.20 to 1.18.22 (#263) Bumps [lombok](https://github.com/projectlombok/lombok) from 1.18.20 to 1.18.22. - [Release notes](https://github.com/projectlombok/lombok/releases) - [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/projectlombok/lombok/compare/v1.18.20...v1.18.22) --- updated-dependencies: - dependency-name: org.projectlombok:lombok dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9bb69758..7c700f2db 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 15 ${jdk.version} ${jdk.version} - 1.18.20 + 1.18.22 3.12.0 3.12.4 From 91a24304d071566ee1d7737f3981d6be351d9dbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Oct 2021 06:24:12 +0200 Subject: [PATCH 1528/1786] Bump mockito-core from 3.12.4 to 4.0.0 (#264) Bumps [mockito-core](https://github.com/mockito/mockito) from 3.12.4 to 4.0.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v3.12.4...v4.0.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7c700f2db..691b02c68 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.22 3.12.0 - 3.12.4 + 4.0.0 7.4.0 3.21.0 From 7217d8cdc75a9aceddbcd654a998b86e0c6b64a7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Oct 2021 11:51:01 +0200 Subject: [PATCH 1529/1786] [issue-265] Enable one-to-many field mapping and field transformer (#266) * Adds a function to reset all the defined settings * Adds the possibility to map the same source field into multiple fields * Adds the possibility to apply the same field transformation function on multiple fields --- CHANGELOG-JDK11.md | 14 +- CHANGELOG.md | 16 +- PULL_REQUEST_TEMPLATE.md | 1 - README.md | 204 ++++++++++------- .../transformer/BeanTransformerTest.java | 25 +++ .../MixedObjectTransformationTest.java | 63 ++++++ .../MutableObjectTransformationTest.java | 1 - .../transformer/AbstractTransformer.java | 35 ++- .../expediagroup/transformer/Transformer.java | 5 + .../transformer/model/FieldMapping.java | 2 +- .../transformer/model/FieldTransformer.java | 16 +- .../model/TransformerSettings.java | 2 +- .../MixedToFooSimpleNotExistingFields.java | 35 +++ .../transformer/AbstractTransformerTest.java | 1 + .../transformer/AbstractMapTransformer.java | 6 +- .../model/MapTransformerSettings.java | 2 +- .../site/markdown/transformer/bean/samples.md | 209 +++++++++++------- 17 files changed, 447 insertions(+), 190 deletions(-) create mode 100644 bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooSimpleNotExistingFields.java diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index fdc28ff96..2a86e4c62 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -2,22 +2,20 @@ All notable changes to this project will be documented in this file. -### [2.0.1-jdk11] TBD - +### [2.0.1-jdk11] 2021.10.24 +#### Added +* Adds a function to reset all the defined settings +* Adds the possibility to map the same source field into multiple fields +* Adds the possibility to apply the same field transformation function on multiple fields #### Changed - * Updated `eg-oss-parent` version to `2.4.1` (was `2.4.0`). ### [2.0.0-jdk11] 2021.07.23 - -#### Adds - +#### Added * Renames the package from `com.hotels` to `com.expediagroup` ### [1.7.7] 2021.06.23 - #### Changed - * Fixes an issue that was preventing the transformation of Object type fields ### [1.7.6] 2021.01.11 diff --git a/CHANGELOG.md b/CHANGELOG.md index bafc0a26d..7d0f0160a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,22 +2,20 @@ All notable changes to this project will be documented in this file. -### [2.1.1] TBD - +### [2.1.1] 2021.10.24 +#### Added +* Adds a function to reset all the defined settings +* Adds the possibility to map the same source field into multiple fields +* Adds the possibility to apply the same field transformation function on multiple fields #### Changed - * Updated `eg-oss-parent` version to `2.4.1` (was `2.4.0`). ### [2.1.0] 2021.07.23 - -#### Adds - +#### Changed * Renames the package from `com.hotels` to `com.expediagroup` ### [2.0.1.1] 2021.06.24 - -#### Adds - +#### Added * Adds the javadoc generation to the release ### [2.0.1] 2021.06.23 diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 5cddfba25..35afcfe4f 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -31,5 +31,4 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file - [ ] Any implemented change has been added in the [CHANGELOG-JDK11.md](./CHANGELOG-JDK11.md) file - [ ] My changes have been applied on a separate branch too with compatibility with Java 11. Follow this [instructions](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#3-prepare-the-jdk11-release) for help. - - [ ] The maven version has been increased. diff --git a/README.md b/README.md index ca5a84a54..e4855ca42 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Bean Utils Light Library BULL is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable, and incredibly fast. -It's the only library able to transform Mutable, Immutable, and Mixed bean without any custom configuration. +It's the only library able to transform Mutable, Immutable, and Mixed bean without any custom configuration. ## Start using @@ -19,7 +19,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) [![License](https://img.shields.io/github/license/ExpediaGroup/bull.svg)](https://img.shields.io/github/license/ExpediaGroup/bull.svg) -All BULL modules are available on Maven Central: +All BULL modules are available on Maven Central: * ### Bean BOM @@ -166,16 +166,16 @@ mvnw.cmd versions:display-dependency-updates -P check-for-updates ### Simple case: ```java -public class FromBean { public class ToBean { - private final String name; @NotNull - private final BigInteger id; public BigInteger id; - private final List subBeanList; private final String name; - private List list; private final List list; - private final FromSubBean subObject; private final List subBeanList; - private ImmutableToSubFoo subObject; - - // all constructors // all args constructor - // getters and setters... // getters and setters... +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List subBeanList; + private ImmutableToSubFoo subObject; + + // all constructors // all args constructor + // getters and setters... // getters and setters... } ``` And one line code as: @@ -187,30 +187,30 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); From class and To class with different field names: ```java -public class FromBean { public class ToBean { - - private final String name; private final String differentName; - private final int id; private final int id; - private final List subBeanList; private final List subBeanList; - private final List list; private final List list; - private final FromSubBean subObject; private final ToSubBean subObject; - - // getters... - public ToBean(final String differentName, - final int id, +public class FromBean { public class ToBean { + + private final String name; private final String differentName; + private final int id; private final int id; + private final List subBeanList; private final List subBeanList; + private final List list; private final List list; + private final FromSubBean subObject; private final ToSubBean subObject; + + // getters... + public ToBean(final String differentName, + final int id, } final List subBeanList, - final List list, - final ToSubBean subObject) { - this.differentName = differentName; - this.id = id; - this.subBeanList = subBeanList; - this.list = list; - this.subObject = subObject; - } - - // getters... - - } + final List list, + final ToSubBean subObject) { + this.differentName = differentName; + this.id = id; + this.subBeanList = subBeanList; + this.list = list; + this.subObject = subObject; + } + + // getters... + +} ``` And one line code as: @@ -218,34 +218,80 @@ And one line code as: beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class); ``` +it is also possible to map a field in the source class into multiple fields in the destination object. + +Given the following source class: + +``` +public class SourceClass { + private final String name; + private final int id; +} +``` + +the following destination class: + +``` +public class DestinationClass { + private final String name; + private final int id; + private final int index; +} +``` + +and the following operations: + +``` +var sourceObj = new SourceClass("foo", 123); + +var multipleFieldMapping = new FieldMapping<>("id", "index", "identifier"); + +var destObj = new BeanUtils().getBeanTransformer() + .withFieldMapping(multipleFieldMapping) + .transform(sourceObj, DestinationClass.class); + +System.out.println("name = " + destObj.getName()); +System.out.println("id = " + destObj.getId()); +System.out.println("index = " + destObj.getIndex()); +``` + +the output will be: + +``` +name = foo +id = 123 +index = 123 +``` + + ### Mapping destination fields with correspondent fields contained inside one of the nested objects in the source object: Assuming that the object `FromSubBean` is declared as follow: ```java -public class FromSubBean { - - private String serialNumber; - private Date creationDate; - - // getters and setters... - +public class FromSubBean { + + private String serialNumber; + private Date creationDate; + + // getters and setters... + } ``` and our source object and destination object are described as follow: ```java -public class FromBean { public class ToBean { - - private final int id; private final int id; - private final String name; private final String name; - private final FromSubBean subObject; private final String serialNumber; - private final Date creationDate; - - // all args constructor // all args constructor - // getters... // getters... - +public class FromBean { public class ToBean { + + private final int id; private final int id; + private final String name; private final String name; + private final FromSubBean subObject; private final String serialNumber; + private final Date creationDate; + + // all args constructor // all args constructor + // getters... // getters... + } } ``` -the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: +the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done by defining the whole path to the end property: ```java FieldMapping serialNumberMapping = new FieldMapping<>("subObject.serialNumber", "serialNumber"); FieldMapping creationDateMapping = new FieldMapping<>("subObject.creationDate", "creationDate"); @@ -294,6 +340,7 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger identifier; + private final BigInteger index; public BigInteger index; private final List subBeanList; private final String name; private List list; private final List list; private final FromSubBean subObject; private final List nestedObjectList; @@ -315,9 +362,16 @@ beanUtils.getTransformer() .withFieldTransformer(localeTransformer); ``` +It's also possible to apply the same transformation function on multiple fields. Taking as an example the above bean and +assuming that we would negate both the id and the identifier, the transformer function has to be defined as follows: + +```java +FieldTransformer fieldTransformer = new FieldTransformer<>(List.of("identifier", "index"), BigInteger::negate); +``` + ### Assign a default value in case of missing field in the source object: -Assign a default value in case of missing field in the source object: +Assign a default value in case of a missing field in the source object: ```java public class FromBean { public class ToBean { @@ -339,7 +393,7 @@ ToBean toBean = beanUtils.getTransformer() ### Disable the default value set for primitive types in case they are null: -BULL by default sets the default value for all primitive types fields in case their value in the source object. +BULL by default sets the default value for all primitive types fields in case their value is in the source object. Given the following Java Bean: ```java @@ -355,7 +409,7 @@ public class FromBean { public class ToBean ``` in case the field `id` in the `FromBean` object is `null`, the value assigned the correspondent field in the `ToBean` object will be `0`. -To disable this you can simply do: +To disable this you can simply do: ```java ToBean toBean = beanUtils.getTransformer() @@ -366,7 +420,7 @@ in this case, the field `id` after the transformation will be `null` ### Applying a transformation function in case of missing fields in the source object: -Assign a default value in case of missing field in the source object: +Assign a default value in case of a missing field in the source object: ```java public class FromBean { public class ToBean { @@ -389,7 +443,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on a field contained in a nested object: -This example shows off a lambda transformation function that can be applied to a nested object field. +This example shows how a lambda transformation function can be applied to a nested object field. Given: @@ -409,7 +463,7 @@ public class ToSubBean { private final long index; } ``` -Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as follow: ```java FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); @@ -441,7 +495,7 @@ public class ToSubBean { // all args constructor } // getters... ``` -Assuming that the value `x` should be mapped into the field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as +Assuming that the value `x` should be mapped into the field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as follow: ```java ToBean toBean = beanUtils.getTransformer() @@ -474,7 +528,7 @@ public class FromSubBean { public class ToSubBe } } ``` Assuming that the lambda transformation function should be applied only to the field: `name` contained in the `ToSubBean` object, the transformation function has to be defined - as +as follow: ```java FieldTransformer nameTransformer = new FieldTransformer<>("name", StringUtils::capitalize); @@ -638,12 +692,12 @@ Transformer transformer = beanUtils.getTransformer() ToBean toBean = transformer.transform(fromBean, ToBean.class); ``` -**IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function defined on a specific field. +**IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function is defined on a specific field. This means that once the `FieldTransformer` function will be executed the field value has already been transformed. ## Builder supported patterns -The library support the transformation of Java Bean using the following Builder patterns: +The library supports the transformation of Java Bean using the following Builder patterns: ### Standard pattern: @@ -731,7 +785,7 @@ public class ItemType { } ``` -It's needed to enable the custom Builder Transformation as following: +It's needed to enable the custom Builder Transformation as follows: ```java ToBean toBean = new BeanTransformer() @@ -787,9 +841,9 @@ Following a comparison between the BULL functionalities and the following Third- | Annotation field validation | X | - | X | - | _[*] Immutable types are not supported by Dozer. When a type doesn't have a no-arg constructor and all fields are final, Dozer can't perform the mapping. - A workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ +A workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ _[+] Requires a custom configuration_ - + ## Performance Let's have a look at the performance library performance. The test has been executed on the following objects: @@ -812,7 +866,7 @@ Transformation time [screenshot](docs/site/resources/images/stats/performance/tr The Bean Utils library has been tested on a real case scenario integrating it into a real edge service (called BPE). The purpose was to compare the latency introduced by the library plus the memory/CPU usage. -The dashboard's screenshot shows the latency of the invoked downstream service (called BPAS) and the one where the library has been installed (BPE). +The dashboard's screenshot shows the latency of the invoked downstream service (called BPAS) and the one where the library has been installed (BPE). Following the obtained results: | | **Classic transformer** | **BeanUtils library** | @@ -826,7 +880,7 @@ Following the obtained results: ## Validation samples -Validate a java bean has never been so simple. The library offers different API related to this, following some examples: +Validating a java bean has never been so simple. The library offers different APIs related to this, following some examples: ### Validate a Java Bean: @@ -884,7 +938,7 @@ And one line code as: List violatedConstraints = beanUtils.getValidator().getConstraintViolationsMessages(sampleBean); ``` -this will returns a list containing a constraint validation message for the `id` field as it's null and the constraint: `@NotNull` is not met. +this will return a list containing a constraint validation message for the `id` field as it's null and the constraint: `@NotNull` is not met. in case it's needed to have the `ConstraintViolation` object: ```java @@ -894,7 +948,7 @@ Set> violatedConstraints = beanUtils.getValidator(). ## Primitive type object converter Converts a given primitive value into the given primitive type. -The supported types, in which an object can be converted (from / to), are: +The supported types, in which an object can be converted (from/to), are: * `Byte`, `byte` or `byte[]` * `Short` or `short` @@ -951,19 +1005,19 @@ Samples on how to transform a `Map` and all others function applicable to it can Detailed project documentation is available [here](https://opensource.expediagroup.com/bull), including some samples for [testing the library](https://opensource.expediagroup.com/bull/transformer/testing.html) inside your project. -An article that explains how it works, with suggestion and examples is available on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) +An article that explains how it works, with suggestions and examples, is available on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) ## Credits -Created by: [Fabio Borriello](https://github.com/fborriello) with the contribution of: [Patrizio Munzi](https://github.com/patriziomunzi), +Created by: [Fabio Borriello](https://github.com/fborriello) with the contribution of: [Patrizio Munzi](https://github.com/patriziomunzi), [Andrea Marsiglia](https://github.com/AndreaMars94), [Giorgio Delle Grottaglie](https://github.com/geordie--) & the Hotels.com's Checkout team in Rome. The application's logo has been designed by Rob Light. ## Related articles - - DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) - - InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[PT-BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] +- DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) +- InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[PT-BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] ## Release @@ -989,4 +1043,4 @@ For any question, proposal, or help, please refer to the slack channel: [#bull]( This project is available under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html). -Copyright 2018-2019 Expedia Inc. +Copyright 2018-2021 Expedia Inc. \ No newline at end of file diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java index 4a6ac4e4a..aeb972d75 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java @@ -161,6 +161,31 @@ public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() beanTransformer.removeFieldTransformer(null); } + /** + * Test that is possible to remove all the transformer settings. + */ + @Test + @SuppressWarnings("unchecked") + public void testResetWorksProperly() { + // GIVEN + BeanTransformer beanTransformer = underTest + .withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val), new FieldTransformer<>(REFLECTION_UTILS_FIELD_NAME, val -> val)) + .withFieldMapping(new FieldMapping<>(SOURCE_FIELD_NAME, DEST_FIELD_NAME)) + .skipTransformationForField(NAME_FIELD_NAME) + .setDefaultValueForMissingField(true); + + // WHEN + beanTransformer.reset(); + TransformerSettings transformerSettings = + (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); + + // THEN + assertThat(transformerSettings.getFieldsTransformers()).isEmpty(); + assertThat(transformerSettings.getFieldsNameMapping()).isEmpty(); + assertThat(transformerSettings.getFieldsToSkip()).isEmpty(); + assertThat(transformerSettings.isSetDefaultValueForMissingField()).isFalse(); + } + /** * Test that the method: {@code getSourceFieldValue} raises a {@link NullPointerException} in case any of the parameters null. * @throws Exception uf the invocation fails diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java index f2af12eef..f01c1b71c 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java @@ -15,9 +15,12 @@ */ package com.expediagroup.beans.transformer; +import static java.math.BigInteger.ONE; + import static org.assertj.core.api.Assertions.assertThat; import java.math.BigInteger; +import java.util.List; import org.testng.annotations.Test; @@ -27,6 +30,7 @@ import com.expediagroup.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; import com.expediagroup.beans.sample.mixed.MixedToFooMissingField; import com.expediagroup.beans.sample.mixed.MixedToFooNotExistingFields; +import com.expediagroup.beans.sample.mixed.MixedToFooSimpleNotExistingFields; import com.expediagroup.transformer.error.MissingFieldException; import com.expediagroup.transformer.model.FieldMapping; import com.expediagroup.transformer.model.FieldTransformer; @@ -36,6 +40,7 @@ */ public class MixedObjectTransformationTest extends AbstractBeanTransformerTest { private static final boolean ACTIVE = true; + private static final String INDEX_FIELD_NAME = "index"; /** * Test that a Mixed bean with a constructor containing the final field only is correctly copied. @@ -183,4 +188,62 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { assertThat(mixedToFoo).usingRecursiveComparison() .isEqualTo(fromFoo); } + + /** + * Test that bean containing both final fields (with different names) and not with a source field mapped into + * multiple destination fields is correctly copied. + */ + @Test + public void testMixedBeanWithASourceFieldMappedIntoMultipleDestinationFieldsIsCorrectlyCopied() { + // GIVEN + var multipleDestinationFieldMapping = new FieldMapping<>(ID_FIELD_NAME, + ID_FIELD_NAME, INDEX_FIELD_NAME); + + // WHEN + var actual = underTest + .withFieldMapping(multipleDestinationFieldMapping) + .setDefaultValueForMissingField(true) + .transform(fromFooSimple, MixedToFooSimpleNotExistingFields.class); + + // THEN + assertThat(actual) + .hasFieldOrPropertyWithValue(ID_FIELD_NAME, fromFoo.getId()) + .hasFieldOrPropertyWithValue(INDEX_FIELD_NAME, fromFoo.getId()) + .usingRecursiveComparison() + .ignoringFields(INDEX_FIELD_NAME, AGE_FIELD_NAME, ACTIVE_FIELD_NAME) + .isEqualTo(fromFoo); + underTest.reset(); + } + + /** + * Test that bean containing both final fields (with different names) and not with a source field mapped into + * multiple destination fields and field transformeration applies on mutliple fields is correctly copied. + */ + @Test + public void testMixedBeanWithASourceFieldMappedIntoMultipleDestinationFieldsAndMultipleFieldTransformerIsCorrectlyCopied() { + // GIVEN + var valueToAdd = ONE; + var expectedIdValue = fromFooSimple.getId().add(valueToAdd); + var multipleDestinationFieldMapping = new FieldMapping<>(ID_FIELD_NAME, + ID_FIELD_NAME, INDEX_FIELD_NAME); + var multipleDestinationFieldTransformer = + new FieldTransformer(List.of(ID_FIELD_NAME, INDEX_FIELD_NAME), + val -> val.add(valueToAdd)); + + // WHEN + var actual = underTest + .withFieldMapping(multipleDestinationFieldMapping) + .withFieldTransformer(multipleDestinationFieldTransformer) + .setDefaultValueForMissingField(true) + .transform(fromFooSimple, MixedToFooSimpleNotExistingFields.class); + + // THEN + assertThat(actual) + .hasFieldOrPropertyWithValue(ID_FIELD_NAME, expectedIdValue) + .hasFieldOrPropertyWithValue(INDEX_FIELD_NAME, expectedIdValue) + .usingRecursiveComparison() + .ignoringFields(ID_FIELD_NAME, INDEX_FIELD_NAME, AGE_FIELD_NAME, ACTIVE_FIELD_NAME) + .isEqualTo(fromFoo); + underTest.reset(); + } } diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java index 9b88ed446..17fd185c8 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java @@ -59,7 +59,6 @@ public class MutableObjectTransformationTest extends AbstractBeanTransformerTest private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; private static final String INJECT_VALUES_METHOD_NAME = "injectValues"; private static final String NESTED_OBJECT_NAME_FIELD_NAME = "nestedObject.name"; - private static final String ACTIVE_FIELD_NAME = "active"; private static final String CODE_FIELD_NAME = "code"; /** diff --git a/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java index 03c7a7c89..f5ae64080 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java @@ -15,11 +15,11 @@ */ package com.expediagroup.transformer; +import static java.util.Arrays.stream; + import static com.expediagroup.transformer.cache.CacheManagerFactory.getCacheManager; import static com.expediagroup.transformer.validator.Validator.notNull; -import java.util.Map; - import com.expediagroup.transformer.cache.CacheManager; import com.expediagroup.transformer.model.FieldMapping; import com.expediagroup.transformer.model.FieldTransformer; @@ -31,6 +31,7 @@ /** * Abstract class containing all method implementation that will be common to any {@link Transformer}. + * * @param the {@link Transformer} implementation. * @param the {@link TransformerSettings} implementation. * @param

      the {@link FieldMapping} and {@link FieldTransformer} key class type. @@ -60,13 +61,14 @@ public abstract class AbstractTransformer fieldsNameMapping = settings.getFieldsNameMapping(); - for (FieldMapping mapping : fieldMapping) { - fieldsNameMapping.put((P) mapping.destFieldName(), (P) mapping.sourceFieldName()); + var fieldsNameMapping = settings.getFieldsNameMapping(); + for (FieldMapping mapping : fieldMapping) { + stream(mapping.destFieldName()) + .forEach(destField -> fieldsNameMapping.put(destField, mapping.sourceFieldName())); } return (T) this; } @@ -95,9 +98,10 @@ public final T withFieldMapping(final FieldMapping... fieldMapping) { @Override @SuppressWarnings("unchecked") public final T withFieldTransformer(final FieldTransformer... fieldTransformer) { - Map fieldsTransformers = settings.getFieldsTransformers(); - for (FieldTransformer transformer : fieldTransformer) { - fieldsTransformers.put((P) transformer.getDestFieldName(), transformer); + var fieldsTransformers = settings.getFieldsTransformers(); + for (var transformer : fieldTransformer) { + transformer.getDestFieldName() + .forEach(destFieldName -> fieldsTransformers.put((P) destFieldName, transformer)); } return (T) this; } @@ -139,4 +143,13 @@ public final void resetFieldsTransformer() { settings.getFieldsTransformers().clear(); cacheManager.removeMatchingKeys(transformerFunctionRegex); } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public final void reset() { + settings = (S) new TransformerSettings<>(); + } } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java b/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java index 9eaaa8f92..4e972a621 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java @@ -58,4 +58,9 @@ public interface Transformer { * Removes all the configured fields transformer. */ void resetFieldsTransformer(); + + /** + * Removes all the configured settings. + */ + void reset(); } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java index 5700635c8..280d4fad8 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java @@ -22,5 +22,5 @@ * @param sourceFieldName the field name in the source object * @param destFieldName the field name in the destination object. */ -public record FieldMapping(T sourceFieldName, K destFieldName) { +public record FieldMapping(T sourceFieldName, K... destFieldName) { } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java index 358328bbc..3d7311a53 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java @@ -19,6 +19,7 @@ import static lombok.AccessLevel.PRIVATE; +import java.util.List; import java.util.function.Function; import java.util.function.Supplier; @@ -41,7 +42,7 @@ public class FieldTransformer { /** * The field name in the destination object. */ - private final String destFieldName; + private final List destFieldName; /** * The field transformer function. @@ -53,13 +54,22 @@ public class FieldTransformer { */ private final Supplier transformerSupplier; + /** + * Creates a field transformer with a lambda function to be applied on a list of fields. + * @param destinationFieldNames the field name in the destination object. + * @param fieldTransformerFunction the transformer function to apply on field + */ + public FieldTransformer(final List destinationFieldNames, final Function fieldTransformerFunction) { + this(destinationFieldNames, fieldTransformerFunction, null); + } + /** * Creates a field transformer with a lambda function to be applied on the field. * @param destinationFieldName the field name in the destination object. * @param fieldTransformerFunction the transformer function to apply on field */ public FieldTransformer(final String destinationFieldName, final Function fieldTransformerFunction) { - this(destinationFieldName, fieldTransformerFunction, null); + this(List.of(destinationFieldName), fieldTransformerFunction, null); } /** @@ -68,7 +78,7 @@ public FieldTransformer(final String destinationFieldName, final Function * @param fieldTransformerSupplier the transformer supplier to apply on field */ public FieldTransformer(final String destinationFieldName, final Supplier fieldTransformerSupplier) { - this(destinationFieldName, null, fieldTransformerSupplier); + this(List.of(destinationFieldName), null, fieldTransformerSupplier); } /** diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java b/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java index a741533f3..8c1e6a10e 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java @@ -42,7 +42,7 @@ public class TransformerSettings { /** * Contains the lambda functions to be applied on a given fields. - * This features allows to apply transformation on the destination object value. + * This feature allows applying transformation on the destination object value. * e.g. The following instructions allows to negate the destination value of the identifier field. * {@code * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooSimpleNotExistingFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooSimpleNotExistingFields.java new file mode 100644 index 000000000..14bc750ee --- /dev/null +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooSimpleNotExistingFields.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.sample.mixed; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mixed object that contains multiple fields not existing in the source object. + */ +@AllArgsConstructor +@Getter +@Setter +public class MixedToFooSimpleNotExistingFields { + private final String name; + private final BigInteger id; + private final BigInteger index; + private int age; +} diff --git a/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java index 6b58b4b2f..a7a065183 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java @@ -64,6 +64,7 @@ public abstract class AbstractTransformerTest { protected static final String PHONE_NUMBER_DEST_FIELD_NAME = "phoneNumbers"; protected static final String PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME = "nestedObject.phoneNumbers"; protected static final String NAME_FIELD_NAME = "name"; + protected static final String ACTIVE_FIELD_NAME = "active"; protected static final float PRICE = 10.0f; protected static final Map SAMPLE_MAP = new HashMap<>(); protected static final Map> COMPLEX_MAP = new HashMap<>(); diff --git a/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java index 8557b83f6..ca4d5717d 100644 --- a/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java @@ -59,10 +59,12 @@ public Map transform(final Map sourceMap, final Class keyFieldsTransformers = settings.getKeyFieldsTransformers(); - for (FieldTransformer transformer : keyFieldTransformer) { - keyFieldsTransformers.put(transformer.getDestFieldName(), transformer); + for (var transformer : keyFieldTransformer) { + transformer.getDestFieldName() + .forEach(destFieldName -> keyFieldsTransformers.put(destFieldName, transformer)); } return this; } diff --git a/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java index 2f56a242c..f6b541da9 100644 --- a/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java @@ -32,7 +32,7 @@ public class MapTransformerSettings extends TransformerSettings { /** * Contains the lambda functions to be applied on a given map key. - * This features allows to apply transformation on the destination object value. + * This feature allows applying transformation on the destination object value. * e.g. The following instructions allows to negate the destination value of the identifier field. * {@code * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); diff --git a/docs/site/markdown/transformer/bean/samples.md b/docs/site/markdown/transformer/bean/samples.md index b4707bcad..69170e143 100644 --- a/docs/site/markdown/transformer/bean/samples.md +++ b/docs/site/markdown/transformer/bean/samples.md @@ -7,18 +7,17 @@ ### Simple case: ```java -public class FromBean { public class ToBean { - private final String name; @NotNull - private final BigInteger id; public BigInteger id; - private final List subBeanList; private final String name; - private List list; private final List list; - private final FromSubBean subObject; private final List subBeanList; - private ImmutableToSubFoo subObject; - - // all constructors // all args constructor - // getters and setters... // getters and setters... -} - } +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List subBeanList; + private ImmutableToSubFoo subObject; + + // all constructors // all args constructor + // getters and setters... // getters and setters... +} ``` And one line code as: ```java @@ -29,65 +28,111 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); From class and To class with different field names: ```java -public class FromBean { public class ToBean { - - private final String name; private final String differentName; - private final int id; private final int id; - private final List subBeanList; private final List subBeanList; - private final List list; private final List list; - private final FromSubBean subObject; private final ToSubBean subObject; - - // getters... - public ToBean(final String differentName, - final int id, +public class FromBean { public class ToBean { + + private final String name; private final String differentName; + private final int id; private final int id; + private final List subBeanList; private final List subBeanList; + private final List list; private final List list; + private final FromSubBean subObject; private final ToSubBean subObject; + + // getters... + public ToBean(final String differentName, + final int id, } final List subBeanList, - final List list, - final ToSubBean subObject) { - this.differentName = differentName; - this.id = id; - this.subBeanList = subBeanList; - this.list = list; - this.subObject = subObject; - } - - // getters... - - } + final List list, + final ToSubBean subObject) { + this.differentName = differentName; + this.id = id; + this.subBeanList = subBeanList; + this.list = list; + this.subObject = subObject; + } + + // getters... + +} ``` And one line code as: ```java -beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class);` +beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class); +``` + +it is also possible to map a field in the source class into multiple fields in the destination object. + +Given the following source class: + +``` +public class SourceClass { + private final String name; + private final int id; +} ``` -### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: +the following destination class: + +``` +public class DestinationClass { + private final String name; + private final int id; + private final int index; +} +``` + +and the following operations: + +``` +var sourceObj = new SourceClass("foo", 123); + +var multipleFieldMapping = new FieldMapping<>("id", "index", "identifier"); + +var destObj = new BeanUtils().getBeanTransformer() + .withFieldMapping(multipleFieldMapping) + .transform(sourceObj, DestinationClass.class); + +System.out.println("name = " + destObj.getName()); +System.out.println("id = " + destObj.getId()); +System.out.println("index = " + destObj.getIndex()); +``` + +the output will be: + +``` +name = foo +id = 123 +index = 123 +``` + + +### Mapping destination fields with correspondent fields contained inside one of the nested objects in the source object: Assuming that the object `FromSubBean` is declared as follow: ```java -public class FromSubBean { - - private String serialNumber; - private Date creationDate; - - // getters and setters... - +public class FromSubBean { + + private String serialNumber; + private Date creationDate; + + // getters and setters... + } ``` and our source object and destination object are described as follow: ```java -public class FromBean { public class ToBean { - - private final int id; private final int id; - private final String name; private final String name; - private final FromSubBean subObject; private final String serialNumber; - private final Date creationDate; - - // all args constructor // all args constructor - // getters... // getters... - +public class FromBean { public class ToBean { + + private final int id; private final int id; + private final String name; private final String name; + private final FromSubBean subObject; private final String serialNumber; + private final Date creationDate; + + // all args constructor // all args constructor + // getters... // getters... + } } ``` -the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: +the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done by defining the whole path to the end property: ```java FieldMapping serialNumberMapping = new FieldMapping<>("subObject.serialNumber", "serialNumber"); FieldMapping creationDateMapping = new FieldMapping<>("subObject.creationDate", "creationDate"); @@ -157,9 +202,16 @@ beanUtils.getTransformer() .withFieldTransformer(localeTransformer); ``` +It's also possible to apply the same transformation function on multiple fields. Taking as an example the above bean and +assuming that we would negate both the id and the identifier, the transformer function has to be defined as follows: + +```java +FieldTransformer fieldTransformer = new FieldTransformer<>(List.of("identifier", "index"), BigInteger::negate); +``` + ### Assign a default value in case of missing field in the source object: -Assign a default value in case of missing field in the source object: +Assign a default value in case of a missing field in the source object: ```java public class FromBean { public class ToBean { @@ -181,7 +233,7 @@ ToBean toBean = beanUtils.getTransformer() ### Disable the default value set for primitive types in case they are null: -BULL by default sets the default value for all primitive types fields in case their value in the source object. +BULL by default sets the default value for all primitive types fields in case their value is in the source object. Given the following Java Bean: ```java @@ -197,18 +249,18 @@ public class FromBean { public class ToBean ``` in case the field `id` in the `FromBean` object is `null`, the value assigned the correspondent field in the `ToBean` object will be `0`. -To disable this you can simply do: +To disable this you can simply do: ```java ToBean toBean = beanUtils.getTransformer() .setDefaultValueForMissingPrimitiveField(false).transform(fromBean, ToBean.class); ``` -in this case the field `id` after the transformation will be `null` +in this case, the field `id` after the transformation will be `null` ### Applying a transformation function in case of missing fields in the source object: -Assign a default value in case of missing field in the source object: +Assign a default value in case of a missing field in the source object: ```java public class FromBean { public class ToBean { @@ -231,7 +283,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on a field contained in a nested object: -This example shows of a lambda transformation function can be applied on a nested object field. +This example shows how a lambda transformation function can be applied to a nested object field. Given: @@ -251,7 +303,7 @@ public class ToSubBean { private final long index; } ``` -Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as follow: ```java FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); @@ -283,7 +335,7 @@ public class ToSubBean { // all args constructor } // getters... ``` -Assuming that the value `x` should be mapped into field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as +Assuming that the value `x` should be mapped into the field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as follow: ```java ToBean toBean = beanUtils.getTransformer() @@ -292,7 +344,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on all fields matching with the given one: -This example shows how a lambda transformation function can be applied on all fields matching with the given one independently from their position. +This example shows how a lambda transformation function can be applied to all fields matching with the given one independently from their position. Given: @@ -315,7 +367,8 @@ public class FromSubBean { public class ToSubBe // getters... // getters... } } ``` -Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +Assuming that the lambda transformation function should be applied only to the field: `name` contained in the `ToSubBean` object, the transformation function has to be defined +as follow: ```java FieldTransformer nameTransformer = new FieldTransformer<>("name", StringUtils::capitalize); @@ -345,7 +398,7 @@ List actual = fromFooSimpleList.stream() .collect(Collectors.toList()); ``` -### Disable Java Beans validation: +### Enable Java Beans validation: Assuming that the field: `id` in the fromBean instance is null. ```java @@ -358,10 +411,10 @@ public class FromBean { public class ToBean // getters... // getters and setters... } } ``` -adding the following configuration no exception will be thrown: +adding the following configuration an exception will be thrown: ```java ToBean toBean = beanUtils.getTransformer() - .setValidationDisabled(true) + .setValidationEnabled(true) .transform(fromBean, ToBean.class); ``` @@ -415,11 +468,11 @@ beanUtils.getTransformer() where `nestedObject` is the name of the field in the destination object. -This feature allows to **transform an object keeping the data from different sources**. +This feature allows us to **transform an object keeping the data from different sources**. To better explain this function let's assume that the `ToBean` (defined above) should be transformed as follow: -- `name` field value has be taken from the `FromBean` object -- `nestedObject` field value has be taken from the `FromBean2` object +- `name` field value has been taken from the `FromBean` object +- `nestedObject` field value has been taken from the `FromBean2` object the objective can be reached by doing: ```java @@ -438,8 +491,7 @@ beanUtils.getTransformer() ``` ### Not existing field in the source object: - -In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library gets the field value from that method. +In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should gets the field value from that method. ```java public class FromBean { public class ToBean { private final BigInteger id; @@ -470,8 +522,8 @@ public class FromBean { public class ToBean ``` as, by default the primitive type conversion is disabled, to get the above object converted we should have -implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically from enabling the -functionality described above. +implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically by enabling the +the functionality described above. ```java Transformer transformer = beanUtils.getTransformer() @@ -480,13 +532,16 @@ Transformer transformer = beanUtils.getTransformer() ToBean toBean = transformer.transform(fromBean, ToBean.class); ``` +**IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function is defined on a specific field. +This means that once the `FieldTransformer` function will be executed the field value has already been transformed. + ## Transform Java Record ### Simple case: ```java -public record FromFooRecord(BigInteger id, String name) { public record RecordToFoo(BigInteger id, String name) { -} } +public record FromFooRecord(BigInteger id, String name) { public record RecordToFoo(BigInteger id, String name) { +} } ``` And one line code as: From 7172f3436e595d387d07188d5190cb37be27c6b5 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Oct 2021 11:51:01 +0200 Subject: [PATCH 1530/1786] [issue-265] Enable one-to-many field mapping and field transformer (#266) * Adds a function to reset all the defined settings * Adds the possibility to map the same source field into multiple fields * Adds the possibility to apply the same field transformation function on multiple fields --- CHANGELOG-JDK11.md | 14 +- CHANGELOG.md | 16 +- PULL_REQUEST_TEMPLATE.md | 1 - README.md | 204 ++++++++++------- .../transformer/BeanTransformerTest.java | 25 +++ .../MixedObjectTransformationTest.java | 63 ++++++ .../MutableObjectTransformationTest.java | 1 - .../transformer/AbstractTransformer.java | 35 ++- .../expediagroup/transformer/Transformer.java | 5 + .../transformer/model/FieldMapping.java | 2 +- .../transformer/model/FieldTransformer.java | 16 +- .../model/TransformerSettings.java | 2 +- .../MixedToFooSimpleNotExistingFields.java | 35 +++ .../transformer/AbstractTransformerTest.java | 1 + .../transformer/AbstractMapTransformer.java | 6 +- .../model/MapTransformerSettings.java | 2 +- .../site/markdown/transformer/bean/samples.md | 209 +++++++++++------- 17 files changed, 447 insertions(+), 190 deletions(-) create mode 100644 bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooSimpleNotExistingFields.java diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index fdc28ff96..2a86e4c62 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -2,22 +2,20 @@ All notable changes to this project will be documented in this file. -### [2.0.1-jdk11] TBD - +### [2.0.1-jdk11] 2021.10.24 +#### Added +* Adds a function to reset all the defined settings +* Adds the possibility to map the same source field into multiple fields +* Adds the possibility to apply the same field transformation function on multiple fields #### Changed - * Updated `eg-oss-parent` version to `2.4.1` (was `2.4.0`). ### [2.0.0-jdk11] 2021.07.23 - -#### Adds - +#### Added * Renames the package from `com.hotels` to `com.expediagroup` ### [1.7.7] 2021.06.23 - #### Changed - * Fixes an issue that was preventing the transformation of Object type fields ### [1.7.6] 2021.01.11 diff --git a/CHANGELOG.md b/CHANGELOG.md index bafc0a26d..7d0f0160a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,22 +2,20 @@ All notable changes to this project will be documented in this file. -### [2.1.1] TBD - +### [2.1.1] 2021.10.24 +#### Added +* Adds a function to reset all the defined settings +* Adds the possibility to map the same source field into multiple fields +* Adds the possibility to apply the same field transformation function on multiple fields #### Changed - * Updated `eg-oss-parent` version to `2.4.1` (was `2.4.0`). ### [2.1.0] 2021.07.23 - -#### Adds - +#### Changed * Renames the package from `com.hotels` to `com.expediagroup` ### [2.0.1.1] 2021.06.24 - -#### Adds - +#### Added * Adds the javadoc generation to the release ### [2.0.1] 2021.06.23 diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 5cddfba25..35afcfe4f 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -31,5 +31,4 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file - [ ] Any implemented change has been added in the [CHANGELOG-JDK11.md](./CHANGELOG-JDK11.md) file - [ ] My changes have been applied on a separate branch too with compatibility with Java 11. Follow this [instructions](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#3-prepare-the-jdk11-release) for help. - - [ ] The maven version has been increased. diff --git a/README.md b/README.md index ca5a84a54..e4855ca42 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Bean Utils Light Library BULL is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable, and incredibly fast. -It's the only library able to transform Mutable, Immutable, and Mixed bean without any custom configuration. +It's the only library able to transform Mutable, Immutable, and Mixed bean without any custom configuration. ## Start using @@ -19,7 +19,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) [![License](https://img.shields.io/github/license/ExpediaGroup/bull.svg)](https://img.shields.io/github/license/ExpediaGroup/bull.svg) -All BULL modules are available on Maven Central: +All BULL modules are available on Maven Central: * ### Bean BOM @@ -166,16 +166,16 @@ mvnw.cmd versions:display-dependency-updates -P check-for-updates ### Simple case: ```java -public class FromBean { public class ToBean { - private final String name; @NotNull - private final BigInteger id; public BigInteger id; - private final List subBeanList; private final String name; - private List list; private final List list; - private final FromSubBean subObject; private final List subBeanList; - private ImmutableToSubFoo subObject; - - // all constructors // all args constructor - // getters and setters... // getters and setters... +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List subBeanList; + private ImmutableToSubFoo subObject; + + // all constructors // all args constructor + // getters and setters... // getters and setters... } ``` And one line code as: @@ -187,30 +187,30 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); From class and To class with different field names: ```java -public class FromBean { public class ToBean { - - private final String name; private final String differentName; - private final int id; private final int id; - private final List subBeanList; private final List subBeanList; - private final List list; private final List list; - private final FromSubBean subObject; private final ToSubBean subObject; - - // getters... - public ToBean(final String differentName, - final int id, +public class FromBean { public class ToBean { + + private final String name; private final String differentName; + private final int id; private final int id; + private final List subBeanList; private final List subBeanList; + private final List list; private final List list; + private final FromSubBean subObject; private final ToSubBean subObject; + + // getters... + public ToBean(final String differentName, + final int id, } final List subBeanList, - final List list, - final ToSubBean subObject) { - this.differentName = differentName; - this.id = id; - this.subBeanList = subBeanList; - this.list = list; - this.subObject = subObject; - } - - // getters... - - } + final List list, + final ToSubBean subObject) { + this.differentName = differentName; + this.id = id; + this.subBeanList = subBeanList; + this.list = list; + this.subObject = subObject; + } + + // getters... + +} ``` And one line code as: @@ -218,34 +218,80 @@ And one line code as: beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class); ``` +it is also possible to map a field in the source class into multiple fields in the destination object. + +Given the following source class: + +``` +public class SourceClass { + private final String name; + private final int id; +} +``` + +the following destination class: + +``` +public class DestinationClass { + private final String name; + private final int id; + private final int index; +} +``` + +and the following operations: + +``` +var sourceObj = new SourceClass("foo", 123); + +var multipleFieldMapping = new FieldMapping<>("id", "index", "identifier"); + +var destObj = new BeanUtils().getBeanTransformer() + .withFieldMapping(multipleFieldMapping) + .transform(sourceObj, DestinationClass.class); + +System.out.println("name = " + destObj.getName()); +System.out.println("id = " + destObj.getId()); +System.out.println("index = " + destObj.getIndex()); +``` + +the output will be: + +``` +name = foo +id = 123 +index = 123 +``` + + ### Mapping destination fields with correspondent fields contained inside one of the nested objects in the source object: Assuming that the object `FromSubBean` is declared as follow: ```java -public class FromSubBean { - - private String serialNumber; - private Date creationDate; - - // getters and setters... - +public class FromSubBean { + + private String serialNumber; + private Date creationDate; + + // getters and setters... + } ``` and our source object and destination object are described as follow: ```java -public class FromBean { public class ToBean { - - private final int id; private final int id; - private final String name; private final String name; - private final FromSubBean subObject; private final String serialNumber; - private final Date creationDate; - - // all args constructor // all args constructor - // getters... // getters... - +public class FromBean { public class ToBean { + + private final int id; private final int id; + private final String name; private final String name; + private final FromSubBean subObject; private final String serialNumber; + private final Date creationDate; + + // all args constructor // all args constructor + // getters... // getters... + } } ``` -the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: +the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done by defining the whole path to the end property: ```java FieldMapping serialNumberMapping = new FieldMapping<>("subObject.serialNumber", "serialNumber"); FieldMapping creationDateMapping = new FieldMapping<>("subObject.creationDate", "creationDate"); @@ -294,6 +340,7 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); public class FromBean { public class ToBean { private final String name; @NotNull private final BigInteger id; public BigInteger identifier; + private final BigInteger index; public BigInteger index; private final List subBeanList; private final String name; private List list; private final List list; private final FromSubBean subObject; private final List nestedObjectList; @@ -315,9 +362,16 @@ beanUtils.getTransformer() .withFieldTransformer(localeTransformer); ``` +It's also possible to apply the same transformation function on multiple fields. Taking as an example the above bean and +assuming that we would negate both the id and the identifier, the transformer function has to be defined as follows: + +```java +FieldTransformer fieldTransformer = new FieldTransformer<>(List.of("identifier", "index"), BigInteger::negate); +``` + ### Assign a default value in case of missing field in the source object: -Assign a default value in case of missing field in the source object: +Assign a default value in case of a missing field in the source object: ```java public class FromBean { public class ToBean { @@ -339,7 +393,7 @@ ToBean toBean = beanUtils.getTransformer() ### Disable the default value set for primitive types in case they are null: -BULL by default sets the default value for all primitive types fields in case their value in the source object. +BULL by default sets the default value for all primitive types fields in case their value is in the source object. Given the following Java Bean: ```java @@ -355,7 +409,7 @@ public class FromBean { public class ToBean ``` in case the field `id` in the `FromBean` object is `null`, the value assigned the correspondent field in the `ToBean` object will be `0`. -To disable this you can simply do: +To disable this you can simply do: ```java ToBean toBean = beanUtils.getTransformer() @@ -366,7 +420,7 @@ in this case, the field `id` after the transformation will be `null` ### Applying a transformation function in case of missing fields in the source object: -Assign a default value in case of missing field in the source object: +Assign a default value in case of a missing field in the source object: ```java public class FromBean { public class ToBean { @@ -389,7 +443,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on a field contained in a nested object: -This example shows off a lambda transformation function that can be applied to a nested object field. +This example shows how a lambda transformation function can be applied to a nested object field. Given: @@ -409,7 +463,7 @@ public class ToSubBean { private final long index; } ``` -Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as follow: ```java FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); @@ -441,7 +495,7 @@ public class ToSubBean { // all args constructor } // getters... ``` -Assuming that the value `x` should be mapped into the field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as +Assuming that the value `x` should be mapped into the field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as follow: ```java ToBean toBean = beanUtils.getTransformer() @@ -474,7 +528,7 @@ public class FromSubBean { public class ToSubBe } } ``` Assuming that the lambda transformation function should be applied only to the field: `name` contained in the `ToSubBean` object, the transformation function has to be defined - as +as follow: ```java FieldTransformer nameTransformer = new FieldTransformer<>("name", StringUtils::capitalize); @@ -638,12 +692,12 @@ Transformer transformer = beanUtils.getTransformer() ToBean toBean = transformer.transform(fromBean, ToBean.class); ``` -**IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function defined on a specific field. +**IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function is defined on a specific field. This means that once the `FieldTransformer` function will be executed the field value has already been transformed. ## Builder supported patterns -The library support the transformation of Java Bean using the following Builder patterns: +The library supports the transformation of Java Bean using the following Builder patterns: ### Standard pattern: @@ -731,7 +785,7 @@ public class ItemType { } ``` -It's needed to enable the custom Builder Transformation as following: +It's needed to enable the custom Builder Transformation as follows: ```java ToBean toBean = new BeanTransformer() @@ -787,9 +841,9 @@ Following a comparison between the BULL functionalities and the following Third- | Annotation field validation | X | - | X | - | _[*] Immutable types are not supported by Dozer. When a type doesn't have a no-arg constructor and all fields are final, Dozer can't perform the mapping. - A workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ +A workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ _[+] Requires a custom configuration_ - + ## Performance Let's have a look at the performance library performance. The test has been executed on the following objects: @@ -812,7 +866,7 @@ Transformation time [screenshot](docs/site/resources/images/stats/performance/tr The Bean Utils library has been tested on a real case scenario integrating it into a real edge service (called BPE). The purpose was to compare the latency introduced by the library plus the memory/CPU usage. -The dashboard's screenshot shows the latency of the invoked downstream service (called BPAS) and the one where the library has been installed (BPE). +The dashboard's screenshot shows the latency of the invoked downstream service (called BPAS) and the one where the library has been installed (BPE). Following the obtained results: | | **Classic transformer** | **BeanUtils library** | @@ -826,7 +880,7 @@ Following the obtained results: ## Validation samples -Validate a java bean has never been so simple. The library offers different API related to this, following some examples: +Validating a java bean has never been so simple. The library offers different APIs related to this, following some examples: ### Validate a Java Bean: @@ -884,7 +938,7 @@ And one line code as: List violatedConstraints = beanUtils.getValidator().getConstraintViolationsMessages(sampleBean); ``` -this will returns a list containing a constraint validation message for the `id` field as it's null and the constraint: `@NotNull` is not met. +this will return a list containing a constraint validation message for the `id` field as it's null and the constraint: `@NotNull` is not met. in case it's needed to have the `ConstraintViolation` object: ```java @@ -894,7 +948,7 @@ Set> violatedConstraints = beanUtils.getValidator(). ## Primitive type object converter Converts a given primitive value into the given primitive type. -The supported types, in which an object can be converted (from / to), are: +The supported types, in which an object can be converted (from/to), are: * `Byte`, `byte` or `byte[]` * `Short` or `short` @@ -951,19 +1005,19 @@ Samples on how to transform a `Map` and all others function applicable to it can Detailed project documentation is available [here](https://opensource.expediagroup.com/bull), including some samples for [testing the library](https://opensource.expediagroup.com/bull/transformer/testing.html) inside your project. -An article that explains how it works, with suggestion and examples is available on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) +An article that explains how it works, with suggestions and examples, is available on DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) ## Credits -Created by: [Fabio Borriello](https://github.com/fborriello) with the contribution of: [Patrizio Munzi](https://github.com/patriziomunzi), +Created by: [Fabio Borriello](https://github.com/fborriello) with the contribution of: [Patrizio Munzi](https://github.com/patriziomunzi), [Andrea Marsiglia](https://github.com/AndreaMars94), [Giorgio Delle Grottaglie](https://github.com/geordie--) & the Hotels.com's Checkout team in Rome. The application's logo has been designed by Rob Light. ## Related articles - - DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) - - InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[PT-BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] +- DZone: [How to Transform Any Type of Java Bean With BULL](https://dzone.com/articles/how-to-transform-any-type-of-java-bean-with-one-li) +- InfoQ: [How Expedia Is Getting Rid of Java Bean Transformers](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/) [[EN](https://www.infoq.com/articles/expedia-rid-of-bean-transformers/)] [[PT-BR](https://www.infoq.com/br/articles/expedia-rid-of-bean-transformers/)] ## Release @@ -989,4 +1043,4 @@ For any question, proposal, or help, please refer to the slack channel: [#bull]( This project is available under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html). -Copyright 2018-2019 Expedia Inc. +Copyright 2018-2021 Expedia Inc. \ No newline at end of file diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java index 4a6ac4e4a..aeb972d75 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/BeanTransformerTest.java @@ -161,6 +161,31 @@ public void testRemoveFieldTransformerRaisesExceptionIfItsCalledWithNullParam() beanTransformer.removeFieldTransformer(null); } + /** + * Test that is possible to remove all the transformer settings. + */ + @Test + @SuppressWarnings("unchecked") + public void testResetWorksProperly() { + // GIVEN + BeanTransformer beanTransformer = underTest + .withFieldTransformer(new FieldTransformer<>(DEST_FIELD_NAME, val -> val), new FieldTransformer<>(REFLECTION_UTILS_FIELD_NAME, val -> val)) + .withFieldMapping(new FieldMapping<>(SOURCE_FIELD_NAME, DEST_FIELD_NAME)) + .skipTransformationForField(NAME_FIELD_NAME) + .setDefaultValueForMissingField(true); + + // WHEN + beanTransformer.reset(); + TransformerSettings transformerSettings = + (TransformerSettings) REFLECTION_UTILS.getFieldValue(beanTransformer, TRANSFORMER_SETTINGS_FIELD_NAME, TransformerSettings.class); + + // THEN + assertThat(transformerSettings.getFieldsTransformers()).isEmpty(); + assertThat(transformerSettings.getFieldsNameMapping()).isEmpty(); + assertThat(transformerSettings.getFieldsToSkip()).isEmpty(); + assertThat(transformerSettings.isSetDefaultValueForMissingField()).isFalse(); + } + /** * Test that the method: {@code getSourceFieldValue} raises a {@link NullPointerException} in case any of the parameters null. * @throws Exception uf the invocation fails diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java index f2af12eef..f01c1b71c 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java @@ -15,9 +15,12 @@ */ package com.expediagroup.beans.transformer; +import static java.math.BigInteger.ONE; + import static org.assertj.core.api.Assertions.assertThat; import java.math.BigInteger; +import java.util.List; import org.testng.annotations.Test; @@ -27,6 +30,7 @@ import com.expediagroup.beans.sample.mixed.MixedToFooMissingAllArgsConstructor; import com.expediagroup.beans.sample.mixed.MixedToFooMissingField; import com.expediagroup.beans.sample.mixed.MixedToFooNotExistingFields; +import com.expediagroup.beans.sample.mixed.MixedToFooSimpleNotExistingFields; import com.expediagroup.transformer.error.MissingFieldException; import com.expediagroup.transformer.model.FieldMapping; import com.expediagroup.transformer.model.FieldTransformer; @@ -36,6 +40,7 @@ */ public class MixedObjectTransformationTest extends AbstractBeanTransformerTest { private static final boolean ACTIVE = true; + private static final String INDEX_FIELD_NAME = "index"; /** * Test that a Mixed bean with a constructor containing the final field only is correctly copied. @@ -183,4 +188,62 @@ public void testTransformationOnAnExistingDestinationWorksProperly() { assertThat(mixedToFoo).usingRecursiveComparison() .isEqualTo(fromFoo); } + + /** + * Test that bean containing both final fields (with different names) and not with a source field mapped into + * multiple destination fields is correctly copied. + */ + @Test + public void testMixedBeanWithASourceFieldMappedIntoMultipleDestinationFieldsIsCorrectlyCopied() { + // GIVEN + var multipleDestinationFieldMapping = new FieldMapping<>(ID_FIELD_NAME, + ID_FIELD_NAME, INDEX_FIELD_NAME); + + // WHEN + var actual = underTest + .withFieldMapping(multipleDestinationFieldMapping) + .setDefaultValueForMissingField(true) + .transform(fromFooSimple, MixedToFooSimpleNotExistingFields.class); + + // THEN + assertThat(actual) + .hasFieldOrPropertyWithValue(ID_FIELD_NAME, fromFoo.getId()) + .hasFieldOrPropertyWithValue(INDEX_FIELD_NAME, fromFoo.getId()) + .usingRecursiveComparison() + .ignoringFields(INDEX_FIELD_NAME, AGE_FIELD_NAME, ACTIVE_FIELD_NAME) + .isEqualTo(fromFoo); + underTest.reset(); + } + + /** + * Test that bean containing both final fields (with different names) and not with a source field mapped into + * multiple destination fields and field transformeration applies on mutliple fields is correctly copied. + */ + @Test + public void testMixedBeanWithASourceFieldMappedIntoMultipleDestinationFieldsAndMultipleFieldTransformerIsCorrectlyCopied() { + // GIVEN + var valueToAdd = ONE; + var expectedIdValue = fromFooSimple.getId().add(valueToAdd); + var multipleDestinationFieldMapping = new FieldMapping<>(ID_FIELD_NAME, + ID_FIELD_NAME, INDEX_FIELD_NAME); + var multipleDestinationFieldTransformer = + new FieldTransformer(List.of(ID_FIELD_NAME, INDEX_FIELD_NAME), + val -> val.add(valueToAdd)); + + // WHEN + var actual = underTest + .withFieldMapping(multipleDestinationFieldMapping) + .withFieldTransformer(multipleDestinationFieldTransformer) + .setDefaultValueForMissingField(true) + .transform(fromFooSimple, MixedToFooSimpleNotExistingFields.class); + + // THEN + assertThat(actual) + .hasFieldOrPropertyWithValue(ID_FIELD_NAME, expectedIdValue) + .hasFieldOrPropertyWithValue(INDEX_FIELD_NAME, expectedIdValue) + .usingRecursiveComparison() + .ignoringFields(ID_FIELD_NAME, INDEX_FIELD_NAME, AGE_FIELD_NAME, ACTIVE_FIELD_NAME) + .isEqualTo(fromFoo); + underTest.reset(); + } } diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java index 9b88ed446..17fd185c8 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java @@ -59,7 +59,6 @@ public class MutableObjectTransformationTest extends AbstractBeanTransformerTest private static final String CLASS_UTILS_FIELD_NAME = "classUtils"; private static final String INJECT_VALUES_METHOD_NAME = "injectValues"; private static final String NESTED_OBJECT_NAME_FIELD_NAME = "nestedObject.name"; - private static final String ACTIVE_FIELD_NAME = "active"; private static final String CODE_FIELD_NAME = "code"; /** diff --git a/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java index 03c7a7c89..f5ae64080 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java @@ -15,11 +15,11 @@ */ package com.expediagroup.transformer; +import static java.util.Arrays.stream; + import static com.expediagroup.transformer.cache.CacheManagerFactory.getCacheManager; import static com.expediagroup.transformer.validator.Validator.notNull; -import java.util.Map; - import com.expediagroup.transformer.cache.CacheManager; import com.expediagroup.transformer.model.FieldMapping; import com.expediagroup.transformer.model.FieldTransformer; @@ -31,6 +31,7 @@ /** * Abstract class containing all method implementation that will be common to any {@link Transformer}. + * * @param the {@link Transformer} implementation. * @param the {@link TransformerSettings} implementation. * @param

      the {@link FieldMapping} and {@link FieldTransformer} key class type. @@ -60,13 +61,14 @@ public abstract class AbstractTransformer fieldsNameMapping = settings.getFieldsNameMapping(); - for (FieldMapping mapping : fieldMapping) { - fieldsNameMapping.put((P) mapping.destFieldName(), (P) mapping.sourceFieldName()); + var fieldsNameMapping = settings.getFieldsNameMapping(); + for (FieldMapping mapping : fieldMapping) { + stream(mapping.destFieldName()) + .forEach(destField -> fieldsNameMapping.put(destField, mapping.sourceFieldName())); } return (T) this; } @@ -95,9 +98,10 @@ public final T withFieldMapping(final FieldMapping... fieldMapping) { @Override @SuppressWarnings("unchecked") public final T withFieldTransformer(final FieldTransformer... fieldTransformer) { - Map fieldsTransformers = settings.getFieldsTransformers(); - for (FieldTransformer transformer : fieldTransformer) { - fieldsTransformers.put((P) transformer.getDestFieldName(), transformer); + var fieldsTransformers = settings.getFieldsTransformers(); + for (var transformer : fieldTransformer) { + transformer.getDestFieldName() + .forEach(destFieldName -> fieldsTransformers.put((P) destFieldName, transformer)); } return (T) this; } @@ -139,4 +143,13 @@ public final void resetFieldsTransformer() { settings.getFieldsTransformers().clear(); cacheManager.removeMatchingKeys(transformerFunctionRegex); } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public final void reset() { + settings = (S) new TransformerSettings<>(); + } } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java b/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java index 9eaaa8f92..4e972a621 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/Transformer.java @@ -58,4 +58,9 @@ public interface Transformer { * Removes all the configured fields transformer. */ void resetFieldsTransformer(); + + /** + * Removes all the configured settings. + */ + void reset(); } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java index 5700635c8..280d4fad8 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java @@ -22,5 +22,5 @@ * @param sourceFieldName the field name in the source object * @param destFieldName the field name in the destination object. */ -public record FieldMapping(T sourceFieldName, K destFieldName) { +public record FieldMapping(T sourceFieldName, K... destFieldName) { } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java index 358328bbc..3d7311a53 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldTransformer.java @@ -19,6 +19,7 @@ import static lombok.AccessLevel.PRIVATE; +import java.util.List; import java.util.function.Function; import java.util.function.Supplier; @@ -41,7 +42,7 @@ public class FieldTransformer { /** * The field name in the destination object. */ - private final String destFieldName; + private final List destFieldName; /** * The field transformer function. @@ -53,13 +54,22 @@ public class FieldTransformer { */ private final Supplier transformerSupplier; + /** + * Creates a field transformer with a lambda function to be applied on a list of fields. + * @param destinationFieldNames the field name in the destination object. + * @param fieldTransformerFunction the transformer function to apply on field + */ + public FieldTransformer(final List destinationFieldNames, final Function fieldTransformerFunction) { + this(destinationFieldNames, fieldTransformerFunction, null); + } + /** * Creates a field transformer with a lambda function to be applied on the field. * @param destinationFieldName the field name in the destination object. * @param fieldTransformerFunction the transformer function to apply on field */ public FieldTransformer(final String destinationFieldName, final Function fieldTransformerFunction) { - this(destinationFieldName, fieldTransformerFunction, null); + this(List.of(destinationFieldName), fieldTransformerFunction, null); } /** @@ -68,7 +78,7 @@ public FieldTransformer(final String destinationFieldName, final Function * @param fieldTransformerSupplier the transformer supplier to apply on field */ public FieldTransformer(final String destinationFieldName, final Supplier fieldTransformerSupplier) { - this(destinationFieldName, null, fieldTransformerSupplier); + this(List.of(destinationFieldName), null, fieldTransformerSupplier); } /** diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java b/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java index a741533f3..8c1e6a10e 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/TransformerSettings.java @@ -42,7 +42,7 @@ public class TransformerSettings { /** * Contains the lambda functions to be applied on a given fields. - * This features allows to apply transformation on the destination object value. + * This feature allows applying transformation on the destination object value. * e.g. The following instructions allows to negate the destination value of the identifier field. * {@code * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooSimpleNotExistingFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooSimpleNotExistingFields.java new file mode 100644 index 000000000..14bc750ee --- /dev/null +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooSimpleNotExistingFields.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.sample.mixed; + +import java.math.BigInteger; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Sample mixed object that contains multiple fields not existing in the source object. + */ +@AllArgsConstructor +@Getter +@Setter +public class MixedToFooSimpleNotExistingFields { + private final String name; + private final BigInteger id; + private final BigInteger index; + private int age; +} diff --git a/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java b/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java index 6b58b4b2f..a7a065183 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/AbstractTransformerTest.java @@ -64,6 +64,7 @@ public abstract class AbstractTransformerTest { protected static final String PHONE_NUMBER_DEST_FIELD_NAME = "phoneNumbers"; protected static final String PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME = "nestedObject.phoneNumbers"; protected static final String NAME_FIELD_NAME = "name"; + protected static final String ACTIVE_FIELD_NAME = "active"; protected static final float PRICE = 10.0f; protected static final Map SAMPLE_MAP = new HashMap<>(); protected static final Map> COMPLEX_MAP = new HashMap<>(); diff --git a/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java index 8557b83f6..ca4d5717d 100644 --- a/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/AbstractMapTransformer.java @@ -59,10 +59,12 @@ public Map transform(final Map sourceMap, final Class keyFieldsTransformers = settings.getKeyFieldsTransformers(); - for (FieldTransformer transformer : keyFieldTransformer) { - keyFieldsTransformers.put(transformer.getDestFieldName(), transformer); + for (var transformer : keyFieldTransformer) { + transformer.getDestFieldName() + .forEach(destFieldName -> keyFieldsTransformers.put(destFieldName, transformer)); } return this; } diff --git a/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java index 2f56a242c..f6b541da9 100644 --- a/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java +++ b/bull-map-transformer/src/main/java/com/expediagroup/map/transformer/model/MapTransformerSettings.java @@ -32,7 +32,7 @@ public class MapTransformerSettings extends TransformerSettings { /** * Contains the lambda functions to be applied on a given map key. - * This features allows to apply transformation on the destination object value. + * This feature allows applying transformation on the destination object value. * e.g. The following instructions allows to negate the destination value of the identifier field. * {@code * FieldTransformer fieldTransformer = new FieldTransformer<>("identifier", BigInteger::negate); diff --git a/docs/site/markdown/transformer/bean/samples.md b/docs/site/markdown/transformer/bean/samples.md index b4707bcad..69170e143 100644 --- a/docs/site/markdown/transformer/bean/samples.md +++ b/docs/site/markdown/transformer/bean/samples.md @@ -7,18 +7,17 @@ ### Simple case: ```java -public class FromBean { public class ToBean { - private final String name; @NotNull - private final BigInteger id; public BigInteger id; - private final List subBeanList; private final String name; - private List list; private final List list; - private final FromSubBean subObject; private final List subBeanList; - private ImmutableToSubFoo subObject; - - // all constructors // all args constructor - // getters and setters... // getters and setters... -} - } +public class FromBean { public class ToBean { + private final String name; @NotNull + private final BigInteger id; public BigInteger id; + private final List subBeanList; private final String name; + private List list; private final List list; + private final FromSubBean subObject; private final List subBeanList; + private ImmutableToSubFoo subObject; + + // all constructors // all args constructor + // getters and setters... // getters and setters... +} ``` And one line code as: ```java @@ -29,65 +28,111 @@ ToBean toBean = beanUtils.getTransformer().transform(fromBean, ToBean.class); From class and To class with different field names: ```java -public class FromBean { public class ToBean { - - private final String name; private final String differentName; - private final int id; private final int id; - private final List subBeanList; private final List subBeanList; - private final List list; private final List list; - private final FromSubBean subObject; private final ToSubBean subObject; - - // getters... - public ToBean(final String differentName, - final int id, +public class FromBean { public class ToBean { + + private final String name; private final String differentName; + private final int id; private final int id; + private final List subBeanList; private final List subBeanList; + private final List list; private final List list; + private final FromSubBean subObject; private final ToSubBean subObject; + + // getters... + public ToBean(final String differentName, + final int id, } final List subBeanList, - final List list, - final ToSubBean subObject) { - this.differentName = differentName; - this.id = id; - this.subBeanList = subBeanList; - this.list = list; - this.subObject = subObject; - } - - // getters... - - } + final List list, + final ToSubBean subObject) { + this.differentName = differentName; + this.id = id; + this.subBeanList = subBeanList; + this.list = list; + this.subObject = subObject; + } + + // getters... + +} ``` And one line code as: ```java -beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class);` +beanUtils.getTransformer().withFieldMapping(new FieldMapping<>("name", "differentName")).transform(fromBean, ToBean.class); +``` + +it is also possible to map a field in the source class into multiple fields in the destination object. + +Given the following source class: + +``` +public class SourceClass { + private final String name; + private final int id; +} ``` -### Mapping destination fields with correspondent fields contained inside one of the nested object in the source object: +the following destination class: + +``` +public class DestinationClass { + private final String name; + private final int id; + private final int index; +} +``` + +and the following operations: + +``` +var sourceObj = new SourceClass("foo", 123); + +var multipleFieldMapping = new FieldMapping<>("id", "index", "identifier"); + +var destObj = new BeanUtils().getBeanTransformer() + .withFieldMapping(multipleFieldMapping) + .transform(sourceObj, DestinationClass.class); + +System.out.println("name = " + destObj.getName()); +System.out.println("id = " + destObj.getId()); +System.out.println("index = " + destObj.getIndex()); +``` + +the output will be: + +``` +name = foo +id = 123 +index = 123 +``` + + +### Mapping destination fields with correspondent fields contained inside one of the nested objects in the source object: Assuming that the object `FromSubBean` is declared as follow: ```java -public class FromSubBean { - - private String serialNumber; - private Date creationDate; - - // getters and setters... - +public class FromSubBean { + + private String serialNumber; + private Date creationDate; + + // getters and setters... + } ``` and our source object and destination object are described as follow: ```java -public class FromBean { public class ToBean { - - private final int id; private final int id; - private final String name; private final String name; - private final FromSubBean subObject; private final String serialNumber; - private final Date creationDate; - - // all args constructor // all args constructor - // getters... // getters... - +public class FromBean { public class ToBean { + + private final int id; private final int id; + private final String name; private final String name; + private final FromSubBean subObject; private final String serialNumber; + private final Date creationDate; + + // all args constructor // all args constructor + // getters... // getters... + } } ``` -the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done defining the whole path to the end property: +the fields: `serialNumber` and `creationDate` needs to be retrieved from `subObject`, this can be done by defining the whole path to the end property: ```java FieldMapping serialNumberMapping = new FieldMapping<>("subObject.serialNumber", "serialNumber"); FieldMapping creationDateMapping = new FieldMapping<>("subObject.creationDate", "creationDate"); @@ -157,9 +202,16 @@ beanUtils.getTransformer() .withFieldTransformer(localeTransformer); ``` +It's also possible to apply the same transformation function on multiple fields. Taking as an example the above bean and +assuming that we would negate both the id and the identifier, the transformer function has to be defined as follows: + +```java +FieldTransformer fieldTransformer = new FieldTransformer<>(List.of("identifier", "index"), BigInteger::negate); +``` + ### Assign a default value in case of missing field in the source object: -Assign a default value in case of missing field in the source object: +Assign a default value in case of a missing field in the source object: ```java public class FromBean { public class ToBean { @@ -181,7 +233,7 @@ ToBean toBean = beanUtils.getTransformer() ### Disable the default value set for primitive types in case they are null: -BULL by default sets the default value for all primitive types fields in case their value in the source object. +BULL by default sets the default value for all primitive types fields in case their value is in the source object. Given the following Java Bean: ```java @@ -197,18 +249,18 @@ public class FromBean { public class ToBean ``` in case the field `id` in the `FromBean` object is `null`, the value assigned the correspondent field in the `ToBean` object will be `0`. -To disable this you can simply do: +To disable this you can simply do: ```java ToBean toBean = beanUtils.getTransformer() .setDefaultValueForMissingPrimitiveField(false).transform(fromBean, ToBean.class); ``` -in this case the field `id` after the transformation will be `null` +in this case, the field `id` after the transformation will be `null` ### Applying a transformation function in case of missing fields in the source object: -Assign a default value in case of missing field in the source object: +Assign a default value in case of a missing field in the source object: ```java public class FromBean { public class ToBean { @@ -231,7 +283,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on a field contained in a nested object: -This example shows of a lambda transformation function can be applied on a nested object field. +This example shows how a lambda transformation function can be applied to a nested object field. Given: @@ -251,7 +303,7 @@ public class ToSubBean { private final long index; } ``` -Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as follow: ```java FieldTransformer nameTransformer = new FieldTransformer<>("nestedObject.name", StringUtils::capitalize); @@ -283,7 +335,7 @@ public class ToSubBean { // all args constructor } // getters... ``` -Assuming that the value `x` should be mapped into field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as +Assuming that the value `x` should be mapped into the field: `x` contained into the `ToSubBean` object, the field mapping has to be defined as follow: ```java ToBean toBean = beanUtils.getTransformer() @@ -292,7 +344,7 @@ ToBean toBean = beanUtils.getTransformer() ### Apply a transformation function on all fields matching with the given one: -This example shows how a lambda transformation function can be applied on all fields matching with the given one independently from their position. +This example shows how a lambda transformation function can be applied to all fields matching with the given one independently from their position. Given: @@ -315,7 +367,8 @@ public class FromSubBean { public class ToSubBe // getters... // getters... } } ``` -Assuming that the lambda transformation function should be applied only to field: `name` contained into the `ToSubBean` object, the transformation function has to be defined as +Assuming that the lambda transformation function should be applied only to the field: `name` contained in the `ToSubBean` object, the transformation function has to be defined +as follow: ```java FieldTransformer nameTransformer = new FieldTransformer<>("name", StringUtils::capitalize); @@ -345,7 +398,7 @@ List actual = fromFooSimpleList.stream() .collect(Collectors.toList()); ``` -### Disable Java Beans validation: +### Enable Java Beans validation: Assuming that the field: `id` in the fromBean instance is null. ```java @@ -358,10 +411,10 @@ public class FromBean { public class ToBean // getters... // getters and setters... } } ``` -adding the following configuration no exception will be thrown: +adding the following configuration an exception will be thrown: ```java ToBean toBean = beanUtils.getTransformer() - .setValidationDisabled(true) + .setValidationEnabled(true) .transform(fromBean, ToBean.class); ``` @@ -415,11 +468,11 @@ beanUtils.getTransformer() where `nestedObject` is the name of the field in the destination object. -This feature allows to **transform an object keeping the data from different sources**. +This feature allows us to **transform an object keeping the data from different sources**. To better explain this function let's assume that the `ToBean` (defined above) should be transformed as follow: -- `name` field value has be taken from the `FromBean` object -- `nestedObject` field value has be taken from the `FromBean2` object +- `name` field value has been taken from the `FromBean` object +- `nestedObject` field value has been taken from the `FromBean2` object the objective can be reached by doing: ```java @@ -438,8 +491,7 @@ beanUtils.getTransformer() ``` ### Not existing field in the source object: - -In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library gets the field value from that method. +In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should gets the field value from that method. ```java public class FromBean { public class ToBean { private final BigInteger id; @@ -470,8 +522,8 @@ public class FromBean { public class ToBean ``` as, by default the primitive type conversion is disabled, to get the above object converted we should have -implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically from enabling the -functionality described above. +implemented transformer functions for both field `indexNumber` and `id`, but this can be done automatically by enabling the +the functionality described above. ```java Transformer transformer = beanUtils.getTransformer() @@ -480,13 +532,16 @@ Transformer transformer = beanUtils.getTransformer() ToBean toBean = transformer.transform(fromBean, ToBean.class); ``` +**IMPORTANT:** The primitive type transformation (if enabled) is executed before any other `FieldTransformer` function is defined on a specific field. +This means that once the `FieldTransformer` function will be executed the field value has already been transformed. + ## Transform Java Record ### Simple case: ```java -public record FromFooRecord(BigInteger id, String name) { public record RecordToFoo(BigInteger id, String name) { -} } +public record FromFooRecord(BigInteger id, String name) { public record RecordToFoo(BigInteger id, String name) { +} } ``` And one line code as: From bc7817240e9efb9555465a55ba877327a793f71d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Oct 2021 11:53:30 +0200 Subject: [PATCH 1531/1786] [maven-release-plugin] prepare release 2.1.1 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 7030473e2..a1d294a73 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 2f321b5e2..75b2398f1 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 807386dde..75bf341cc 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 0f7910941..a42c37a8f 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0c49e825a..15191939b 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index c13482418..e945a1822 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/pom.xml b/pom.xml index 691b02c68..603c46fb3 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.1-SNAPSHOT + 2.1.1 pom 2019 @@ -109,7 +109,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.1.1 From 141116045d806546fc85c764e5cd73b5f105329d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Oct 2021 11:53:30 +0200 Subject: [PATCH 1532/1786] [maven-release-plugin] prepare release 2.1.1 --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 7030473e2..a1d294a73 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 2f321b5e2..75b2398f1 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 807386dde..75bf341cc 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 0f7910941..a42c37a8f 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0c49e825a..15191939b 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/bull-report/pom.xml b/bull-report/pom.xml index c13482418..e945a1822 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/pom.xml b/pom.xml index 691b02c68..603c46fb3 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.1-SNAPSHOT + 2.1.1 pom 2019 @@ -109,7 +109,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - HEAD + 2.1.1 From eca23757d76f1d95c9c18f163a3ed01a9061261e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Oct 2021 11:53:34 +0200 Subject: [PATCH 1533/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index a1d294a73..0ef6b2ef1 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 75b2398f1..4db2ff8db 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 75bf341cc..e5d44b1d0 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index a42c37a8f..f024b05ba 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 15191939b..9733a2e50 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index e945a1822..0aa880201 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 603c46fb3..ea144210b 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.1 + 2.1.2-SNAPSHOT pom 2019 @@ -109,7 +109,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.1.1 + HEAD From 1e1987f309f77051ec356812d739ea77e47ad12a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Oct 2021 11:53:34 +0200 Subject: [PATCH 1534/1786] [maven-release-plugin] prepare for next development iteration --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index a1d294a73..0ef6b2ef1 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 75b2398f1..4db2ff8db 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 75bf341cc..e5d44b1d0 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index a42c37a8f..f024b05ba 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 15191939b..9733a2e50 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index e945a1822..0aa880201 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 603c46fb3..ea144210b 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.1 + 2.1.2-SNAPSHOT pom 2019 @@ -109,7 +109,7 @@ scm:git:git@github.com:ExpediaGroup/bull.git scm:git:git@github.com:ExpediaGroup/bull.git https://github.com/ExpediaGroup/bull - 2.1.1 + HEAD From bd1771c86494cecb3cf97c0b7e2b361e256e34ae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Oct 2021 12:10:40 +0200 Subject: [PATCH 1535/1786] Adds the logo into the bull badge --- README.md | 5 +++-- .../com/expediagroup/transformer/model/FieldMapping.java | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e4855ca42..ada78ad99 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![Coverage Status](https://coveralls.io/repos/github/ExpediaGroup/bull/badge.svg?branch=master)](https://coveralls.io/github/ExpediaGroup/bull?branch=master) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) [![License](https://img.shields.io/github/license/ExpediaGroup/bull.svg)](https://img.shields.io/github/license/ExpediaGroup/bull.svg) +[![Dependabot](https://img.shields.io/badge/dependabot-enabled-success?logo=dependabot)](https://img.shields.io/badge/dependabot-enabled-success?logo=dependabot) All BULL modules are available on Maven Central: @@ -1025,12 +1026,12 @@ All the instructions for releasing a new version are available at [RELEASES.md]( ## Badge your project -[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/ExpediaGroup/bull) +[![Bull enabled](https://img.shields.io/badge/bull-enabled-red?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAA8FBMVEUAAADRKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi////+bJRrYAAAATnRSTlMAABoFB0UGATtcHQsinVIEAz3Dy6QwHmzlylsTl/uGVvXonjMm0+pLApjjNO3nv0H3/N9VTVnauEn49r391vCCcnsJCn76aa6LFxnVZrus5DL8AAAApElEQVR42k2NA7rDABAGM89mbZupbbd7/9sU8Xzc/aUYwN09igMeHp+eHR94eX17tx/w8fn1+m08gJ/fv3+XG+vh8fpE/AEPGI9gKCxXIrYlGhOJJ5KWI5UWyWRzmBP3+au/UASe0Qy/peujXKlyr9XyHJIrtbraaLa0x1tbdGKdlPbo9vqDQX84GstEu5kOZ/PFcrXOqpsf7bFN72B/mHA8LVAuoY0XA5ziPJYAAAAASUVORK5CYII=)](https://github.com/ExpediaGroup/bull) Add the following snippet in your Markdown file: ``` -[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/ExpediaGroup/bull) +[![Bull enabled](https://img.shields.io/badge/bull-enabled-red?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAA8FBMVEUAAADRKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi////+bJRrYAAAATnRSTlMAABoFB0UGATtcHQsinVIEAz3Dy6QwHmzlylsTl/uGVvXonjMm0+pLApjjNO3nv0H3/N9VTVnauEn49r391vCCcnsJCn76aa6LFxnVZrus5DL8AAAApElEQVR42k2NA7rDABAGM89mbZupbbd7/9sU8Xzc/aUYwN09igMeHp+eHR94eX17tx/w8fn1+m08gJ/fv3+XG+vh8fpE/AEPGI9gKCxXIrYlGhOJJ5KWI5UWyWRzmBP3+au/UASe0Qy/peujXKlyr9XyHJIrtbraaLa0x1tbdGKdlPbo9vqDQX84GstEu5kOZ/PFcrXOqpsf7bFN72B/mHA8LVAuoY0XA5ziPJYAAAAASUVORK5CYII=)](https://github.com/ExpediaGroup/bull) ``` ## Support diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java index 280d4fad8..781fef122 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java @@ -23,4 +23,7 @@ * @param destFieldName the field name in the destination object. */ public record FieldMapping(T sourceFieldName, K... destFieldName) { + @SafeVarargs + public FieldMapping { + } } From 157c214e4619415e463dd8aea0e662f70ec932d3 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sun, 24 Oct 2021 12:10:40 +0200 Subject: [PATCH 1536/1786] Adds the logo into the bull badge --- README.md | 5 +++-- .../com/expediagroup/transformer/model/FieldMapping.java | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e4855ca42..ada78ad99 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ It's the only library able to transform Mutable, Immutable, and Mixed bean witho [![Coverage Status](https://coveralls.io/repos/github/ExpediaGroup/bull/badge.svg?branch=master)](https://coveralls.io/github/ExpediaGroup/bull?branch=master) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=BULL&metric=security_rating)](https://sonarcloud.io/dashboard?id=BULL) [![License](https://img.shields.io/github/license/ExpediaGroup/bull.svg)](https://img.shields.io/github/license/ExpediaGroup/bull.svg) +[![Dependabot](https://img.shields.io/badge/dependabot-enabled-success?logo=dependabot)](https://img.shields.io/badge/dependabot-enabled-success?logo=dependabot) All BULL modules are available on Maven Central: @@ -1025,12 +1026,12 @@ All the instructions for releasing a new version are available at [RELEASES.md]( ## Badge your project -[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/ExpediaGroup/bull) +[![Bull enabled](https://img.shields.io/badge/bull-enabled-red?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAA8FBMVEUAAADRKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi////+bJRrYAAAATnRSTlMAABoFB0UGATtcHQsinVIEAz3Dy6QwHmzlylsTl/uGVvXonjMm0+pLApjjNO3nv0H3/N9VTVnauEn49r391vCCcnsJCn76aa6LFxnVZrus5DL8AAAApElEQVR42k2NA7rDABAGM89mbZupbbd7/9sU8Xzc/aUYwN09igMeHp+eHR94eX17tx/w8fn1+m08gJ/fv3+XG+vh8fpE/AEPGI9gKCxXIrYlGhOJJ5KWI5UWyWRzmBP3+au/UASe0Qy/peujXKlyr9XyHJIrtbraaLa0x1tbdGKdlPbo9vqDQX84GstEu5kOZ/PFcrXOqpsf7bFN72B/mHA8LVAuoY0XA5ziPJYAAAAASUVORK5CYII=)](https://github.com/ExpediaGroup/bull) Add the following snippet in your Markdown file: ``` -[![Bull enabled](https://img.shields.io/badge/bull-enabled-red)](https://github.com/ExpediaGroup/bull) +[![Bull enabled](https://img.shields.io/badge/bull-enabled-red?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAA8FBMVEUAAADRKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi////+bJRrYAAAATnRSTlMAABoFB0UGATtcHQsinVIEAz3Dy6QwHmzlylsTl/uGVvXonjMm0+pLApjjNO3nv0H3/N9VTVnauEn49r391vCCcnsJCn76aa6LFxnVZrus5DL8AAAApElEQVR42k2NA7rDABAGM89mbZupbbd7/9sU8Xzc/aUYwN09igMeHp+eHR94eX17tx/w8fn1+m08gJ/fv3+XG+vh8fpE/AEPGI9gKCxXIrYlGhOJJ5KWI5UWyWRzmBP3+au/UASe0Qy/peujXKlyr9XyHJIrtbraaLa0x1tbdGKdlPbo9vqDQX84GstEu5kOZ/PFcrXOqpsf7bFN72B/mHA8LVAuoY0XA5ziPJYAAAAASUVORK5CYII=)](https://github.com/ExpediaGroup/bull) ``` ## Support diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java index 280d4fad8..781fef122 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java @@ -23,4 +23,7 @@ * @param destFieldName the field name in the destination object. */ public record FieldMapping(T sourceFieldName, K... destFieldName) { + @SafeVarargs + public FieldMapping { + } } From 1a8e5dc9ac31bf9dcf19508527e59936159e071d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Nov 2021 07:06:22 +0100 Subject: [PATCH 1537/1786] Bump checkstyle from 9.0.1 to 9.1 (#267) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.0.1 to 9.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.0.1...checkstyle-9.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ea144210b..eb459d131 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.3.1 3.1.2 2.8.1 - 9.0.1 + 9.1 3.0.0-M4 1.6.8 3.1.2 From adaf5b18e46a52c94275391a7e28d0f304f17f23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Nov 2021 07:06:22 +0100 Subject: [PATCH 1538/1786] Bump checkstyle from 9.0.1 to 9.1 (#267) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.0.1 to 9.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.0.1...checkstyle-9.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ea144210b..eb459d131 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.3.1 3.1.2 2.8.1 - 9.0.1 + 9.1 3.0.0-M4 1.6.8 3.1.2 From 28c2a719a12a0b419386524d49ddfe0ae61a5c08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 07:45:21 +0100 Subject: [PATCH 1539/1786] Bump mockito-core from 4.0.0 to 4.1.0 (#268) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.0.0 to 4.1.0. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eb459d131..23c4ac182 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.22 3.12.0 - 4.0.0 + 4.1.0 7.4.0 3.21.0 From 8ac7b0d6ab99fb4cd247180b154e6d55b39ab1d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 07:45:21 +0100 Subject: [PATCH 1540/1786] Bump mockito-core from 4.0.0 to 4.1.0 (#268) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.0.0 to 4.1.0. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eb459d131..23c4ac182 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.22 3.12.0 - 4.0.0 + 4.1.0 7.4.0 3.21.0 From 0385e67b1a93606c01e1cdaa5f236340272cf3d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Nov 2021 07:22:28 +0100 Subject: [PATCH 1541/1786] Bump checkstyle from 9.1 to 9.2 (#269) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.1 to 9.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.1...checkstyle-9.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 23c4ac182..b9e129e13 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.3.1 3.1.2 2.8.1 - 9.1 + 9.2 3.0.0-M4 1.6.8 3.1.2 From 150f6bad1bb01622f96159d0baf2c964d3d00311 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Nov 2021 07:22:28 +0100 Subject: [PATCH 1542/1786] Bump checkstyle from 9.1 to 9.2 (#269) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.1 to 9.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.1...checkstyle-9.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 23c4ac182..b9e129e13 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.3.1 3.1.2 2.8.1 - 9.1 + 9.2 3.0.0-M4 1.6.8 3.1.2 From a77f3235748edb433da491cb52cbeb949676c9e7 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 6 Dec 2021 10:11:20 +0100 Subject: [PATCH 1543/1786] Adds a check for duplicated dependency definition --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b9e129e13..f7912f242 100644 --- a/pom.xml +++ b/pom.xml @@ -687,7 +687,8 @@ ${maven.required.version} - + + From bc7971bc4fc1d44044f29637b5f1d0c63883c9b1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 6 Dec 2021 10:11:20 +0100 Subject: [PATCH 1544/1786] Adds a check for duplicated dependency definition --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b9e129e13..f7912f242 100644 --- a/pom.xml +++ b/pom.xml @@ -687,7 +687,8 @@ ${maven.required.version} - + + From 5e785aaa1133b2f25713a13a790be8e5f0f77b9f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 16 Dec 2021 15:50:40 +0100 Subject: [PATCH 1545/1786] Simplifies the spotless configuration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f7912f242..842d9a539 100644 --- a/pom.xml +++ b/pom.xml @@ -99,7 +99,7 @@ true false - \#java,\#javax,\#jakarta,\#org,\#,\#com,\#com.expedia,\#com.expediagroup,\#com.hotels,,\#lombok,java,javax,jakarta,org,,com,com.expedia,com.expediagroup,com.hotels,lombok + \#java,\#javax,\#jakarta,\#org,\#com,\#com.expediagroup,\#lombok,java,javax,jakarta,org,com,com.expediagroup,lombok, false From 8a0abc08dcf4fdb50e030bce28ffa4fbe3316b50 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 16 Dec 2021 15:50:40 +0100 Subject: [PATCH 1546/1786] Simplifies the spotless configuration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f7912f242..842d9a539 100644 --- a/pom.xml +++ b/pom.xml @@ -99,7 +99,7 @@ true false - \#java,\#javax,\#jakarta,\#org,\#,\#com,\#com.expedia,\#com.expediagroup,\#com.hotels,,\#lombok,java,javax,jakarta,org,,com,com.expedia,com.expediagroup,com.hotels,lombok + \#java,\#javax,\#jakarta,\#org,\#com,\#com.expediagroup,\#lombok,java,javax,jakarta,org,com,com.expediagroup,lombok, false From 9ded48ac9118191179b3541eaf810d58ad377d04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Dec 2021 08:14:47 +0100 Subject: [PATCH 1547/1786] Bump mockito-core from 4.1.0 to 4.2.0 (#270) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.1.0 to 4.2.0. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 842d9a539..f6f109353 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.22 3.12.0 - 4.1.0 + 4.2.0 7.4.0 3.21.0 From 448da5bff0f5af654e522e04616bfe18ce3cea61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Dec 2021 08:14:47 +0100 Subject: [PATCH 1548/1786] Bump mockito-core from 4.1.0 to 4.2.0 (#270) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.1.0 to 4.2.0. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 842d9a539..f6f109353 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.22 3.12.0 - 4.1.0 + 4.2.0 7.4.0 3.21.0 From b38b340f83b103cacf05896c57aa634466022bd8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Dec 2021 07:21:16 +0100 Subject: [PATCH 1549/1786] Bump wagon-ssh from 3.4.3 to 3.5.0 (#271) Bumps wagon-ssh from 3.4.3 to 3.5.0. --- updated-dependencies: - dependency-name: org.apache.maven.wagon:wagon-ssh dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f6f109353..f5c79b1f5 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ 2.3.1 - 3.4.3 + 3.5.0 0.12 github 3.9.1 From 1d28dffd0e884d93b63fdaeb0838e66bedeae69a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Dec 2021 07:21:16 +0100 Subject: [PATCH 1550/1786] Bump wagon-ssh from 3.4.3 to 3.5.0 (#271) Bumps wagon-ssh from 3.4.3 to 3.5.0. --- updated-dependencies: - dependency-name: org.apache.maven.wagon:wagon-ssh dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f6f109353..f5c79b1f5 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ 2.3.1 - 3.4.3 + 3.5.0 0.12 github 3.9.1 From 6624f675de9152b54f99aea934b23e4db5908553 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Dec 2021 06:55:33 +0100 Subject: [PATCH 1551/1786] Bump checkstyle from 9.2 to 9.2.1 (#274) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.2 to 9.2.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.2...checkstyle-9.2.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f5c79b1f5..e4e35678a 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.3.1 3.1.2 2.8.1 - 9.2 + 9.2.1 3.0.0-M4 1.6.8 3.1.2 From 674626439a7724d8f9f68c346ccf47ebbc016bec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Dec 2021 06:55:33 +0100 Subject: [PATCH 1552/1786] Bump checkstyle from 9.2 to 9.2.1 (#274) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.2 to 9.2.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.2...checkstyle-9.2.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f5c79b1f5..e4e35678a 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.3.1 3.1.2 2.8.1 - 9.2 + 9.2.1 3.0.0-M4 1.6.8 3.1.2 From d23790cb2f3b63c5137c88428650e27f95bd9712 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Dec 2021 07:22:16 +0100 Subject: [PATCH 1553/1786] Bump maven-site-plugin from 3.9.1 to 3.10.0 (#273) Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.9.1 to 3.10.0. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.9.1...maven-site-plugin-3.10.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e4e35678a..ec38954a7 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 3.5.0 0.12 github - 3.9.1 + 3.10.0 [3.8.1,) 3.0.1 From 1f60e3f87b0b395fb0871f0af097f696f0154a07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Dec 2021 07:22:16 +0100 Subject: [PATCH 1554/1786] Bump maven-site-plugin from 3.9.1 to 3.10.0 (#273) Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.9.1 to 3.10.0. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.9.1...maven-site-plugin-3.10.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e4e35678a..ec38954a7 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 3.5.0 0.12 github - 3.9.1 + 3.10.0 [3.8.1,) 3.0.1 From 9c3a9b0f3cd20b71ba25a3a9a8e5c3ba4d6b99fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Dec 2021 07:22:34 +0100 Subject: [PATCH 1555/1786] Bump wagon-ssh from 3.5.0 to 3.5.1 (#272) Bumps wagon-ssh from 3.5.0 to 3.5.1. --- updated-dependencies: - dependency-name: org.apache.maven.wagon:wagon-ssh dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec38954a7..9c2b5f195 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ 2.3.1 - 3.5.0 + 3.5.1 0.12 github 3.10.0 From f7cb1da9a602e48ddd83c6021771c89919ec1df0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Dec 2021 07:22:34 +0100 Subject: [PATCH 1556/1786] Bump wagon-ssh from 3.5.0 to 3.5.1 (#272) Bumps wagon-ssh from 3.5.0 to 3.5.1. --- updated-dependencies: - dependency-name: org.apache.maven.wagon:wagon-ssh dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec38954a7..9c2b5f195 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ 2.3.1 - 3.5.0 + 3.5.1 0.12 github 3.10.0 From e867994918e6f0d84c2fc90a7b1e5e1d53a98052 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jan 2022 09:01:26 +0100 Subject: [PATCH 1557/1786] Bump assertj-core from 3.21.0 to 3.22.0 (#275) Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.21.0 to 3.22.0. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.21.0...assertj-core-3.22.0) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9c2b5f195..2b0497b62 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 4.2.0 7.4.0 - 3.21.0 + 3.22.0 7.0.1.Final 3.4.2.Final From c06b2634e41e3ea55e35cb14ee7af8aa025d6518 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jan 2022 09:01:26 +0100 Subject: [PATCH 1558/1786] Bump assertj-core from 3.21.0 to 3.22.0 (#275) Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.21.0 to 3.22.0. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.21.0...assertj-core-3.22.0) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9c2b5f195..2b0497b62 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 4.2.0 7.4.0 - 3.21.0 + 3.22.0 7.0.1.Final 3.4.2.Final From 02a333cf306646af202f71e97eacf0f178589acd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jan 2022 10:09:30 +0100 Subject: [PATCH 1559/1786] Removes records to avoid using the enable-preview options (#276) Removes records objects to avoid hosting projects to being forced to use the enable-preview options --- CHANGELOG.md | 5 ++ bull-bean-transformer/pom.xml | 2 +- .../beans/populator/MapPopulator.java | 10 +-- .../RecordObjectTransformationTest.java | 62 ------------------- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- .../transformer/AbstractTransformer.java | 10 +-- .../transformer/model/FieldMapping.java | 32 ++++++++-- .../transformer/model/ItemType.java | 19 ++++-- .../transformer/model/MapType.java | 21 +++++-- .../beans/sample/record/FromFooRecord.java | 26 -------- .../beans/sample/record/RecordToFoo.java | 26 -------- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 11 ++-- 16 files changed, 83 insertions(+), 151 deletions(-) delete mode 100644 bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java delete mode 100644 bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java delete mode 100644 bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d0f0160a..bd77178c9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ + # BULL Change Log All notable changes to this project will be documented in this file. +### [2.1.2] 2022.01.05 +#### Changed +* Removes Java Records objects to avoid hosting projects to being forced to use the `enable-preview` options + ### [2.1.1] 2021.10.24 #### Added * Adds a function to reset all the defined settings diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 0ef6b2ef1..4a060d542 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java index 39de10f70..51473a062 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,8 +54,8 @@ class MapPopulator extends Populator> { * @return the populated map */ private Map getPopulatedObject(final Map fieldValue, final MapType mapType) { - final MapElemType keyType = mapType.keyType(); - final MapElemType elemType = mapType.elemType(); + final MapElemType keyType = mapType.getKeyType(); + final MapElemType elemType = mapType.getElemType(); final boolean keyIsPrimitive = isPrimitive(keyType); final boolean elemIsPrimitive = isPrimitive(elemType); Map populatedObject; @@ -78,7 +78,7 @@ class MapPopulator extends Populator> { * @return true if it's primitive, false otherwise */ private boolean isPrimitive(final MapElemType mapElemType) { - return mapElemType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) mapElemType).objectClass()); + return mapElemType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) mapElemType).getObjectClass()); } /** @@ -96,7 +96,7 @@ private T getElemValue(final MapElemType mapElemType, final boolean elemIsPr elemValue = value; } else { if (mapElemType.getClass().equals(ItemType.class)) { - elemValue = (T) transform(value, ((ItemType) mapElemType).objectClass(), ((ItemType) mapElemType).genericClass()); + elemValue = (T) transform(value, ((ItemType) mapElemType).getObjectClass(), ((ItemType) mapElemType).getGenericClass()); } else { elemValue = (T) getPopulatedObject((Map) value, (MapType) mapElemType); } diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java deleted file mode 100644 index 70e59fd94..000000000 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (C) 2019-2021 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.beans.transformer; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.testng.annotations.Test; - -import com.expediagroup.beans.sample.record.FromFooRecord; -import com.expediagroup.beans.sample.record.RecordToFoo; - -/** - * Unit test for all {@link BeanTransformer} functions related to a Java record. - */ -public class RecordObjectTransformationTest extends AbstractBeanTransformerTest { - /** - * Test that the transformation between Records works properly. - */ - @Test - public void testRecordIsCorrectlyCopied() { - // GIVEN - var sourceObject = new FromFooRecord(ID, NAME); - - // WHEN - var actual = underTest.transform(sourceObject, RecordToFoo.class); - - // THEN - assertThat(actual).usingRecursiveComparison() - .ignoringAllOverriddenEquals() - .isEqualTo(sourceObject); - } - - /** - * Test that the transformation from a bean to a records works properly. - */ - @Test - public void testThatARecordIsCorrectlyCopiedFromANormalBean() { - // GIVEN - - // WHEN - var actual = underTest.transform(fromFoo, RecordToFoo.class); - - // THEN - assertThat(actual) - .extracting(ID_FIELD_NAME, NAME_FIELD_NAME) - .containsExactly(fromFoo.getId(), fromFoo.getName()); - } - -} diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 4db2ff8db..d1e7417fa 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e5d44b1d0..0d20bf381 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java index f5ae64080..7014e6c85 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82,12 +82,12 @@ protected AbstractTransformer(final String transformerFunctionCachePrefix, final * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public final T withFieldMapping(final FieldMapping... fieldMapping) { var fieldsNameMapping = settings.getFieldsNameMapping(); for (FieldMapping mapping : fieldMapping) { - stream(mapping.destFieldName()) - .forEach(destField -> fieldsNameMapping.put(destField, mapping.sourceFieldName())); + stream(mapping.getDestFieldName()) + .forEach(destField -> fieldsNameMapping.put(destField, mapping.getSourceFieldName())); } return (T) this; } @@ -96,7 +96,7 @@ public final T withFieldMapping(final FieldMapping... fieldMapping) { * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public final T withFieldTransformer(final FieldTransformer... fieldTransformer) { var fieldsTransformers = settings.getFieldsTransformers(); for (var transformer : fieldTransformer) { diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java index 781fef122..5311d4f9a 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,35 @@ */ package com.expediagroup.transformer.model; +import lombok.Getter; +import lombok.ToString; + /** * Specifies the field's name mapping between the source object and destination one. * @param source element type * @param target element type - * @param sourceFieldName the field name in the source object - * @param destFieldName the field name in the destination object. */ -public record FieldMapping(T sourceFieldName, K... destFieldName) { - @SafeVarargs - public FieldMapping { +@Getter +@ToString +public class FieldMapping { + + /** + * The field name in the source object. + */ + private final T sourceFieldName; + + /** + * The field name in the destination object. + */ + private final K[] destFieldName; + + /** + * Specifies the field's name mapping between the source object and destination one. + * @param srcFieldName the field name in the source object + * @param destFieldsName the field name in the destination object. + */ + public FieldMapping(final T srcFieldName, final K... destFieldsName) { + this.sourceFieldName = srcFieldName; + this.destFieldName = destFieldsName; } } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java b/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java index 9775f16d2..a1aba254e 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,23 @@ package com.expediagroup.transformer.model; import lombok.Builder; +import lombok.Getter; /** * Bean class for mapping the "Generic" object type and its nested generic (if any). - * @param objectClass the object class. i.e. In case of: {@code Map, Integer>} the value wil be {@code List} - * @param genericClass the generic object class in the key object (if any). i.e. In case of: {@code Map, Integer>} the value wil be {@code String} */ +@Getter @Builder -public record ItemType(Class objectClass, Class genericClass) implements MapElemType { +public class ItemType implements MapElemType { + /** + * The object class. + * i.e. In case of: {@code Map, Integer>} the value wil be {@code List} + */ + private final Class objectClass; + + /** + * The generic object class in the key object (if any). + * i.e. In case of: {@code Map, Integer>} the value wil be {@code String} + */ + private final Class genericClass; } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java b/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java index 390399844..81f81501e 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,23 @@ */ package com.expediagroup.transformer.model; +import lombok.AllArgsConstructor; +import lombok.Getter; + /** * Bean class for mapping the java.util.Map type. - * @param keyType key object class - * @param elemType elem object class */ -public record MapType(MapElemType keyType, MapElemType elemType) implements MapElemType { +@AllArgsConstructor +@Getter +public class MapType implements MapElemType { + /** + * key object class. + */ + private final MapElemType keyType; + + /** + * elem object class. + */ + private final MapElemType elemType; + } diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java b/bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java deleted file mode 100644 index 1d0125db5..000000000 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (C) 2019-2021 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.beans.sample.record; - -import java.math.BigInteger; - -/** - * Sample record object. - * @param id the id - * @param name the foo name - */ -public record FromFooRecord(BigInteger id, String name) { -} diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java deleted file mode 100644 index 04a02e29e..000000000 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (C) 2019-2021 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.beans.sample.record; - -import java.math.BigInteger; - -/** - * Sample record object. - * @param id the id - * @param name the foo name - */ -public record RecordToFoo(BigInteger id, String name) { -} diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index f024b05ba..0ebc738fe 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 9733a2e50..7c15ba6e1 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 0aa880201..662abd339 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index 2b0497b62..9d4cfe9be 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT pom 2019 @@ -270,7 +270,7 @@ **/PerformanceTest.java - @{argLine} --enable-preview + @{argLine} @@ -357,7 +357,7 @@ **/PerformanceTest.java - @{argLine} --enable-preview + @{argLine} @@ -431,7 +431,6 @@ ${maven.compiler.target} true true - --enable-preview @@ -498,7 +497,7 @@ ${maven.surefire.plugin.version} false - @{argLine} --enable-preview + @{argLine} @@ -750,7 +749,6 @@ ${maven.javadoc-plugin.version} ${javadoc.skip} - --enable-preview ${jdk.version} @@ -776,7 +774,6 @@ maven-javadoc-plugin public - --enable-preview ${jdk.version} From d58f286c6f0c5e7bb54646bfdad50e7e211b8462 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 5 Jan 2022 10:09:30 +0100 Subject: [PATCH 1560/1786] Removes records to avoid using the enable-preview options (#276) Removes records objects to avoid hosting projects to being forced to use the enable-preview options --- CHANGELOG.md | 5 ++ bull-bean-transformer/pom.xml | 2 +- .../beans/populator/MapPopulator.java | 10 +-- .../RecordObjectTransformationTest.java | 62 ------------------- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- .../transformer/AbstractTransformer.java | 10 +-- .../transformer/model/FieldMapping.java | 32 ++++++++-- .../transformer/model/ItemType.java | 19 ++++-- .../transformer/model/MapType.java | 21 +++++-- .../beans/sample/record/FromFooRecord.java | 26 -------- .../beans/sample/record/RecordToFoo.java | 26 -------- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 11 ++-- 16 files changed, 83 insertions(+), 151 deletions(-) delete mode 100644 bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java delete mode 100644 bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java delete mode 100644 bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d0f0160a..bd77178c9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ + # BULL Change Log All notable changes to this project will be documented in this file. +### [2.1.2] 2022.01.05 +#### Changed +* Removes Java Records objects to avoid hosting projects to being forced to use the `enable-preview` options + ### [2.1.1] 2021.10.24 #### Added * Adds a function to reset all the defined settings diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 0ef6b2ef1..4a060d542 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java index 39de10f70..51473a062 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,8 +54,8 @@ class MapPopulator extends Populator> { * @return the populated map */ private Map getPopulatedObject(final Map fieldValue, final MapType mapType) { - final MapElemType keyType = mapType.keyType(); - final MapElemType elemType = mapType.elemType(); + final MapElemType keyType = mapType.getKeyType(); + final MapElemType elemType = mapType.getElemType(); final boolean keyIsPrimitive = isPrimitive(keyType); final boolean elemIsPrimitive = isPrimitive(elemType); Map populatedObject; @@ -78,7 +78,7 @@ class MapPopulator extends Populator> { * @return true if it's primitive, false otherwise */ private boolean isPrimitive(final MapElemType mapElemType) { - return mapElemType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) mapElemType).objectClass()); + return mapElemType.getClass().equals(ItemType.class) && classUtils.isPrimitiveOrSpecialType(((ItemType) mapElemType).getObjectClass()); } /** @@ -96,7 +96,7 @@ private T getElemValue(final MapElemType mapElemType, final boolean elemIsPr elemValue = value; } else { if (mapElemType.getClass().equals(ItemType.class)) { - elemValue = (T) transform(value, ((ItemType) mapElemType).objectClass(), ((ItemType) mapElemType).genericClass()); + elemValue = (T) transform(value, ((ItemType) mapElemType).getObjectClass(), ((ItemType) mapElemType).getGenericClass()); } else { elemValue = (T) getPopulatedObject((Map) value, (MapType) mapElemType); } diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java deleted file mode 100644 index 70e59fd94..000000000 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/RecordObjectTransformationTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (C) 2019-2021 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.beans.transformer; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.testng.annotations.Test; - -import com.expediagroup.beans.sample.record.FromFooRecord; -import com.expediagroup.beans.sample.record.RecordToFoo; - -/** - * Unit test for all {@link BeanTransformer} functions related to a Java record. - */ -public class RecordObjectTransformationTest extends AbstractBeanTransformerTest { - /** - * Test that the transformation between Records works properly. - */ - @Test - public void testRecordIsCorrectlyCopied() { - // GIVEN - var sourceObject = new FromFooRecord(ID, NAME); - - // WHEN - var actual = underTest.transform(sourceObject, RecordToFoo.class); - - // THEN - assertThat(actual).usingRecursiveComparison() - .ignoringAllOverriddenEquals() - .isEqualTo(sourceObject); - } - - /** - * Test that the transformation from a bean to a records works properly. - */ - @Test - public void testThatARecordIsCorrectlyCopiedFromANormalBean() { - // GIVEN - - // WHEN - var actual = underTest.transform(fromFoo, RecordToFoo.class); - - // THEN - assertThat(actual) - .extracting(ID_FIELD_NAME, NAME_FIELD_NAME) - .containsExactly(fromFoo.getId(), fromFoo.getName()); - } - -} diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 4db2ff8db..d1e7417fa 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index e5d44b1d0..0d20bf381 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java index f5ae64080..7014e6c85 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/AbstractTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82,12 +82,12 @@ protected AbstractTransformer(final String transformerFunctionCachePrefix, final * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public final T withFieldMapping(final FieldMapping... fieldMapping) { var fieldsNameMapping = settings.getFieldsNameMapping(); for (FieldMapping mapping : fieldMapping) { - stream(mapping.destFieldName()) - .forEach(destField -> fieldsNameMapping.put(destField, mapping.sourceFieldName())); + stream(mapping.getDestFieldName()) + .forEach(destField -> fieldsNameMapping.put(destField, mapping.getSourceFieldName())); } return (T) this; } @@ -96,7 +96,7 @@ public final T withFieldMapping(final FieldMapping... fieldMapping) { * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public final T withFieldTransformer(final FieldTransformer... fieldTransformer) { var fieldsTransformers = settings.getFieldsTransformers(); for (var transformer : fieldTransformer) { diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java index 781fef122..5311d4f9a 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/FieldMapping.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,35 @@ */ package com.expediagroup.transformer.model; +import lombok.Getter; +import lombok.ToString; + /** * Specifies the field's name mapping between the source object and destination one. * @param source element type * @param target element type - * @param sourceFieldName the field name in the source object - * @param destFieldName the field name in the destination object. */ -public record FieldMapping(T sourceFieldName, K... destFieldName) { - @SafeVarargs - public FieldMapping { +@Getter +@ToString +public class FieldMapping { + + /** + * The field name in the source object. + */ + private final T sourceFieldName; + + /** + * The field name in the destination object. + */ + private final K[] destFieldName; + + /** + * Specifies the field's name mapping between the source object and destination one. + * @param srcFieldName the field name in the source object + * @param destFieldsName the field name in the destination object. + */ + public FieldMapping(final T srcFieldName, final K... destFieldsName) { + this.sourceFieldName = srcFieldName; + this.destFieldName = destFieldsName; } } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java b/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java index 9775f16d2..a1aba254e 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/ItemType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,23 @@ package com.expediagroup.transformer.model; import lombok.Builder; +import lombok.Getter; /** * Bean class for mapping the "Generic" object type and its nested generic (if any). - * @param objectClass the object class. i.e. In case of: {@code Map, Integer>} the value wil be {@code List} - * @param genericClass the generic object class in the key object (if any). i.e. In case of: {@code Map, Integer>} the value wil be {@code String} */ +@Getter @Builder -public record ItemType(Class objectClass, Class genericClass) implements MapElemType { +public class ItemType implements MapElemType { + /** + * The object class. + * i.e. In case of: {@code Map, Integer>} the value wil be {@code List} + */ + private final Class objectClass; + + /** + * The generic object class in the key object (if any). + * i.e. In case of: {@code Map, Integer>} the value wil be {@code String} + */ + private final Class genericClass; } diff --git a/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java b/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java index 390399844..81f81501e 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/model/MapType.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,23 @@ */ package com.expediagroup.transformer.model; +import lombok.AllArgsConstructor; +import lombok.Getter; + /** * Bean class for mapping the java.util.Map type. - * @param keyType key object class - * @param elemType elem object class */ -public record MapType(MapElemType keyType, MapElemType elemType) implements MapElemType { +@AllArgsConstructor +@Getter +public class MapType implements MapElemType { + /** + * key object class. + */ + private final MapElemType keyType; + + /** + * elem object class. + */ + private final MapElemType elemType; + } diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java b/bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java deleted file mode 100644 index 1d0125db5..000000000 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/record/FromFooRecord.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (C) 2019-2021 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.beans.sample.record; - -import java.math.BigInteger; - -/** - * Sample record object. - * @param id the id - * @param name the foo name - */ -public record FromFooRecord(BigInteger id, String name) { -} diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java deleted file mode 100644 index 04a02e29e..000000000 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/record/RecordToFoo.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (C) 2019-2021 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.beans.sample.record; - -import java.math.BigInteger; - -/** - * Sample record object. - * @param id the id - * @param name the foo name - */ -public record RecordToFoo(BigInteger id, String name) { -} diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index f024b05ba..0ebc738fe 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 9733a2e50..7c15ba6e1 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 0aa880201..662abd339 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index 2b0497b62..9d4cfe9be 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.2-SNAPSHOT + 2.1.3-SNAPSHOT pom 2019 @@ -270,7 +270,7 @@ **/PerformanceTest.java - @{argLine} --enable-preview + @{argLine} @@ -357,7 +357,7 @@ **/PerformanceTest.java - @{argLine} --enable-preview + @{argLine} @@ -431,7 +431,6 @@ ${maven.compiler.target} true true - --enable-preview @@ -498,7 +497,7 @@ ${maven.surefire.plugin.version} false - @{argLine} --enable-preview + @{argLine} @@ -750,7 +749,6 @@ ${maven.javadoc-plugin.version} ${javadoc.skip} - --enable-preview ${jdk.version} @@ -776,7 +774,6 @@ maven-javadoc-plugin public - --enable-preview ${jdk.version} From 0711eea35e7c2cf00a3a432c1a824cbd0ce969b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jan 2022 09:55:51 +0100 Subject: [PATCH 1561/1786] Bump testng from 7.4.0 to 7.5 (#277) * Bump testng from 7.4.0 to 7.5 Bumps [testng](https://github.com/cbeust/testng) from 7.4.0 to 7.5. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/compare/7.4.0...7.5) --- pom.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d4cfe9be..5ae38ccc3 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.12.0 4.2.0 - 7.4.0 + 7.5 3.22.0 7.0.1.Final @@ -177,6 +177,10 @@ com.google.guava guava + + com.google.code.findbugs + jsr305 + org.yaml snakeyaml From 5ffb573fa985a9ac7fb5c8437c56b6409251e5cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jan 2022 09:55:51 +0100 Subject: [PATCH 1562/1786] Bump testng from 7.4.0 to 7.5 (#277) * Bump testng from 7.4.0 to 7.5 Bumps [testng](https://github.com/cbeust/testng) from 7.4.0 to 7.5. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/compare/7.4.0...7.5) --- pom.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d4cfe9be..5ae38ccc3 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.12.0 4.2.0 - 7.4.0 + 7.5 3.22.0 7.0.1.Final @@ -177,6 +177,10 @@ com.google.guava guava + + com.google.code.findbugs + jsr305 + org.yaml snakeyaml From 7dc8228df885c84bef0ead5fa2b613e5cbadc212 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 10 Jan 2022 10:43:17 +0100 Subject: [PATCH 1563/1786] Move to Javax (#278) * replaces jakarta with javax * Replaces jakarta with javax * updates the changelog * [maven-release-plugin] prepare release 2.2.0 * [maven-release-plugin] prepare for next development iteration Co-authored-by: Fabio Borriello --- CHANGELOG-JDK11.md | 4 ++++ CHANGELOG.md | 4 ++++ bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 4 ++-- .../expediagroup/transformer/validator/Validator.java | 4 ++-- .../transformer/validator/ValidatorImpl.java | 10 +++++----- .../beans/sample/immutable/ImmutableToFoo.java | 4 ++-- .../immutable/ImmutableToFooCustomAnnotation.java | 4 ++-- .../sample/immutable/ImmutableToFooDiffFields.java | 4 ++-- .../ImmutableToFooMissingCustomAnnotation.java | 4 ++-- .../beans/sample/immutable/ImmutableToFooSubClass.java | 4 ++-- .../immutable/ImmutableToSubFooCustomAnnotation.java | 4 ++-- .../expediagroup/beans/sample/mixed/MixedToFoo.java | 4 ++-- .../mixed/MixedToFooMissingAllArgsConstructor.java | 4 ++-- .../sample/mixed/MixedToFooMissingConstructor.java | 4 ++-- .../expediagroup/transformer/utils/ClassUtilsTest.java | 4 ++-- .../transformer/utils/ReflectionUtilsTest.java | 6 +++--- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 10 +++++----- 22 files changed, 50 insertions(+), 42 deletions(-) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index 2a86e4c62..dd815730a 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [2.1.0-jdk11] 2022.01.10 +#### Changed +* Updated `hibernate-validator` version to `6.2.1.Final` (was `7.0.1.Final`). This replaces the jakarta validation with the javax one. + ### [2.0.1-jdk11] 2021.10.24 #### Added * Adds a function to reset all the defined settings diff --git a/CHANGELOG.md b/CHANGELOG.md index bd77178c9..a77fcc394 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. +### [2.2.0] 2022.01.10 +#### Changed +* Updated `hibernate-validator` version to `6.2.1.Final` (was `7.0.1.Final`). This replaces the jakarta validation with the javax one. + ### [2.1.2] 2022.01.05 #### Changed * Removes Java Records objects to avoid hosting projects to being forced to use the `enable-preview` options diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 4a060d542..0699c03b1 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index d1e7417fa..5e0af1f00 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 0d20bf381..2cd922a83 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT @@ -34,7 +34,7 @@ org.glassfish - jakarta.el + javax.el diff --git a/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java b/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java index f38167fa1..fe4489cf4 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import java.util.List; import java.util.Set; -import jakarta.validation.ConstraintViolation; +import javax.validation.ConstraintViolation; import com.expediagroup.transformer.error.InvalidBeanException; diff --git a/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java b/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java index e3a077c52..c882edf2f 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; -import static jakarta.validation.Validation.buildDefaultValidatorFactory; +import static javax.validation.Validation.buildDefaultValidatorFactory; import static org.apache.commons.lang3.StringUtils.SPACE; @@ -26,7 +26,7 @@ import java.util.Set; import java.util.function.Function; -import jakarta.validation.ConstraintViolation; +import javax.validation.ConstraintViolation; import com.expediagroup.transformer.cache.CacheManager; import com.expediagroup.transformer.cache.CacheManagerFactory; @@ -98,9 +98,9 @@ private Function, String> getConstraintViolationMess * Creates the validator. * @return a {@link javax.validation.Validator} instance. */ - private jakarta.validation.Validator getValidator() { + private javax.validation.Validator getValidator() { var cacheKey = "BeanValidator"; - return cacheManager.getFromCache(cacheKey, jakarta.validation.Validator.class) + return cacheManager.getFromCache(cacheKey, javax.validation.Validator.class) .orElseGet(() -> { var validator = buildDefaultValidatorFactory().getValidator(); cacheManager.cacheObject(cacheKey, validator); diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java index 7ddb2845f..7e961dce3 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java index cd88fad67..a65284bb8 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java index 84c9bee01..0b4926669 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java index d7895f0b4..5e603d815 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ */ package com.expediagroup.beans.sample.immutable; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java index cf35004c8..7c0351b7a 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import lombok.Getter; import lombok.ToString; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java index 7fb38968d..fdd30c04a 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.util.List; import java.util.Map; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java index cefee46e2..34c3255a2 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java index 3149a8d10..eb0f2ca8a 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java index 18d6a0bf6..d3917083e 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ import java.math.BigInteger; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java index f44d8939b..46420dd6e 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java index 94292cf36..2498e7840 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,8 +41,8 @@ import java.util.Map; import java.util.Optional; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.mockito.InjectMocks; diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 0ebc738fe..3550e13af 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 7c15ba6e1..7a47323d5 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 662abd339..f0e6fec7b 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 5ae38ccc3..cc309b1b8 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT pom 2019 @@ -57,10 +57,10 @@ 7.5 3.22.0 - 7.0.1.Final + 6.2.1.Final 3.4.2.Final 1.7.32 - 4.0.2 + 3.0.0 0.8.7 1.0 @@ -151,8 +151,8 @@ org.glassfish - jakarta.el - ${glassfish.jakarta.el.version} + javax.el + ${glassfish.javax.el.version} From 077b189fef0d8b6ef5d4014695ec4768b5e02c4e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 10 Jan 2022 10:43:17 +0100 Subject: [PATCH 1564/1786] Move to Javax (#278) * replaces jakarta with javax * Replaces jakarta with javax * updates the changelog * [maven-release-plugin] prepare release 2.2.0 * [maven-release-plugin] prepare for next development iteration Co-authored-by: Fabio Borriello --- CHANGELOG-JDK11.md | 4 ++++ CHANGELOG.md | 4 ++++ bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 4 ++-- .../expediagroup/transformer/validator/Validator.java | 4 ++-- .../transformer/validator/ValidatorImpl.java | 10 +++++----- .../beans/sample/immutable/ImmutableToFoo.java | 4 ++-- .../immutable/ImmutableToFooCustomAnnotation.java | 4 ++-- .../sample/immutable/ImmutableToFooDiffFields.java | 4 ++-- .../ImmutableToFooMissingCustomAnnotation.java | 4 ++-- .../beans/sample/immutable/ImmutableToFooSubClass.java | 4 ++-- .../immutable/ImmutableToSubFooCustomAnnotation.java | 4 ++-- .../expediagroup/beans/sample/mixed/MixedToFoo.java | 4 ++-- .../mixed/MixedToFooMissingAllArgsConstructor.java | 4 ++-- .../sample/mixed/MixedToFooMissingConstructor.java | 4 ++-- .../expediagroup/transformer/utils/ClassUtilsTest.java | 4 ++-- .../transformer/utils/ReflectionUtilsTest.java | 6 +++--- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 10 +++++----- 22 files changed, 50 insertions(+), 42 deletions(-) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index 2a86e4c62..dd815730a 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [2.1.0-jdk11] 2022.01.10 +#### Changed +* Updated `hibernate-validator` version to `6.2.1.Final` (was `7.0.1.Final`). This replaces the jakarta validation with the javax one. + ### [2.0.1-jdk11] 2021.10.24 #### Added * Adds a function to reset all the defined settings diff --git a/CHANGELOG.md b/CHANGELOG.md index bd77178c9..a77fcc394 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. +### [2.2.0] 2022.01.10 +#### Changed +* Updated `hibernate-validator` version to `6.2.1.Final` (was `7.0.1.Final`). This replaces the jakarta validation with the javax one. + ### [2.1.2] 2022.01.05 #### Changed * Removes Java Records objects to avoid hosting projects to being forced to use the `enable-preview` options diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 4a060d542..0699c03b1 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index d1e7417fa..5e0af1f00 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 0d20bf381..2cd922a83 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT @@ -34,7 +34,7 @@ org.glassfish - jakarta.el + javax.el diff --git a/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java b/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java index f38167fa1..fe4489cf4 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import java.util.List; import java.util.Set; -import jakarta.validation.ConstraintViolation; +import javax.validation.ConstraintViolation; import com.expediagroup.transformer.error.InvalidBeanException; diff --git a/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java b/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java index e3a077c52..c882edf2f 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; -import static jakarta.validation.Validation.buildDefaultValidatorFactory; +import static javax.validation.Validation.buildDefaultValidatorFactory; import static org.apache.commons.lang3.StringUtils.SPACE; @@ -26,7 +26,7 @@ import java.util.Set; import java.util.function.Function; -import jakarta.validation.ConstraintViolation; +import javax.validation.ConstraintViolation; import com.expediagroup.transformer.cache.CacheManager; import com.expediagroup.transformer.cache.CacheManagerFactory; @@ -98,9 +98,9 @@ private Function, String> getConstraintViolationMess * Creates the validator. * @return a {@link javax.validation.Validator} instance. */ - private jakarta.validation.Validator getValidator() { + private javax.validation.Validator getValidator() { var cacheKey = "BeanValidator"; - return cacheManager.getFromCache(cacheKey, jakarta.validation.Validator.class) + return cacheManager.getFromCache(cacheKey, javax.validation.Validator.class) .orElseGet(() -> { var validator = buildDefaultValidatorFactory().getValidator(); cacheManager.cacheObject(cacheKey, validator); diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java index 7ddb2845f..7e961dce3 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java index cd88fad67..a65284bb8 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java index 84c9bee01..0b4926669 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java index d7895f0b4..5e603d815 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ */ package com.expediagroup.beans.sample.immutable; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java index cf35004c8..7c0351b7a 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import lombok.Getter; import lombok.ToString; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java index 7fb38968d..fdd30c04a 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.util.List; import java.util.Map; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java index cefee46e2..34c3255a2 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java index 3149a8d10..eb0f2ca8a 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java index 18d6a0bf6..d3917083e 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ import java.math.BigInteger; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java index f44d8939b..46420dd6e 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotNull; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java index 94292cf36..2498e7840 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,8 +41,8 @@ import java.util.Map; import java.util.Optional; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.mockito.InjectMocks; diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 0ebc738fe..3550e13af 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 7c15ba6e1..7a47323d5 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 662abd339..f0e6fec7b 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index 5ae38ccc3..cc309b1b8 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.1.3-SNAPSHOT + 2.2.1-SNAPSHOT pom 2019 @@ -57,10 +57,10 @@ 7.5 3.22.0 - 7.0.1.Final + 6.2.1.Final 3.4.2.Final 1.7.32 - 4.0.2 + 3.0.0 0.8.7 1.0 @@ -151,8 +151,8 @@ org.glassfish - jakarta.el - ${glassfish.jakarta.el.version} + javax.el + ${glassfish.javax.el.version} From 60567bbad05e22aae8148ebe4978a703f0ef6daa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jan 2022 09:24:44 +0100 Subject: [PATCH 1565/1786] Bump jboss-logging from 3.4.2.Final to 3.4.3.Final (#280) * Bump jboss-logging from 3.4.2.Final to 3.4.3.Final --- bull-common/pom.xml | 16 ++++++++++++++++ pom.xml | 13 ++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 2cd922a83..1ae75f2ca 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -26,12 +26,28 @@ org.jboss.logging jboss-logging + + org.jboss.logging + jboss-logging-annotations + + + org.jboss.logging + jboss-logging-processor + org.jboss.logging jboss-logging + + org.jboss.logging + jboss-logging-annotations + + + org.jboss.logging + jboss-logging-processor + org.glassfish javax.el diff --git a/pom.xml b/pom.xml index cc309b1b8..af052ceab 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,8 @@ 3.22.0 6.2.1.Final - 3.4.2.Final + 3.4.3.Final + 2.2.1.Final 1.7.32 3.0.0 @@ -149,6 +150,16 @@ jboss-logging ${jboss-logging.version} + + org.jboss.logging + jboss-logging-annotations + ${jboss-logging-modules.version} + + + org.jboss.logging + jboss-logging-processor + ${jboss-logging-modules.version} + org.glassfish javax.el From 0d4c9076e9e2b6ace17e3a52ee5c509bb6d07972 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jan 2022 09:24:44 +0100 Subject: [PATCH 1566/1786] Bump jboss-logging from 3.4.2.Final to 3.4.3.Final (#280) * Bump jboss-logging from 3.4.2.Final to 3.4.3.Final --- bull-common/pom.xml | 16 ++++++++++++++++ pom.xml | 13 ++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 2cd922a83..1ae75f2ca 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -26,12 +26,28 @@ org.jboss.logging jboss-logging + + org.jboss.logging + jboss-logging-annotations + + + org.jboss.logging + jboss-logging-processor + org.jboss.logging jboss-logging + + org.jboss.logging + jboss-logging-annotations + + + org.jboss.logging + jboss-logging-processor + org.glassfish javax.el diff --git a/pom.xml b/pom.xml index cc309b1b8..af052ceab 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,8 @@ 3.22.0 6.2.1.Final - 3.4.2.Final + 3.4.3.Final + 2.2.1.Final 1.7.32 3.0.0 @@ -149,6 +150,16 @@ jboss-logging ${jboss-logging.version} + + org.jboss.logging + jboss-logging-annotations + ${jboss-logging-modules.version} + + + org.jboss.logging + jboss-logging-processor + ${jboss-logging-modules.version} + org.glassfish javax.el From 6c4db2a205bfa39c47542c794600d0fe7b325f4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jan 2022 06:42:41 +0100 Subject: [PATCH 1567/1786] Bump slf4j-api from 1.7.32 to 1.7.33 (#281) Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.32 to 1.7.33. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.32...v_1.7.33) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index af052ceab..dda8b48b0 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.1.Final 3.4.3.Final 2.2.1.Final - 1.7.32 + 1.7.33 3.0.0 0.8.7 From d7419ce9a477797e4ce9057d420c3d0886274b50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jan 2022 06:42:41 +0100 Subject: [PATCH 1568/1786] Bump slf4j-api from 1.7.32 to 1.7.33 (#281) Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.32 to 1.7.33. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.32...v_1.7.33) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index af052ceab..dda8b48b0 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.1.Final 3.4.3.Final 2.2.1.Final - 1.7.32 + 1.7.33 3.0.0 0.8.7 From 4cf20b3a7b29510f6533e0965b565681b1919a5c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 14 Jan 2022 18:21:37 +0100 Subject: [PATCH 1569/1786] double extra lines cleanup --- .../beans/transformer/ImmutableObjectTransformationTest.java | 1 - .../java/com/expediagroup/transformer/utils/ClassUtilsTest.java | 1 - .../com/expediagroup/transformer/utils/ReflectionUtilsTest.java | 2 -- .../main/java/com/expediagroup/beans/conversion/Converter.java | 1 - 4 files changed, 5 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java index 7d614d519..64da90a3f 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java @@ -15,7 +15,6 @@ */ package com.expediagroup.beans.transformer; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java index 46420dd6e..7557b6f5b 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java @@ -665,7 +665,6 @@ public void testAllParameterAnnotatedWithWorksAsExpected(final String testCaseDe // GIVEN Constructor constructor = ImmutableToFooCustomAnnotation.class.getConstructors()[0]; - // WHEN boolean actual = underTest.allParameterAnnotatedWith(constructor, annotationClass); diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java index 2498e7840..02f868845 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java @@ -464,7 +464,6 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong MutableToFoo mutableToFoo = createMutableToFoo(null); Method idSetterMethod = underTest.getSetterMethodForField(MutableToFoo.class, LIST_FIELD_NAME, List.class); - // WHEN ThrowingCallable actual = () -> getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) @@ -549,7 +548,6 @@ public void testGetDeclaredFieldTypeWorksProperly() { assertThat(actual).isNotNull(); } - /** * Tests that the method {@code getGenericFieldType} works properly. * @param testCaseDescription the test case description diff --git a/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java index 4c1e7b8ba..292a99f7c 100644 --- a/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java @@ -32,7 +32,6 @@ public interface Converter { */ Optional> getConversionFunction(Class sourceClass, Class targetClass); - /** * Converts a given primitive value into the given primitive type. * @param valueToConvert the value to be converted From 0be31df08a1fb9a0c1c77ddd2ed94a9f4c8d46ae Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 14 Jan 2022 18:21:37 +0100 Subject: [PATCH 1570/1786] double extra lines cleanup --- .../beans/transformer/ImmutableObjectTransformationTest.java | 1 - .../java/com/expediagroup/transformer/utils/ClassUtilsTest.java | 1 - .../com/expediagroup/transformer/utils/ReflectionUtilsTest.java | 2 -- .../main/java/com/expediagroup/beans/conversion/Converter.java | 1 - 4 files changed, 5 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java index 7d614d519..64da90a3f 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java @@ -15,7 +15,6 @@ */ package com.expediagroup.beans.transformer; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java index 46420dd6e..7557b6f5b 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java @@ -665,7 +665,6 @@ public void testAllParameterAnnotatedWithWorksAsExpected(final String testCaseDe // GIVEN Constructor constructor = ImmutableToFooCustomAnnotation.class.getConstructors()[0]; - // WHEN boolean actual = underTest.allParameterAnnotatedWith(constructor, annotationClass); diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java index 2498e7840..02f868845 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java @@ -464,7 +464,6 @@ public void testInvokeMethodRaisesAnIllegalArgumentExceptionIfTheArgumentIsWrong MutableToFoo mutableToFoo = createMutableToFoo(null); Method idSetterMethod = underTest.getSetterMethodForField(MutableToFoo.class, LIST_FIELD_NAME, List.class); - // WHEN ThrowingCallable actual = () -> getMethod(underTest.getClass(), INVOKE_METHOD_NAME, true, Method.class, Object.class, Object[].class) @@ -549,7 +548,6 @@ public void testGetDeclaredFieldTypeWorksProperly() { assertThat(actual).isNotNull(); } - /** * Tests that the method {@code getGenericFieldType} works properly. * @param testCaseDescription the test case description diff --git a/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java b/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java index 4c1e7b8ba..292a99f7c 100644 --- a/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java +++ b/bull-converter/src/main/java/com/expediagroup/beans/conversion/Converter.java @@ -32,7 +32,6 @@ public interface Converter { */ Optional> getConversionFunction(Class sourceClass, Class targetClass); - /** * Converts a given primitive value into the given primitive type. * @param valueToConvert the value to be converted From c6668a1552716376776a1c11f08a866a419bcf03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 05:50:52 +0100 Subject: [PATCH 1571/1786] Bump versions-maven-plugin from 2.8.1 to 2.9.0 (#282) Bumps [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) from 2.8.1 to 2.9.0. - [Release notes](https://github.com/mojohaus/versions-maven-plugin/releases) - [Changelog](https://github.com/mojohaus/versions-maven-plugin/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions-maven-plugin/compare/versions-maven-plugin-2.8.1...versions-maven-plugin-2.9.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dda8b48b0..52fe9e6a7 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.0.1 3.3.1 3.1.2 - 2.8.1 + 2.9.0 9.2.1 3.0.0-M4 1.6.8 From 83371c8823f3b2b9c044ebc188753b2b28349f41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 05:50:52 +0100 Subject: [PATCH 1572/1786] Bump versions-maven-plugin from 2.8.1 to 2.9.0 (#282) Bumps [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) from 2.8.1 to 2.9.0. - [Release notes](https://github.com/mojohaus/versions-maven-plugin/releases) - [Changelog](https://github.com/mojohaus/versions-maven-plugin/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions-maven-plugin/compare/versions-maven-plugin-2.8.1...versions-maven-plugin-2.9.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dda8b48b0..52fe9e6a7 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.0.1 3.3.1 3.1.2 - 2.8.1 + 2.9.0 9.2.1 3.0.0-M4 1.6.8 From a565df8e97ffa6212271c09c8d3ff7c2c92d4384 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jan 2022 06:19:24 +0100 Subject: [PATCH 1573/1786] Bump mockito-core from 4.2.0 to 4.3.0 (#283) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.2.0 to 4.3.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.2.0...v4.3.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 52fe9e6a7..8d1b14bd8 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.22 3.12.0 - 4.2.0 + 4.3.0 7.5 3.22.0 From 18d450573906ca0380b66d8bebc57fd100a91802 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jan 2022 06:19:24 +0100 Subject: [PATCH 1574/1786] Bump mockito-core from 4.2.0 to 4.3.0 (#283) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.2.0 to 4.3.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.2.0...v4.3.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 52fe9e6a7..8d1b14bd8 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.22 3.12.0 - 4.2.0 + 4.3.0 7.5 3.22.0 From ea433c2444b30914f88e056cbb275573b62e5026 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jan 2022 06:28:01 +0100 Subject: [PATCH 1575/1786] Bump slf4j-api from 1.7.33 to 1.7.35 (#284) Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.33 to 1.7.35. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.33...v_1.7.35) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8d1b14bd8..1c0b9ee48 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.1.Final 3.4.3.Final 2.2.1.Final - 1.7.33 + 1.7.35 3.0.0 0.8.7 From 835da698871993897b2096694af7da06f88b8759 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jan 2022 06:28:01 +0100 Subject: [PATCH 1576/1786] Bump slf4j-api from 1.7.33 to 1.7.35 (#284) Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.33 to 1.7.35. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.33...v_1.7.35) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8d1b14bd8..1c0b9ee48 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.1.Final 3.4.3.Final 2.2.1.Final - 1.7.33 + 1.7.35 3.0.0 0.8.7 From 3f01ff667c7e8d2fc20b86d341dcf5181879369d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 26 Jan 2022 06:29:25 +0100 Subject: [PATCH 1577/1786] Bump slf4j-api from 1.7.33 to 1.7.35 (#284) (#286) Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.33 to 1.7.35. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.33...v_1.7.35) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8d1b14bd8..1c0b9ee48 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.1.Final 3.4.3.Final 2.2.1.Final - 1.7.33 + 1.7.35 3.0.0 0.8.7 From ddb3efdccf85dea8a3dec00be7e6119b5b14a44f Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 26 Jan 2022 06:29:25 +0100 Subject: [PATCH 1578/1786] Bump slf4j-api from 1.7.33 to 1.7.35 (#284) (#286) Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.33 to 1.7.35. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.33...v_1.7.35) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8d1b14bd8..1c0b9ee48 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.1.Final 3.4.3.Final 2.2.1.Final - 1.7.33 + 1.7.35 3.0.0 0.8.7 From 7a728e8590e7644aad5087d875a6d74b3b749cb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jan 2022 06:55:40 +0100 Subject: [PATCH 1579/1786] Bump checkstyle from 9.2.1 to 9.3 (#287) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.2.1 to 9.3. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.2.1...checkstyle-9.3) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1c0b9ee48..b25f34dad 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.3.1 3.1.2 2.9.0 - 9.2.1 + 9.3 3.0.0-M4 1.6.8 3.1.2 From 48cf53bfcb71131b753e96ff9feeb2d5a1ad0559 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jan 2022 06:55:40 +0100 Subject: [PATCH 1580/1786] Bump checkstyle from 9.2.1 to 9.3 (#287) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.2.1 to 9.3. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.2.1...checkstyle-9.3) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1c0b9ee48..b25f34dad 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.3.1 3.1.2 2.9.0 - 9.2.1 + 9.3 3.0.0-M4 1.6.8 3.1.2 From a367f1aa38d6f443794ddd06f70cd60c90b361a0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 31 Jan 2022 16:11:58 +0100 Subject: [PATCH 1581/1786] Maven wrapper update and licence year update (#288) * Updates the licence copyright * Updated the mvn wrapper version to 3.8.4 * Typo error fix --- .mvn/jvm.config | 10 ++++ .mvn/wrapper/maven-wrapper.properties | 2 +- .../com/expediagroup/beans/BeanUtils.java | 2 +- .../com/expediagroup/beans/package-info.java | 2 +- .../beans/populator/ArrayPopulator.java | 2 +- .../beans/populator/CollectionPopulator.java | 2 +- .../beans/populator/ICollectionPopulator.java | 2 +- .../beans/populator/OptionalPopulator.java | 2 +- .../beans/populator/Populator.java | 2 +- .../beans/populator/PopulatorFactory.java | 2 +- .../beans/populator/package-info.java | 2 +- .../transformer/AbstractBeanTransformer.java | 2 +- .../beans/transformer/BeanTransformer.java | 2 +- .../beans/transformer/TransformerImpl.java | 2 +- .../beans/transformer/package-info.java | 2 +- .../src/main/resources/logback.xml | 2 +- .../com/expediagroup/beans/BeanUtilsTest.java | 2 +- .../com/expediagroup/beans/package-info.java | 2 +- .../beans/performance/PerformanceTest.java | 2 +- .../beans/performance/package-info.java | 2 +- .../beans/populator/ArrayPopulatorTest.java | 2 +- .../beans/populator/PopulatorFactoryTest.java | 2 +- .../beans/populator/package-info.java | 2 +- .../AbstractBeanTransformerTest.java | 2 +- .../transformer/BeanTransformerTest.java | 8 +-- .../BuilderObjectTransformationTest.java | 2 +- .../ImmutableObjectTransformationTest.java | 2 +- .../MixedObjectTransformationTest.java | 2 +- .../MutableObjectTransformationTest.java | 2 +- .../beans/transformer/package-info.java | 2 +- .../src/test/resources/logback-test.xml | 2 +- .../expediagroup/transformer/Transformer.java | 2 +- .../annotation/ConstructorArg.java | 2 +- .../transformer/annotation/package-info.java | 2 +- .../transformer/base/Defaults.java | 2 +- .../transformer/base/package-info.java | 2 +- .../transformer/cache/CacheManager.java | 2 +- .../cache/CacheManagerFactory.java | 2 +- .../transformer/cache/package-info.java | 2 +- .../transformer/constant/ClassType.java | 2 +- .../transformer/constant/Filters.java | 2 +- .../transformer/constant/MethodPrefix.java | 2 +- .../transformer/constant/Punctuation.java | 2 +- .../transformer/constant/package-info.java | 2 +- .../error/InstanceCreationException.java | 2 +- .../error/InvalidBeanException.java | 2 +- .../error/InvalidFunctionException.java | 2 +- .../error/MissingFieldException.java | 2 +- .../error/MissingMethodException.java | 2 +- .../transformer/error/package-info.java | 2 +- .../transformer/model/EmptyValue.java | 2 +- .../transformer/model/FieldTransformer.java | 2 +- .../transformer/model/MapElemType.java | 2 +- .../model/TransformerSettings.java | 2 +- .../transformer/model/package-info.java | 2 +- .../transformer/package-info.java | 2 +- .../transformer/utils/ClassUtils.java | 4 +- .../transformer/utils/ReflectionUtils.java | 4 +- .../transformer/utils/package-info.java | 2 +- .../transformer/validator/package-info.java | 2 +- .../com/expediagroup/beans/package-info.java | 2 +- .../beans/sample/AbstractClass.java | 2 +- .../expediagroup/beans/sample/FromFoo.java | 2 +- .../beans/sample/FromFooAdvFields.java | 2 +- .../expediagroup/beans/sample/FromFooMap.java | 2 +- .../beans/sample/FromFooNoField.java | 2 +- .../sample/FromFooOnlyPrimitiveTypes.java | 2 +- .../beans/sample/FromFooSimple.java | 2 +- .../sample/FromFooSimpleBooleanField.java | 2 +- .../beans/sample/FromFooSimpleNoGetters.java | 2 +- .../beans/sample/FromFooSubClass.java | 2 +- .../sample/FromFooWithPrimitiveFields.java | 2 +- .../expediagroup/beans/sample/FromSubFoo.java | 2 +- .../expediagroup/beans/sample/ISubClass.java | 2 +- .../sample/immutable/ImmutableFlatToFoo.java | 2 +- .../immutable/ImmutableToFooAdvFields.java | 2 +- .../ImmutableToFooDiffTypesFields.java | 2 +- .../sample/immutable/ImmutableToFooMap.java | 2 +- .../ImmutableToFooNoConstructors.java | 2 +- .../ImmutableToFooNotExistingFields.java | 2 +- .../immutable/ImmutableToFooSimple.java | 2 +- .../ImmutableToFooSimpleBoolean.java | 2 +- .../ImmutableToFooSimpleWrongTypes.java | 2 +- .../immutable/ImmutableToFooWithBuilder.java | 2 +- .../sample/immutable/ImmutableToSubFoo.java | 2 +- .../beans/sample/immutable/package-info.java | 2 +- .../sample/mixed/MixedToFooDiffFields.java | 2 +- .../sample/mixed/MixedToFooMissingField.java | 2 +- .../mixed/MixedToFooNotExistingFields.java | 2 +- .../MixedToFooSimpleNotExistingFields.java | 2 +- .../sample/mixed/MixedToFooStaticField.java | 2 +- .../sample/mixed/MixedToFooWithBuilder.java | 2 +- .../mixed/MutableToFooOnlyPrimitiveTypes.java | 2 +- .../beans/sample/mixed/package-info.java | 2 +- .../beans/sample/mutable/MutableToFoo.java | 2 +- .../sample/mutable/MutableToFooAdvFields.java | 2 +- .../sample/mutable/MutableToFooInvalid.java | 2 +- .../MutableToFooNotExistingFields.java | 2 +- .../sample/mutable/MutableToFooSimple.java | 2 +- .../mutable/MutableToFooSimpleNoSetters.java | 2 +- .../sample/mutable/MutableToFooSubClass.java | 2 +- .../mutable/MutableToFooWithBuilder.java | 2 +- ...leToFooWithBuilderMultipleConstructor.java | 2 +- .../mutable/MutableToFooWithWrongBuilder.java | 2 +- .../beans/sample/mutable/MutableToSubFoo.java | 2 +- .../beans/sample/mutable/package-info.java | 2 +- .../beans/sample/package-info.java | 2 +- .../transformer/AbstractTransformerTest.java | 2 +- .../transformer/base/DefaultsTest.java | 2 +- .../transformer/base/package-info.java | 2 +- .../cache/CacheManagerFactoryTest.java | 2 +- .../transformer/cache/CacheManagerTest.java | 2 +- .../transformer/cache/package-info.java | 2 +- .../transformer/package-info.java | 2 +- .../transformer/utils/ClassUtilsTest.java | 59 ++++++++++--------- .../utils/ReflectionUtilsTest.java | 14 ++--- .../transformer/utils/package-info.java | 2 +- .../transformer/validator/ValidatorTest.java | 2 +- .../transformer/validator/package-info.java | 2 +- .../src/test/resources/logback-test.xml | 2 +- .../beans/conversion/Converter.java | 2 +- .../beans/conversion/ConverterImpl.java | 2 +- .../analyzer/ConversionAnalyzer.java | 2 +- .../conversion/analyzer/package-info.java | 2 +- .../error/TypeConversionException.java | 2 +- .../beans/conversion/error/package-info.java | 2 +- .../beans/conversion/package-info.java | 2 +- .../processor/ConversionProcessor.java | 2 +- .../processor/ConversionProcessorFactory.java | 2 +- .../impl/BigDecimalConversionProcessor.java | 2 +- .../impl/BigIntegerConversionProcessor.java | 2 +- .../impl/BooleanConversionProcessor.java | 2 +- .../impl/ByteArrayConversionProcessor.java | 2 +- .../impl/ByteConversionProcessor.java | 2 +- .../impl/CharacterConversionProcessor.java | 2 +- .../impl/DoubleConversionProcessor.java | 2 +- .../impl/FloatConversionProcessor.java | 2 +- .../impl/IntegerConversionProcessor.java | 2 +- .../impl/LongConversionProcessor.java | 2 +- .../impl/ShortConversionProcessor.java | 2 +- .../impl/StringConversionProcessor.java | 2 +- .../processor/impl/package-info.java | 2 +- .../conversion/processor/package-info.java | 2 +- .../conversion/AbstractConversionTest.java | 2 +- .../beans/conversion/ConverterTest.java | 2 +- .../analyzer/ConversionAnalyzerTest.java | 2 +- .../conversion/analyzer/package-info.java | 2 +- .../beans/conversion/package-info.java | 2 +- .../ConversionProcessorFactoryTest.java | 4 +- .../impl/BigDecimalConversionTest.java | 2 +- .../impl/BigIntegerConversionTest.java | 2 +- .../processor/impl/BooleanConversionTest.java | 2 +- .../impl/ByteArrayConversionTest.java | 2 +- .../processor/impl/ByteConversionTest.java | 2 +- .../impl/CharacterConversionTest.java | 2 +- .../processor/impl/DoubleConversionTest.java | 2 +- .../processor/impl/FloatConversionTest.java | 2 +- .../processor/impl/IntegerConversionTest.java | 2 +- .../processor/impl/LongConversionTest.java | 2 +- .../processor/impl/ShortConversionTest.java | 2 +- .../processor/impl/StringConversionTest.java | 2 +- .../processor/impl/package-info.java | 2 +- .../conversion/processor/package-info.java | 2 +- .../java/com/expediagroup/map/MapUtils.java | 2 +- .../com/expediagroup/map/package-info.java | 2 +- .../transformer/AbstractMapTransformer.java | 2 +- .../map/transformer/MapTransformer.java | 2 +- .../map/transformer/MapTransformerImpl.java | 2 +- .../model/MapTransformerSettings.java | 2 +- .../map/transformer/model/package-info.java | 2 +- .../map/transformer/package-info.java | 2 +- .../src/main/resources/logback.xml | 2 +- .../com/expediagroup/map/MapUtilsTest.java | 2 +- .../com/expediagroup/map/package-info.java | 2 +- .../map/transformer/MapTransformerTest.java | 2 +- .../map/transformer/package-info.java | 2 +- 176 files changed, 226 insertions(+), 215 deletions(-) create mode 100644 .mvn/jvm.config diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 000000000..aaee55c31 --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1,10 @@ +--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-opens java.base/java.util=ALL-UNNAMED +--add-opens java.base/java.lang.reflect=ALL-UNNAMED +--add-opens java.base/java.text=ALL-UNNAMED +--add-opens java.desktop/java.awt.font=ALL-UNNAMED \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 672b84c60..4829bd002 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,4 +1,4 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip wrapper.url=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar # Path where the maven-wrapper.jar will be saved to. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java index 8a1ca0485..1cc762d47 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java index 2f247262c..14bb9e8e5 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java index ebc087bdd..a8d70c109 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java index 52c66ab6b..5168e7853 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java index 247b6cf2b..ae98a405a 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java index 3134dab32..9770be260 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java index d388ec054..478182813 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java index 323970b41..91d2070c6 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java index 1e14f7cef..8fb1b860e 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java index 5e413df94..663c81787 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java index 146d48ba4..e1a71f63f 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java index 2b1959630..91ec00711 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java index 5d8b45b2f..0dba08fbf 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2021 Expedia, Inc. + * Copyright (C) 2019-2022 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/resources/logback.xml b/bull-bean-transformer/src/main/resources/logback.xml index 7f3fe5d81..4c13cc321 100644 --- a/bull-bean-transformer/src/main/resources/logback.xml +++ b/bull-bean-transformer/src/main/resources/logback.xml @@ -1,5 +1,5 @@ 0.8.7 From 5e4767d9bff87b69094e6a687afe576e3e88727f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Feb 2022 09:02:56 +0100 Subject: [PATCH 1584/1786] Bump slf4j-api from 1.7.35 to 1.7.36 (#289) Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.35 to 1.7.36. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.35...v_1.7.36) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b25f34dad..2f1d54206 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.1.Final 3.4.3.Final 2.2.1.Final - 1.7.35 + 1.7.36 3.0.0 0.8.7 From b22a92a686bac4cbeca2b785bcce2dc944e81995 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Feb 2022 09:29:59 +0100 Subject: [PATCH 1585/1786] Bump hibernate-validator from 6.2.1.Final to 6.2.2.Final (#290) Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.2.1.Final to 6.2.2.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.2.2.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.2.1.Final...6.2.2.Final) --- updated-dependencies: - dependency-name: org.hibernate.validator:hibernate-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2f1d54206..12bf50efe 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 7.5 3.22.0 - 6.2.1.Final + 6.2.2.Final 3.4.3.Final 2.2.1.Final 1.7.36 From b2ed538dc9c7b091cc98462157ea0921a940828c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Feb 2022 09:29:59 +0100 Subject: [PATCH 1586/1786] Bump hibernate-validator from 6.2.1.Final to 6.2.2.Final (#290) Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.2.1.Final to 6.2.2.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.2.2.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.2.1.Final...6.2.2.Final) --- updated-dependencies: - dependency-name: org.hibernate.validator:hibernate-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2f1d54206..12bf50efe 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 7.5 3.22.0 - 6.2.1.Final + 6.2.2.Final 3.4.3.Final 2.2.1.Final 1.7.36 From ba0f1e97c2235d4d4b874e3f17885d3ca8d36312 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Feb 2022 06:32:28 +0100 Subject: [PATCH 1587/1786] Bump maven-javadoc-plugin from 3.3.1 to 3.3.2 (#293) Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.1...maven-javadoc-plugin-3.3.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 12bf50efe..03a801328 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ [3.8.1,) 3.0.1 - 3.3.1 + 3.3.2 3.1.2 2.9.0 9.3 From 88e21cfe4bf82d8a82a8a3485566ff3664c01fa9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Feb 2022 06:32:28 +0100 Subject: [PATCH 1588/1786] Bump maven-javadoc-plugin from 3.3.1 to 3.3.2 (#293) Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.1...maven-javadoc-plugin-3.3.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 12bf50efe..03a801328 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ [3.8.1,) 3.0.1 - 3.3.1 + 3.3.2 3.1.2 2.9.0 9.3 From 86ab4d4e09a2d1e52c8904008d047e21e7096885 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Feb 2022 22:45:18 +0100 Subject: [PATCH 1589/1786] Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.10 (#292) * Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.10 Bumps nexus-staging-maven-plugin from 1.6.8 to 1.6.10. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump maven-javadoc-plugin from 3.3.1 to 3.3.2 (#291) Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.1...maven-javadoc-plugin-3.3.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 03a801328..b087810f5 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.9.0 9.3 3.0.0-M4 - 1.6.8 + 1.6.10 3.1.2 false From e95f0ec4ff2f3f6d04dc903ce805937ee84d880c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Feb 2022 22:45:18 +0100 Subject: [PATCH 1590/1786] Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.10 (#292) * Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.10 Bumps nexus-staging-maven-plugin from 1.6.8 to 1.6.10. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump maven-javadoc-plugin from 3.3.1 to 3.3.2 (#291) Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.1...maven-javadoc-plugin-3.3.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 03a801328..b087810f5 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.9.0 9.3 3.0.0-M4 - 1.6.8 + 1.6.10 3.1.2 false From c57ca05673a3a7b23e7a06da175d7357e00a9c89 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 15 Feb 2022 22:46:00 +0100 Subject: [PATCH 1591/1786] Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.10 (#292) (#294) * Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.10 Bumps nexus-staging-maven-plugin from 1.6.8 to 1.6.10. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump maven-javadoc-plugin from 3.3.1 to 3.3.2 (#291) Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.1...maven-javadoc-plugin-3.3.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 03a801328..b087810f5 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.9.0 9.3 3.0.0-M4 - 1.6.8 + 1.6.10 3.1.2 false From 2da67a0c7c91134440a1172a039cb5ca74eecd6d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 15 Feb 2022 22:46:00 +0100 Subject: [PATCH 1592/1786] Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.10 (#292) (#294) * Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.10 Bumps nexus-staging-maven-plugin from 1.6.8 to 1.6.10. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump maven-javadoc-plugin from 3.3.1 to 3.3.2 (#291) Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.1...maven-javadoc-plugin-3.3.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 03a801328..b087810f5 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.9.0 9.3 3.0.0-M4 - 1.6.8 + 1.6.10 3.1.2 false From fc6dcf290a18a473f8ed2fd90747fff42527b12a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Feb 2022 06:23:41 +0100 Subject: [PATCH 1593/1786] Bump nexus-staging-maven-plugin from 1.6.10 to 1.6.11 (#295) Bumps nexus-staging-maven-plugin from 1.6.10 to 1.6.11. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b087810f5..f6f0eb085 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.9.0 9.3 3.0.0-M4 - 1.6.10 + 1.6.11 3.1.2 false From 783eb92fc49e850edf1c920127f9605b6b5f8404 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Feb 2022 06:23:41 +0100 Subject: [PATCH 1594/1786] Bump nexus-staging-maven-plugin from 1.6.10 to 1.6.11 (#295) Bumps nexus-staging-maven-plugin from 1.6.10 to 1.6.11. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b087810f5..f6f0eb085 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.9.0 9.3 3.0.0-M4 - 1.6.10 + 1.6.11 3.1.2 false From aa30872d336e032a30e5202e95ff795ead467942 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Feb 2022 08:01:08 +0100 Subject: [PATCH 1595/1786] Bump maven-site-plugin from 3.10.0 to 3.11.0 (#297) Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.10.0 to 3.11.0. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.10.0...maven-site-plugin-3.11.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f6f0eb085..f538f3c6d 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.5.1 0.12 github - 3.10.0 + 3.11.0 [3.8.1,) 3.0.1 From 4a2d29d4b6a7f652a1b217dc596f02b4ccf8707f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Feb 2022 08:01:08 +0100 Subject: [PATCH 1596/1786] Bump maven-site-plugin from 3.10.0 to 3.11.0 (#297) Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.10.0 to 3.11.0. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.10.0...maven-site-plugin-3.11.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f6f0eb085..f538f3c6d 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.5.1 0.12 github - 3.10.0 + 3.11.0 [3.8.1,) 3.0.1 From 2d37c227ed1d2dbd0eb41475e359d559ed31a4c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Feb 2022 08:47:23 +0100 Subject: [PATCH 1597/1786] Bump nexus-staging-maven-plugin from 1.6.11 to 1.6.12 (#298) Bumps nexus-staging-maven-plugin from 1.6.11 to 1.6.12. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f538f3c6d..785bace3c 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.9.0 9.3 3.0.0-M4 - 1.6.11 + 1.6.12 3.1.2 false From f6175f4663ed434285947cd55c479f34220cd318 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Feb 2022 08:47:23 +0100 Subject: [PATCH 1598/1786] Bump nexus-staging-maven-plugin from 1.6.11 to 1.6.12 (#298) Bumps nexus-staging-maven-plugin from 1.6.11 to 1.6.12. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f538f3c6d..785bace3c 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.9.0 9.3 3.0.0-M4 - 1.6.11 + 1.6.12 3.1.2 false From 1cec453d764454c3a9085c1b5428bb07f2da2059 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:02:57 +0100 Subject: [PATCH 1599/1786] Bump checkstyle from 9.3 to 10.0 (#299) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.3 to 10.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.3...checkstyle-10.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 785bace3c..715308db6 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.3.2 3.1.2 2.9.0 - 9.3 + 10.0 3.0.0-M4 1.6.12 3.1.2 From a088ef037ff0df5d47db22bbf03919fa41598885 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Mar 2022 09:02:57 +0100 Subject: [PATCH 1600/1786] Bump checkstyle from 9.3 to 10.0 (#299) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 9.3 to 10.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-9.3...checkstyle-10.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 785bace3c..715308db6 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.3.2 3.1.2 2.9.0 - 9.3 + 10.0 3.0.0-M4 1.6.12 3.1.2 From 290300f565aa8c29fa4b606a19ac2edb4bcccaf6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Mar 2022 09:03:28 +0100 Subject: [PATCH 1601/1786] Bump hibernate-validator from 6.2.2.Final to 6.2.3.Final (#300) Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.2.2.Final to 6.2.3.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.2.3.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.2.2.Final...6.2.3.Final) --- updated-dependencies: - dependency-name: org.hibernate.validator:hibernate-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 715308db6..7250c5e41 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 7.5 3.22.0 - 6.2.2.Final + 6.2.3.Final 3.4.3.Final 2.2.1.Final 1.7.36 From 415b6749821d6be7a283d68bc501f14e29d932de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Mar 2022 09:03:28 +0100 Subject: [PATCH 1602/1786] Bump hibernate-validator from 6.2.2.Final to 6.2.3.Final (#300) Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.2.2.Final to 6.2.3.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.2.3.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.2.2.Final...6.2.3.Final) --- updated-dependencies: - dependency-name: org.hibernate.validator:hibernate-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 715308db6..7250c5e41 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 7.5 3.22.0 - 6.2.2.Final + 6.2.3.Final 3.4.3.Final 2.2.1.Final 1.7.36 From 6f16c12204d26f455f89eca96613dcf650ee2e63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Mar 2022 07:56:18 +0100 Subject: [PATCH 1603/1786] Bump versions-maven-plugin from 2.9.0 to 2.10.0 (#302) Bumps [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) from 2.9.0 to 2.10.0. - [Release notes](https://github.com/mojohaus/versions-maven-plugin/releases) - [Changelog](https://github.com/mojohaus/versions-maven-plugin/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions-maven-plugin/compare/versions-maven-plugin-2.9.0...versions-maven-plugin-2.10.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7250c5e41..36cc4d6e1 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.0.1 3.3.2 3.1.2 - 2.9.0 + 2.10.0 10.0 3.0.0-M4 1.6.12 From 08415c60cfea47304b67930f70f1be8905ee2901 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Mar 2022 07:56:18 +0100 Subject: [PATCH 1604/1786] Bump versions-maven-plugin from 2.9.0 to 2.10.0 (#302) Bumps [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) from 2.9.0 to 2.10.0. - [Release notes](https://github.com/mojohaus/versions-maven-plugin/releases) - [Changelog](https://github.com/mojohaus/versions-maven-plugin/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions-maven-plugin/compare/versions-maven-plugin-2.9.0...versions-maven-plugin-2.10.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7250c5e41..36cc4d6e1 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.0.1 3.3.2 3.1.2 - 2.9.0 + 2.10.0 10.0 3.0.0-M4 1.6.12 From e4fb224880f15dbeaeb9e82335d40673f91cd1d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Mar 2022 07:56:35 +0100 Subject: [PATCH 1605/1786] Bump mockito-core from 4.3.0 to 4.4.0 (#301) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.3.0 to 4.4.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.3.0...v4.4.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 36cc4d6e1..087cf406d 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.22 3.12.0 - 4.3.0 + 4.4.0 7.5 3.22.0 From d9c4cadc5b8833f76cf49e4c118a2c8214d22fcf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Mar 2022 07:56:35 +0100 Subject: [PATCH 1606/1786] Bump mockito-core from 4.3.0 to 4.4.0 (#301) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.3.0 to 4.4.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.3.0...v4.4.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 36cc4d6e1..087cf406d 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.22 3.12.0 - 4.3.0 + 4.4.0 7.5 3.22.0 From f465d93ae8ddd168e10c53f49dce78920dcaadb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 09:45:16 +0200 Subject: [PATCH 1607/1786] Bump checkstyle from 10.0 to 10.1 (#303) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.0 to 10.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.0...checkstyle-10.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 087cf406d..ac257d262 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.3.2 3.1.2 2.10.0 - 10.0 + 10.1 3.0.0-M4 1.6.12 3.1.2 From 61820e5ee9ae7de5b64766f92ebb01b22b834a6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 09:45:16 +0200 Subject: [PATCH 1608/1786] Bump checkstyle from 10.0 to 10.1 (#303) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.0 to 10.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.0...checkstyle-10.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 087cf406d..ac257d262 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.3.2 3.1.2 2.10.0 - 10.0 + 10.1 3.0.0-M4 1.6.12 3.1.2 From 6f85c3c8a664e402e274280daad26d2b19ccf870 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Apr 2022 17:50:16 +0200 Subject: [PATCH 1609/1786] Bump jacoco-maven-plugin from 0.8.7 to 0.8.8 (#304) Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.7 to 0.8.8. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.7...v0.8.8) --- updated-dependencies: - dependency-name: org.jacoco:jacoco-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ac257d262..4aee53417 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 1.7.36 3.0.0 - 0.8.7 + 0.8.8 1.0 0.98 1.0 From 669291d10ccacb7448d6fc0e02172f449b614065 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Apr 2022 17:50:16 +0200 Subject: [PATCH 1610/1786] Bump jacoco-maven-plugin from 0.8.7 to 0.8.8 (#304) Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.7 to 0.8.8. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.7...v0.8.8) --- updated-dependencies: - dependency-name: org.jacoco:jacoco-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ac257d262..4aee53417 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 1.7.36 3.0.0 - 0.8.7 + 0.8.8 1.0 0.98 1.0 From c2c8b14980147b83fdf633542a8c6887e0c37e01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Apr 2022 06:36:46 +0200 Subject: [PATCH 1611/1786] Bump lombok from 1.18.22 to 1.18.24 (#305) Bumps [lombok](https://github.com/projectlombok/lombok) from 1.18.22 to 1.18.24. - [Release notes](https://github.com/projectlombok/lombok/releases) - [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/projectlombok/lombok/compare/v1.18.22...v1.18.24) --- updated-dependencies: - dependency-name: org.projectlombok:lombok dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4aee53417..a7c0f801b 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 15 ${jdk.version} ${jdk.version} - 1.18.22 + 1.18.24 3.12.0 4.4.0 From 013a94adb30cf2d90de80dd21d809718b5390590 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Apr 2022 06:36:46 +0200 Subject: [PATCH 1612/1786] Bump lombok from 1.18.22 to 1.18.24 (#305) Bumps [lombok](https://github.com/projectlombok/lombok) from 1.18.22 to 1.18.24. - [Release notes](https://github.com/projectlombok/lombok/releases) - [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/projectlombok/lombok/compare/v1.18.22...v1.18.24) --- updated-dependencies: - dependency-name: org.projectlombok:lombok dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4aee53417..a7c0f801b 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 15 ${jdk.version} ${jdk.version} - 1.18.22 + 1.18.24 3.12.0 4.4.0 From 9b946d2e3ff7b3739ee86870059038cff8fd73fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Apr 2022 08:58:26 +0200 Subject: [PATCH 1613/1786] Bump mockito-core from 4.4.0 to 4.5.0 (#306) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.4.0 to 4.5.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.4.0...v4.5.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a7c0f801b..a00c3cdde 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.4.0 + 4.5.0 7.5 3.22.0 From 7529351eb85a0c9f47f91b042ff41961df2823bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Apr 2022 08:58:26 +0200 Subject: [PATCH 1614/1786] Bump mockito-core from 4.4.0 to 4.5.0 (#306) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.4.0 to 4.5.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.4.0...v4.5.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a7c0f801b..a00c3cdde 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.4.0 + 4.5.0 7.5 3.22.0 From a73424f2f5eeaeb484a93cea819b7cc5cba96328 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Apr 2022 09:09:52 +0200 Subject: [PATCH 1615/1786] Bump maven-javadoc-plugin from 3.3.2 to 3.4.0 (#308) Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.2 to 3.4.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.2...maven-javadoc-plugin-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a00c3cdde..f7c7c4f70 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ [3.8.1,) 3.0.1 - 3.3.2 + 3.4.0 3.1.2 2.10.0 10.1 From ac0122f8444937a5b9c73363b8719d0764217b47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Apr 2022 09:09:52 +0200 Subject: [PATCH 1616/1786] Bump maven-javadoc-plugin from 3.3.2 to 3.4.0 (#308) Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.2 to 3.4.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.2...maven-javadoc-plugin-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a00c3cdde..f7c7c4f70 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ [3.8.1,) 3.0.1 - 3.3.2 + 3.4.0 3.1.2 2.10.0 10.1 From e2eb48e65607dcbe323979715c960466153579a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Apr 2022 09:10:59 +0200 Subject: [PATCH 1617/1786] Bump maven-site-plugin from 3.11.0 to 3.12.0 (#307) Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.11.0 to 3.12.0. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.11.0...maven-site-plugin-3.12.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f7c7c4f70..3ceeb5b70 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.5.1 0.12 github - 3.11.0 + 3.12.0 [3.8.1,) 3.0.1 From 9c3769789bde79bcea2997358c686ee9232dcd17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Apr 2022 09:10:59 +0200 Subject: [PATCH 1618/1786] Bump maven-site-plugin from 3.11.0 to 3.12.0 (#307) Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.11.0 to 3.12.0. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.11.0...maven-site-plugin-3.12.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f7c7c4f70..3ceeb5b70 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.5.1 0.12 github - 3.11.0 + 3.12.0 [3.8.1,) 3.0.1 From d7943e1240617effe595b277c6ede68fa3397476 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 07:19:44 +0200 Subject: [PATCH 1619/1786] Bump checkstyle from 10.1 to 10.2 (#311) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.1 to 10.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.1...checkstyle-10.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3ceeb5b70..1feb04ddd 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.4.0 3.1.2 2.10.0 - 10.1 + 10.2 3.0.0-M4 1.6.12 3.1.2 From c20b69a9e66dea69d3404607d006ac62b6a4b4cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 07:19:44 +0200 Subject: [PATCH 1620/1786] Bump checkstyle from 10.1 to 10.2 (#311) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.1 to 10.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.1...checkstyle-10.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3ceeb5b70..1feb04ddd 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.4.0 3.1.2 2.10.0 - 10.1 + 10.2 3.0.0-M4 1.6.12 3.1.2 From 359ce20b40fbe477cf527a8090c981726dcc8ce1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 07:20:12 +0200 Subject: [PATCH 1621/1786] Bump mockito-core from 4.5.0 to 4.5.1 (#309) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.5.0...v4.5.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1feb04ddd..b72182194 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.5.0 + 4.5.1 7.5 3.22.0 From 33da1b1420c2206792331c1980e85c03775db50f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 07:20:12 +0200 Subject: [PATCH 1622/1786] Bump mockito-core from 4.5.0 to 4.5.1 (#309) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.5.0...v4.5.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1feb04ddd..b72182194 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.5.0 + 4.5.1 7.5 3.22.0 From e31947e5110b12b91d42e750562efd0986afdb95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 07:21:14 +0200 Subject: [PATCH 1623/1786] Bump nexus-staging-maven-plugin from 1.6.12 to 1.6.13 (#310) Bumps nexus-staging-maven-plugin from 1.6.12 to 1.6.13. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b72182194..7fa526321 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.10.0 10.2 3.0.0-M4 - 1.6.12 + 1.6.13 3.1.2 false From 174515c21a04bf16bb118debcb2c80164ee00085 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 07:21:14 +0200 Subject: [PATCH 1624/1786] Bump nexus-staging-maven-plugin from 1.6.12 to 1.6.13 (#310) Bumps nexus-staging-maven-plugin from 1.6.12 to 1.6.13. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b72182194..7fa526321 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ 2.10.0 10.2 3.0.0-M4 - 1.6.12 + 1.6.13 3.1.2 false From 8644dd4a4e6c5e1c26c13319893c5d6f8d9211cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Apr 2022 07:03:33 +0200 Subject: [PATCH 1625/1786] Bump jboss-logging from 3.4.3.Final to 3.5.0.Final (#312) Bumps [jboss-logging](https://github.com/jboss-logging/jboss-logging) from 3.4.3.Final to 3.5.0.Final. - [Release notes](https://github.com/jboss-logging/jboss-logging/releases) - [Commits](https://github.com/jboss-logging/jboss-logging/compare/3.4.3.Final...3.5.0.Final) --- updated-dependencies: - dependency-name: org.jboss.logging:jboss-logging dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7fa526321..895790bc7 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 3.22.0 6.2.3.Final - 3.4.3.Final + 3.5.0.Final 2.2.1.Final 1.7.36 3.0.0 From 6802d57f5db152c1ecd415d9fe1560e825e7556a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Apr 2022 07:03:33 +0200 Subject: [PATCH 1626/1786] Bump jboss-logging from 3.4.3.Final to 3.5.0.Final (#312) Bumps [jboss-logging](https://github.com/jboss-logging/jboss-logging) from 3.4.3.Final to 3.5.0.Final. - [Release notes](https://github.com/jboss-logging/jboss-logging/releases) - [Commits](https://github.com/jboss-logging/jboss-logging/compare/3.4.3.Final...3.5.0.Final) --- updated-dependencies: - dependency-name: org.jboss.logging:jboss-logging dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7fa526321..895790bc7 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 3.22.0 6.2.3.Final - 3.4.3.Final + 3.5.0.Final 2.2.1.Final 1.7.36 3.0.0 From 01fa5db414e655df155696c413a1a3fe14af4093 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 06:24:54 +0200 Subject: [PATCH 1627/1786] Bump testng from 7.5 to 7.6.0 (#313) Bumps [testng](https://github.com/cbeust/testng) from 7.5 to 7.6.0. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/compare/7.5...7.6.0) --- updated-dependencies: - dependency-name: org.testng:testng dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 895790bc7..1e3d1328a 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.12.0 4.5.1 - 7.5 + 7.6.0 3.22.0 6.2.3.Final From 1aa494b9300dd6fda2f65761ef332d8504363203 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 06:24:54 +0200 Subject: [PATCH 1628/1786] Bump testng from 7.5 to 7.6.0 (#313) Bumps [testng](https://github.com/cbeust/testng) from 7.5 to 7.6.0. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/compare/7.5...7.6.0) --- updated-dependencies: - dependency-name: org.testng:testng dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 895790bc7..1e3d1328a 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.12.0 4.5.1 - 7.5 + 7.6.0 3.22.0 6.2.3.Final From 5dad4e178b842c619651e5633228228b7c7a105b Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 19 May 2022 08:20:55 +0200 Subject: [PATCH 1629/1786] GitHub action lib auto update (#314) Configures dependabot to update also the lib into github actions --- .github/dependabot.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9248c1cf1..57710eef3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,11 +1,23 @@ -# dependabot configuration available at: https://docs.github.com/en/code-security/supply-chain-security/configuration-options-for-dependency-updates +# dependabot configuration available at: https://docs.github.com/en/code-security/dependabot version: 2 updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + target-branch: develop + reviewers: + - fborriello + labels: + - configuration + - update + - github-actions-lib + # Maintain dependencies for maven - package-ecosystem: maven directory: "/" schedule: interval: daily - time: "02:00" open-pull-requests-limit: 10 target-branch: develop reviewers: @@ -13,4 +25,4 @@ updates: labels: - configuration - update - rebase-strategy: "auto" \ No newline at end of file + - dependencies \ No newline at end of file From 0913128ee4205330cfe3b236471340a93bf7e08e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 19 May 2022 08:20:55 +0200 Subject: [PATCH 1630/1786] GitHub action lib auto update (#314) Configures dependabot to update also the lib into github actions --- .github/dependabot.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9248c1cf1..57710eef3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,11 +1,23 @@ -# dependabot configuration available at: https://docs.github.com/en/code-security/supply-chain-security/configuration-options-for-dependency-updates +# dependabot configuration available at: https://docs.github.com/en/code-security/dependabot version: 2 updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + target-branch: develop + reviewers: + - fborriello + labels: + - configuration + - update + - github-actions-lib + # Maintain dependencies for maven - package-ecosystem: maven directory: "/" schedule: interval: daily - time: "02:00" open-pull-requests-limit: 10 target-branch: develop reviewers: @@ -13,4 +25,4 @@ updates: labels: - configuration - update - rebase-strategy: "auto" \ No newline at end of file + - dependencies \ No newline at end of file From 049f3c9143e2f93564e30f92f5102e77bf4ffaa6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 08:25:15 +0200 Subject: [PATCH 1631/1786] Bump actions/checkout from 2 to 3 (#316) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index db5d7cefd..08974cfde 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -11,7 +11,7 @@ jobs: name: "Build" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -30,7 +30,7 @@ jobs: name: "Test and quality check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -80,7 +80,7 @@ jobs: java-version: '15' distribution: 'adopt' - name: "Checkout repository" - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" uses: github/codeql-action/init@v1 diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 5f5946396..2f11ef19c 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -11,7 +11,7 @@ jobs: name: "Build" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -30,7 +30,7 @@ jobs: name: "Test and quality check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -80,7 +80,7 @@ jobs: java-version: '11' distribution: 'adopt' - name: "Checkout repository" - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" uses: github/codeql-action/init@v1 diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index a434fb21d..b10b503b3 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -10,7 +10,7 @@ jobs: name: "BULL Release" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 96d24ed06..a88d7b963 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -10,7 +10,7 @@ jobs: name: "BULL Release" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: From d0e22f0ddceb8f26bf8b3ec0c9661dedcbfcc2d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 08:25:15 +0200 Subject: [PATCH 1632/1786] Bump actions/checkout from 2 to 3 (#316) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index db5d7cefd..08974cfde 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -11,7 +11,7 @@ jobs: name: "Build" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -30,7 +30,7 @@ jobs: name: "Test and quality check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -80,7 +80,7 @@ jobs: java-version: '15' distribution: 'adopt' - name: "Checkout repository" - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" uses: github/codeql-action/init@v1 diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 5f5946396..2f11ef19c 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -11,7 +11,7 @@ jobs: name: "Build" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -30,7 +30,7 @@ jobs: name: "Test and quality check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: @@ -80,7 +80,7 @@ jobs: java-version: '11' distribution: 'adopt' - name: "Checkout repository" - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" uses: github/codeql-action/init@v1 diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index a434fb21d..b10b503b3 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -10,7 +10,7 @@ jobs: name: "BULL Release" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 96d24ed06..a88d7b963 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -10,7 +10,7 @@ jobs: name: "BULL Release" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Cache Maven repository" uses: actions/cache@v2.1.6 with: From b9bf836033185379d3950f1c942e78f1ecdae134 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 08:30:01 +0200 Subject: [PATCH 1633/1786] Bump actions/cache from 2.1.6 to 3.0.2 (#317) Bumps [actions/cache](https://github.com/actions/cache) from 2.1.6 to 3.0.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v2.1.6...v3.0.2) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 08974cfde..1dd554dbb 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 2f11ef19c..07199598c 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index b10b503b3..7d8692657 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index a88d7b963..bf4645a29 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 4c2de5f95f73fe6f43c77f43beae77e898edd51e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 08:30:01 +0200 Subject: [PATCH 1634/1786] Bump actions/cache from 2.1.6 to 3.0.2 (#317) Bumps [actions/cache](https://github.com/actions/cache) from 2.1.6 to 3.0.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v2.1.6...v3.0.2) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 08974cfde..1dd554dbb 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 2f11ef19c..07199598c 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index b10b503b3..7d8692657 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index a88d7b963..bf4645a29 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v2.1.6 + uses: actions/cache@v3.0.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 723ac9dc3723172cf574bb28c92682cbc934abb8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 08:36:06 +0200 Subject: [PATCH 1635/1786] Bump actions/setup-java from 2 to 3 (#318) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 2 to 3. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 1dd554dbb..b0d164f05 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -19,7 +19,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '15' distribution: 'adopt' @@ -42,7 +42,7 @@ jobs: run: | echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '15' distribution: 'adopt' @@ -75,7 +75,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '15' distribution: 'adopt' diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 07199598c..4dfe226f6 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -19,7 +19,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK 11 set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' @@ -42,7 +42,7 @@ jobs: run: | echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "JDK 11 set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' @@ -75,7 +75,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK 11 set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 7d8692657..b459ef3e4 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -29,7 +29,7 @@ jobs: run: | mvn versions:set -D newVersion=${TAG_NAME} - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index bf4645a29..eda289301 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -29,7 +29,7 @@ jobs: run: | mvn versions:set -D newVersion=${TAG_NAME} - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '15' distribution: 'adopt' From a5a0fcef1071784fa83d573ec621816f89546ef3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 08:36:06 +0200 Subject: [PATCH 1636/1786] Bump actions/setup-java from 2 to 3 (#318) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 2 to 3. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 1dd554dbb..b0d164f05 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -19,7 +19,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '15' distribution: 'adopt' @@ -42,7 +42,7 @@ jobs: run: | echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '15' distribution: 'adopt' @@ -75,7 +75,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '15' distribution: 'adopt' diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 07199598c..4dfe226f6 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -19,7 +19,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK 11 set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' @@ -42,7 +42,7 @@ jobs: run: | echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "JDK 11 set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' @@ -75,7 +75,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK 11 set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 7d8692657..b459ef3e4 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -29,7 +29,7 @@ jobs: run: | mvn versions:set -D newVersion=${TAG_NAME} - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '11' distribution: 'adopt' diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index bf4645a29..eda289301 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -29,7 +29,7 @@ jobs: run: | mvn versions:set -D newVersion=${TAG_NAME} - name: "JDK set-up" - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '15' distribution: 'adopt' From 770ea99e2fe60cce4cc03a516b269632a12b974f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 08:39:48 +0200 Subject: [PATCH 1637/1786] Bump github/codeql-action from 1 to 2 (#315) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v1...v2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 4 ++-- .github/workflows/github-default-jdk11-actions.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index b0d164f05..617946a55 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -83,10 +83,10 @@ jobs: uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: 'java' - run: | mvn clean install -B -DskipTests -P fast - name: "Perform Analysis" - uses: github/codeql-action/analyze@v1 \ No newline at end of file + uses: github/codeql-action/analyze@v2 \ No newline at end of file diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 4dfe226f6..a2cb11a09 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -83,10 +83,10 @@ jobs: uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: 'java' - run: | mvn clean install -B -DskipTests -P fast - name: "Perform Analysis" - uses: github/codeql-action/analyze@v1 \ No newline at end of file + uses: github/codeql-action/analyze@v2 \ No newline at end of file From 4e2db97bbff29d37330b230b59c4604b98a07399 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 08:39:48 +0200 Subject: [PATCH 1638/1786] Bump github/codeql-action from 1 to 2 (#315) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v1...v2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 4 ++-- .github/workflows/github-default-jdk11-actions.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index b0d164f05..617946a55 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -83,10 +83,10 @@ jobs: uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: 'java' - run: | mvn clean install -B -DskipTests -P fast - name: "Perform Analysis" - uses: github/codeql-action/analyze@v1 \ No newline at end of file + uses: github/codeql-action/analyze@v2 \ No newline at end of file diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 4dfe226f6..a2cb11a09 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -83,10 +83,10 @@ jobs: uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: 'java' - run: | mvn clean install -B -DskipTests -P fast - name: "Perform Analysis" - uses: github/codeql-action/analyze@v1 \ No newline at end of file + uses: github/codeql-action/analyze@v2 \ No newline at end of file From 3e667302201c28808a551f0b7d0ca3dfec6d219d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 May 2022 22:20:29 +0200 Subject: [PATCH 1639/1786] Bump versions-maven-plugin from 2.10.0 to 2.11.0 (#319) Bumps [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) from 2.10.0 to 2.11.0. - [Release notes](https://github.com/mojohaus/versions-maven-plugin/releases) - [Changelog](https://github.com/mojohaus/versions-maven-plugin/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions-maven-plugin/compare/versions-maven-plugin-2.10.0...versions-maven-plugin-2.11.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1e3d1328a..b78c85b46 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.0.1 3.4.0 3.1.2 - 2.10.0 + 2.11.0 10.2 3.0.0-M4 1.6.13 From bd852681e3667cd7e0d01c312e244d1debf4ed29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 May 2022 22:20:29 +0200 Subject: [PATCH 1640/1786] Bump versions-maven-plugin from 2.10.0 to 2.11.0 (#319) Bumps [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) from 2.10.0 to 2.11.0. - [Release notes](https://github.com/mojohaus/versions-maven-plugin/releases) - [Changelog](https://github.com/mojohaus/versions-maven-plugin/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions-maven-plugin/compare/versions-maven-plugin-2.10.0...versions-maven-plugin-2.11.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1e3d1328a..b78c85b46 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.0.1 3.4.0 3.1.2 - 2.10.0 + 2.11.0 10.2 3.0.0-M4 1.6.13 From 39a012d5598ffecc8196fed60149d0cc89e20aff Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 23 May 2022 17:49:56 +0200 Subject: [PATCH 1641/1786] Trigger notification From 87d05f66ec8140e03d9140c4254ae38fa33e553a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 May 2022 08:36:55 +0200 Subject: [PATCH 1642/1786] Bump mockito-core from 4.5.1 to 4.6.0 (#321) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.5.1 to 4.6.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.5.1...v4.6.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b78c85b46..5dbe01e32 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.5.1 + 4.6.0 7.6.0 3.22.0 From 18c5e0810941d52c7c9fe8eab463ebcf7dc012a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 May 2022 08:43:58 +0200 Subject: [PATCH 1643/1786] Bump checkstyle from 10.2 to 10.3 (#320) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.2 to 10.3. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.2...checkstyle-10.3) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5dbe01e32..1b3c0c31f 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.4.0 3.1.2 2.11.0 - 10.2 + 10.3 3.0.0-M4 1.6.13 3.1.2 From 38b25e41df1a9fb4263c1678629fccc44a6ff17c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Jun 2022 06:17:22 +0200 Subject: [PATCH 1644/1786] Bump actions/cache from 3.0.2 to 3.0.3 (#323) Bumps [actions/cache](https://github.com/actions/cache) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.2...v3.0.3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 617946a55..097346abc 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.2 + uses: actions/cache@v3.0.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.2 + uses: actions/cache@v3.0.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.2 + uses: actions/cache@v3.0.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index a2cb11a09..3e5619261 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.2 + uses: actions/cache@v3.0.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.2 + uses: actions/cache@v3.0.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.2 + uses: actions/cache@v3.0.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index b459ef3e4..bea377c16 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.2 + uses: actions/cache@v3.0.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index eda289301..ac027bd6b 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.2 + uses: actions/cache@v3.0.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From c0ac7839449f0f8a485d1057b1c713e5906c82a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Jun 2022 09:39:57 +0200 Subject: [PATCH 1645/1786] Bump assertj-core from 3.22.0 to 3.23.1 (#322) * Bump assertj-core from 3.22.0 to 3.23.1 Bumps [assertj-core](https://github.com/assertj/assertj-core) from 3.22.0 to 3.23.1. - [Release notes](https://github.com/assertj/assertj-core/releases) - [Commits](https://github.com/assertj/assertj-core/compare/assertj-core-3.22.0...assertj-core-3.23.1) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * fixes the failing test Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .../ImmutableObjectTransformationTest.java | 40 +++++++++++++++++-- pom.xml | 2 +- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java index e744fcb8e..4bc53b5c8 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java @@ -25,8 +25,10 @@ import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.math.BigInteger; +import java.util.ArrayList; import java.util.Locale; import java.util.Optional; +import java.util.stream.IntStream; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.testng.annotations.AfterMethod; @@ -97,7 +99,7 @@ public void testImmutableBeanIsCorrectlyCopied(final String testCaseDescription, // GIVEN // WHEN - Object actual = transformer.transform(sourceObject, targetObjectClass); + var actual = transformer.transform(sourceObject, targetObjectClass); // THEN assertThat(actual).usingRecursiveComparison() @@ -119,12 +121,42 @@ private Object[][] dataDefaultTransformationTesting() { beanUtils.getTransformer().withFieldMapping(), fromFoo, ImmutableToFoo.class}, {"Test that immutable beans with constructor arguments parameter annotated with: @ConstructorArg are correctly copied.", beanUtils.getTransformer(), fromFoo, ImmutableToFooCustomAnnotation.class}, - {"Test that bean that extends another class are correctly copied", beanUtils.getTransformer(), fromFooSubClass, ImmutableToFooSubClass.class}, - {"Test that immutable beans with extremely complex map are correctly transformed.", - beanUtils.getTransformer(), fromFooMap, ImmutableToFooMap.class}, + {"Test that bean that extends another class are correctly copied", beanUtils.getTransformer(), fromFooSubClass, ImmutableToFooSubClass.class} }; } + /** + * Test that immutable beans with extremely complex map are correctly transformed. + */ + @Test + public void testImmutableBeanIsCorrectlyCopied() { + // GIVEN + + // WHEN + var actual = new BeanUtils().getTransformer().transform(fromFooMap, ImmutableToFooMap.class); + + // THEN + assertThat(actual).usingRecursiveComparison() + .ignoringAllOverriddenEquals() + .ignoringFields("extremeComplexMap") + .isEqualTo(fromFooMap); + + var fromFooMapKeys = new ArrayList<>(fromFooMap.getExtremeComplexMap().keySet()); + var actualMapKeys = new ArrayList<>(actual.getExtremeComplexMap().keySet()); + IntStream.range(0, fromFooMapKeys.size()) + .forEach(i -> { + var actualKey = actualMapKeys.get(i); + var sourceKey = fromFooMapKeys.get(i); + assertThat(actualKey).usingRecursiveComparison() + .ignoringAllOverriddenEquals() + .isEqualTo(sourceKey); + + assertThat(actual.getExtremeComplexMap().get(actualKey)) + .usingRecursiveComparison() + .isEqualTo(fromFooMap.getExtremeComplexMap().get(sourceKey)); + }); + } + /** * Test transformation on an existing bean is correctly copied. */ diff --git a/pom.xml b/pom.xml index 1b3c0c31f..b9dd301a1 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 4.6.0 7.6.0 - 3.22.0 + 3.23.1 6.2.3.Final 3.5.0.Final From b920c3ddc28b68ae69818e3753c18b9c92400e8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jun 2022 06:58:06 +0200 Subject: [PATCH 1646/1786] Bump mockito-core from 4.6.0 to 4.6.1 (#324) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.6.0 to 4.6.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.6.0...v4.6.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b9dd301a1..1f22e9b5c 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.6.0 + 4.6.1 7.6.0 3.23.1 From 13341e50e4db71342f9c3b3f77610c8309367c31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jun 2022 08:37:07 +0200 Subject: [PATCH 1647/1786] Bump actions/cache from 3.0.3 to 3.0.4 (#326) Bumps [actions/cache](https://github.com/actions/cache) from 3.0.3 to 3.0.4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.3...v3.0.4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 097346abc..d9c5e14fd 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.3 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.3 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.3 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 3e5619261..6c77f1d3c 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.3 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.3 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.3 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index bea377c16..a9ee1323e 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.3 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index ac027bd6b..f79a689ed 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.3 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 949456c8eee9dcccda77da33939b9b0843dbc245 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 9 Jun 2022 11:53:49 +0200 Subject: [PATCH 1648/1786] [issue 325] Disable override of custom properties (#327) --- CHANGELOG-JDK11.md | 3 ++ CHANGELOG.md | 4 +- bull-bean-transformer/pom.xml | 2 +- .../beans/transformer/TransformerImpl.java | 46 ++++++++++++++++--- .../AbstractBeanTransformerTest.java | 2 + .../ImmutableObjectTransformationTest.java | 3 -- .../MixedObjectTransformationTest.java | 9 ++-- .../MutableObjectTransformationTest.java | 4 -- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- .../transformer/utils/ClassUtilsTest.java | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 15 files changed, 61 insertions(+), 26 deletions(-) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index dd815730a..fd94a5547 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +### [2.1.1-jdk11] 2022.06.09 +* Fixes an issue that was preventing skipping the injection for a given field. For more info about the feature see [here](README.md#skip-transformation-on-a-given-set-of-fields). + ### [2.1.0-jdk11] 2022.01.10 #### Changed * Updated `hibernate-validator` version to `6.2.1.Final` (was `7.0.1.Final`). This replaces the jakarta validation with the javax one. diff --git a/CHANGELOG.md b/CHANGELOG.md index a77fcc394..2be203ba2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ - # BULL Change Log All notable changes to this project will be documented in this file. +### [2.2.1] 2022.06.09 +* Fixes an issue that was preventing skipping the injection for a given field. For more info about the feature see [here](README.md#skip-transformation-on-a-given-set-of-fields). + ### [2.2.0] 2022.01.10 #### Changed * Updated `hibernate-validator` version to `6.2.1.Final` (was `7.0.1.Final`). This replaces the jakarta validation with the javax one. diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 0699c03b1..1ffcb3116 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.1-SNAPSHOT + 2.2.2-SNAPSHOT diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java index 91ec00711..574ce5ac8 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java @@ -205,7 +205,7 @@ protected K handleInjectionException(final T sourceObj, final Class ta * Creates a string containing the arguments used to invoke the given class constructor. * @param targetClass the class containing the constructor * @param constructorArgs the passed arguments - * @param he target object type + * @param the target object type * @return the formatted constructor arguments */ private String getFormattedConstructorArgs(final Class targetClass, final Object[] constructorArgs) { @@ -350,8 +350,8 @@ private void injectAllFields(final T sourceObj, final K targetObject, fin * @param the target object type * @return a {@link Consumer} that sets the field value in the target object */ - private Consumer setFieldValue(final T sourceObj, final K targetObject, final Class targetObjectClass, final String breadcrumb) { - return field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObjectClass, field, breadcrumb)); + private Consumer setFieldValue(final T sourceObj, final K targetObject, final Class targetObjectClass, final String breadcrumb) { + return field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObject, targetObjectClass, field, breadcrumb)); } /** @@ -397,8 +397,13 @@ private void injectFields(final List fieldList, final T sourceObj, * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ private Object getFieldValue(final T sourceObj, final Class targetClass, final Field field, final String breadcrumb) { + K k = null; + return getFieldValue(sourceObj, k, targetClass, field, breadcrumb); + } + + private Object getFieldValue(final T sourceObj, final K targetObject, final Class targetClass, final Field field, final String breadcrumb) { String sourceFieldName = getSourceFieldName(field); - return getFieldValue(sourceObj, sourceFieldName, targetClass, field, breadcrumb); + return getFieldValue(sourceObj, sourceFieldName, targetObject, targetClass, field, breadcrumb); } /** @@ -407,17 +412,22 @@ private Object getFieldValue(final T sourceObj, final Class targetClas * @param sourceFieldName sourceFieldName the field name in the source object (if different from the target one) * @param targetClass the destination object class * @param field The field for which the value has to be retrieved - * @param breadcrumb the full path of the current field starting from his ancestor + * @param breadcrumb the full path of the current field starting from his ancestor * @param the sourceObj object type * @param the target object type * @return the field value * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ private Object getFieldValue(final T sourceObj, final String sourceFieldName, final Class targetClass, final Field field, final String breadcrumb) { + return getFieldValue(sourceObj, sourceFieldName, null, targetClass, field, breadcrumb); + } + + private Object getFieldValue(final T sourceObj, final String sourceFieldName, final K targetObject, + final Class targetClass, final Field field, final String breadcrumb) { String fieldBreadcrumb = evalBreadcrumb(field.getName(), breadcrumb); Class fieldType = field.getType(); if (doSkipTransformation(fieldBreadcrumb)) { - return defaultValue(fieldType); + return getDefaultFieldValue(targetObject, fieldBreadcrumb, fieldType); } boolean primitiveType = classUtils.isPrimitiveType(fieldType); FieldTransformer transformerFunction = getTransformerFunction(field, fieldBreadcrumb); @@ -425,7 +435,7 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN Object fieldValue = getSourceFieldValue(sourceObj, sourceFieldName, field, isTransformerFunctionDefined); if (nonNull(fieldValue)) { // is not a primitive type or an optional && there are no transformer function - // defined it recursively evaluate the value + // defined it recursively evaluates the value boolean notPrimitiveAndNotSpecialType = !primitiveType && !classUtils.isSpecialType(fieldType); if (!isTransformerFunctionDefined && (notPrimitiveAndNotSpecialType || Optional.class.isAssignableFrom(fieldValue.getClass()))) { @@ -438,6 +448,28 @@ private Object getFieldValue(final T sourceObj, final String sourceFieldN return fieldValue; } + /** + * Gets the existing value for a given field in the target object (if any) otherwise it gets the default one. + * @param targetObject the destination object instance + * @param fieldBreadcrumb the full path of the current field starting from his ancestor + * @param fieldType the field class + * @param the target object type + * @return the existing value for a given field in the target object (if any) otherwise it gets the default one. + */ + private Object getDefaultFieldValue(final K targetObject, final String fieldBreadcrumb, final Class fieldType) { + return Optional.ofNullable(targetObject) + .map(to -> { + Object fieldValue; + try { + fieldValue = reflectionUtils.getFieldValue(to, fieldBreadcrumb, fieldType); + } catch (Exception e) { + fieldValue = defaultValue(fieldType); + } + return fieldValue; + }) + .orElseGet(() -> defaultValue(fieldType)); + } + /** * Applies all the transformer function associated to the field and returns the results. * If the field type is different and they are primitive a conversion function is automatically applied. diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/AbstractBeanTransformerTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/AbstractBeanTransformerTest.java index 5c7751299..db3c501b8 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/AbstractBeanTransformerTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/AbstractBeanTransformerTest.java @@ -53,5 +53,7 @@ void beforeClass() { @BeforeMethod void beforeMethod() { openMocks(this); + underTest.resetFieldsTransformer(); + underTest.resetFieldsTransformationSkip(); } } diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java index 4bc53b5c8..bbc935bcc 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/ImmutableObjectTransformationTest.java @@ -83,7 +83,6 @@ public class ImmutableObjectTransformationTest extends AbstractBeanTransformerTe @AfterMethod public void afterMethod() { underTest.setValidationEnabled(false); - underTest.resetFieldsTransformer(); } /** @@ -480,7 +479,6 @@ public void testFieldTransformationSkipWorksProperly() { // THEN assertThat(actual).hasNoNullFieldsOrPropertiesExcept(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); - underTest.resetFieldsTransformationSkip(); } /** @@ -500,7 +498,6 @@ public void testTransformerFunctionHasHigherPriorityThanDefaultValue() { // THEN assertThat(actual.getWork()).isTrue(); - underTest.resetFieldsTransformer(); } /** diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java index da753a0cc..bfe5685ba 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MixedObjectTransformationTest.java @@ -170,7 +170,6 @@ public void testFieldTransformationSkipWorksProperly() { // THEN assertThat(actual).hasNoNullFieldsOrPropertiesExcept(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); - underTest.resetFieldsTransformationSkip(); } /** @@ -179,14 +178,18 @@ public void testFieldTransformationSkipWorksProperly() { @Test public void testTransformationOnAnExistingDestinationWorksProperly() { // GIVEN - MixedToFoo mixedToFoo = new MixedToFoo(null, null, null, null, null); + final BigInteger presetFieldId = BigInteger.valueOf(777); + final String fieldNameToIgnore = "id"; + MixedToFoo mixedToFoo = new MixedToFoo(presetFieldId, null, null, null, null); // WHEN - underTest.skipTransformationForField().transform(fromFoo, mixedToFoo); + underTest.skipTransformationForField(fieldNameToIgnore).transform(fromFoo, mixedToFoo); // THEN assertThat(mixedToFoo).usingRecursiveComparison() + .ignoringFields(fieldNameToIgnore) .isEqualTo(fromFoo); + assertThat(mixedToFoo.getId()).isEqualTo(presetFieldId); } /** diff --git a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java index b15928b70..3ed0e4c54 100644 --- a/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java +++ b/bull-bean-transformer/src/test/java/com/expediagroup/beans/transformer/MutableObjectTransformationTest.java @@ -139,7 +139,6 @@ public void testFieldTransformationIsAppliedOnlyToASpecificField() { assertThat(actual) .extracting(NAME_FIELD_NAME, NESTED_OBJECT_NAME_FIELD_NAME) .containsExactly(fromFoo.getName(), namePrefix + fromFoo.getNestedObject().getName()); - underTest.resetFieldsTransformer(); } /** @@ -161,7 +160,6 @@ public void testFieldTransformationIsAppliedToAllMatchingFields() { assertThat(actual.getName()).isEqualTo(namePrefix + fromFoo.getName()); assertThat(actual.getNestedObject().getName()) .isEqualTo(namePrefix + fromFoo.getNestedObject().getName()); - underTest.resetFieldsTransformer(); } /** @@ -230,7 +228,6 @@ public void testThatAnyTypeOfBeanContainsANotExistingFieldInTheSourceObjectIsCor // THEN assertThat(mutableObjectBean).hasFieldOrPropertyWithValue(AGE_FIELD_NAME, AGE); - underTest.resetFieldsTransformer(); } /** @@ -318,7 +315,6 @@ public void testFieldTransformationSkipWorksProperly() { // THEN assertThat(actual).hasNoNullFieldsOrPropertiesExcept(NAME_FIELD_NAME, PHONE_NUMBER_NESTED_OBJECT_FIELD_NAME); - underTest.resetFieldsTransformationSkip(); } /** diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 5e0af1f00..fc7a6f7d8 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.1-SNAPSHOT + 2.2.2-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 1ae75f2ca..05f5dd137 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.1-SNAPSHOT + 2.2.2-SNAPSHOT diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java index e5ddffa53..dc8fa55ca 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java @@ -509,7 +509,7 @@ public void testAreParameterNamesAvailableWorksAsExpected(final String testCaseD private Object[][] dataAreParameterNamesAvailableTesting() { return new Object[][] { {"Tests that the method returns false if the constructor parameter names are not available", createMockedConstructor(), false}, -// {"Tests that the method returns false if the constructor parameter names are available", underTest.getAllArgsConstructor(MixedToFoo.class), true} + {"Tests that the method returns false if the constructor parameter names are available", underTest.getAllArgsConstructor(MixedToFoo.class), true} }; } diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 3550e13af..3c796f4d4 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.1-SNAPSHOT + 2.2.2-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 7a47323d5..41a6a1d1d 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.2.1-SNAPSHOT + 2.2.2-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index f0e6fec7b..a72283540 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.2.1-SNAPSHOT + 2.2.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 1f22e9b5c..0961079cd 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.2.1-SNAPSHOT + 2.2.2-SNAPSHOT pom 2019 From 7f20c195df10eabe83daa108fc2ab7fee0068419 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 9 Jun 2022 12:09:55 +0200 Subject: [PATCH 1649/1786] fixes a code smell --- .../expediagroup/beans/transformer/TransformerImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java index 574ce5ac8..a3ca121ce 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java @@ -336,7 +336,7 @@ private Object[] getConstructorValuesFromFields(final T sourceObj, final * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ private void injectAllFields(final T sourceObj, final K targetObject, final String breadcrumb) { - final Class targetObjectClass = targetObject.getClass(); + final Class targetObjectClass = (Class) targetObject.getClass(); injectFields(classUtils.getDeclaredFields(targetObjectClass, true), sourceObj, targetObject, targetObjectClass, breadcrumb); } @@ -350,7 +350,7 @@ private void injectAllFields(final T sourceObj, final K targetObject, fin * @param the target object type * @return a {@link Consumer} that sets the field value in the target object */ - private Consumer setFieldValue(final T sourceObj, final K targetObject, final Class targetObjectClass, final String breadcrumb) { + private Consumer setFieldValue(final T sourceObj, final K targetObject, final Class targetObjectClass, final String breadcrumb) { return field -> reflectionUtils.setFieldValue(targetObject, field, getFieldValue(sourceObj, targetObject, targetObjectClass, field, breadcrumb)); } @@ -364,7 +364,7 @@ private Consumer setFieldValue(final T sourceObj, final K targetOb * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ private void injectNotFinalFields(final T sourceObj, final K targetObject, final String breadcrumb) { - final Class targetObjectClass = targetObject.getClass(); + final Class targetObjectClass = (Class) targetObject.getClass(); injectFields(classUtils.getNotFinalFields(targetObjectClass, true), sourceObj, targetObject, targetObjectClass, breadcrumb); } @@ -379,7 +379,7 @@ private void injectNotFinalFields(final T sourceObj, final K targetObject * @param the target object type * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value */ - private void injectFields(final List fieldList, final T sourceObj, final K targetObject, final Class targetObjectClass, final String breadcrumb) { + private void injectFields(final List fieldList, final T sourceObj, final K targetObject, final Class targetObjectClass, final String breadcrumb) { fieldList //.parallelStream() .forEach(setFieldValue(sourceObj, targetObject, targetObjectClass, breadcrumb)); From e7033cf0887cbbee4b046c257d103cccf8da6120 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 9 Jun 2022 12:40:57 +0200 Subject: [PATCH 1650/1786] code look and feel improvement --- CHANGELOG-JDK11.md | 8 ++-- CHANGELOG-JDK8.md | 8 ++-- README.md | 46 +++++++++---------- .../beans/transformer/TransformerImpl.java | 19 +------- .../transformer/utils/ReflectionUtils.java | 4 +- docs/site/markdown/glossary.md | 10 ++-- .../markdown/transformer/bean/performance.md | 26 +++++------ .../bean/thirdPartyLibComparison.md | 36 +++++++-------- 8 files changed, 71 insertions(+), 86 deletions(-) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index fd94a5547..ab6ea0b8d 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -114,11 +114,11 @@ All notable changes to this project will be documented in this file. * Module `bean-utils-library` has been relocated into `bull-bean-transformer`. * The following classes has been deprecated, please find below the complete list and the new one to be used: - | Deprecated | **New one** | - | :----------- | :----------- | - | `com.expediagroup.beans.model.FieldMapping` | `FieldMapping` | + | Deprecated | **New one** | + |:------------------------------------------------|:-------------------| + | `com.expediagroup.beans.model.FieldMapping` | `FieldMapping` | | `com.expediagroup.beans.model.FieldTransformer` | `FieldTransformer` | - | `com.expediagroup.beans.Transformer` | `Transformer` | + | `com.expediagroup.beans.Transformer` | `Transformer` | ### [1.5.0] 2019.08.06 #### Added diff --git a/CHANGELOG-JDK8.md b/CHANGELOG-JDK8.md index 4bf8b64d9..6b5bfb8e2 100755 --- a/CHANGELOG-JDK8.md +++ b/CHANGELOG-JDK8.md @@ -95,11 +95,11 @@ All notable changes to this project will be documented in this file. * Module `bean-utils-library` has been relocated into `bull-bean-transformer`. * The following classes has been deprecated, please find below the complete list and the new one to be used: - | Deprecated | **New one** | - | :----------- | :----------- | - | `com.expediagroup.beans.model.FieldMapping` | `FieldMapping` | + | Deprecated | **New one** | + |:------------------------------------------------|:-------------------| + | `com.expediagroup.beans.model.FieldMapping` | `FieldMapping` | | `com.expediagroup.beans.model.FieldTransformer` | `FieldTransformer` | - | `com.expediagroup.beans.Transformer` | `Transformer` | + | `com.expediagroup.beans.Transformer` | `Transformer` | ### [1.1.23] 2019.08.06 #### Added diff --git a/README.md b/README.md index ada78ad99..4f0ed00f9 100644 --- a/README.md +++ b/README.md @@ -822,24 +822,24 @@ Following a comparison between the BULL functionalities and the following Third- * [Jackson Data Bind](https://github.com/FasterXML/jackson-databind) * [Dozer](http://dozer.sourceforge.net/) -| | **BULL** | **Apache Bean Utils** | **Jackson** | **Dozer** | -| :----------- | :-----------: | :-----------: | :-----------: | :-----------: | -| Mutable bean copy | X | X | X | X+ | -| Mutable bean with nested objects | X | - | X | X+ | -| Mutable bean extending classes | X | - | X | X+ | -| Immutable bean copy | X | - | - | X* | -| Mixed bean copy | X | - | - | X+ | -| Copy of beans without getter and setter methods defined | X | - | - | - | -| Mutable Bean with different field's name | X | - | - | X+ | -| Mixed with different field's type | X | - | - | X+ | -| Immutable with different field's type | X | - | - | X+ | -| Mutable Bean containing collection type fields containing complex objects | X | - | X | X | -| Mixed Bean containing collection type fields containing complex objects | X | - | - | X+ | -| Immutable Bean containing collection type fields containing complex objects | X | - | - | X+ | -| Mutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | X | X | -| Mixed Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | -| Immutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | -| Annotation field validation | X | - | X | - | +| | **BULL** | **Apache Bean Utils** | **Jackson** | **Dozer** | +|:------------------------------------------------------------------------------------------------------------------------|:--------:|:---------------------:|:-----------:|:---------:| +| Mutable bean copy | X | X | X | X+ | +| Mutable bean with nested objects | X | - | X | X+ | +| Mutable bean extending classes | X | - | X | X+ | +| Immutable bean copy | X | - | - | X* | +| Mixed bean copy | X | - | - | X+ | +| Copy of beans without getter and setter methods defined | X | - | - | - | +| Mutable Bean with different field's name | X | - | - | X+ | +| Mixed with different field's type | X | - | - | X+ | +| Immutable with different field's type | X | - | - | X+ | +| Mutable Bean containing collection type fields containing complex objects | X | - | X | X | +| Mixed Bean containing collection type fields containing complex objects | X | - | - | X+ | +| Immutable Bean containing collection type fields containing complex objects | X | - | - | X+ | +| Mutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | X | X | +| Mixed Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | +| Immutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | +| Annotation field validation | X | - | X | - | _[*] Immutable types are not supported by Dozer. When a type doesn't have a no-arg constructor and all fields are final, Dozer can't perform the mapping. A workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ @@ -855,11 +855,11 @@ Let's have a look at the performance library performance. The test has been exec * Immutable objects extending another immutable object * Mixed objects -| | **Mutable** | **Immutable** | **Mixed** | -| :----------- | :-----------: | :-----------: | :-----------: | -| Simple objects (without nested objects) | ~0.011ms | ~0.018ms | NA | -| Complex objects (containing several nested object and several items in Map and Array objects) | ~0.37ms | ~0.21ms | ~0.22ms | -| CPU/Heap usage | [~0.2%/35 MB](docs/site/resources/images/stats/performance/mutableObject/jvmStats.jpg) | [~0.2%/30 MB](docs/site/resources/images/stats/performance/immutableObject/jvmStats.jpg) | [~0.2%/25 MB](docs/site/resources/images/stats/performance/mixedObject/jvmStats.jpg) | +| | **Mutable** | **Immutable** | **Mixed** | +|:----------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------:| +| Simple objects (without nested objects) | ~0.011ms | ~0.018ms | NA | +| Complex objects (containing several nested object and several items in Map and Array objects) | ~0.37ms | ~0.21ms | ~0.22ms | +| CPU/Heap usage | [~0.2%/35 MB](docs/site/resources/images/stats/performance/mutableObject/jvmStats.jpg) | [~0.2%/30 MB](docs/site/resources/images/stats/performance/immutableObject/jvmStats.jpg) | [~0.2%/25 MB](docs/site/resources/images/stats/performance/mixedObject/jvmStats.jpg) | Transformation time [screenshot](docs/site/resources/images/stats/performance/transformationTime.png) diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java index a3ca121ce..5069f8268 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java @@ -321,8 +321,9 @@ private String getDestFieldName(final Parameter constructorParameter, final Stri */ private Object[] getConstructorValuesFromFields(final T sourceObj, final Class targetClass, final String breadcrumb) { final List declaredFields = classUtils.getDeclaredFields(targetClass, true); + K k = null; return declaredFields.stream() - .map(field -> getFieldValue(sourceObj, targetClass, field, breadcrumb)) + .map(field -> getFieldValue(sourceObj, k, targetClass, field, breadcrumb)) .toArray(Object[]::new); } @@ -385,22 +386,6 @@ private void injectFields(final List fieldList, final T sourceObj, .forEach(setFieldValue(sourceObj, targetObject, targetObjectClass, breadcrumb)); } - /** - * Retrieves the value of a field. In case it is not a primitive type it recursively inject the values inside the object. - * @param sourceObj sourceObj the source object - * @param targetClass the destination object class - * @param field The field for which the value has to be retrieved - * @param breadcrumb the full path of the current field starting from his ancestor - * @param the sourceObj object type - * @param the target object type - * @return the field value - * @throws InvalidBeanException {@link InvalidBeanException} if an error occurs while retrieving the value - */ - private Object getFieldValue(final T sourceObj, final Class targetClass, final Field field, final String breadcrumb) { - K k = null; - return getFieldValue(sourceObj, k, targetClass, field, breadcrumb); - } - private Object getFieldValue(final T sourceObj, final K targetObject, final Class targetClass, final Field field, final String breadcrumb) { String sourceFieldName = getSourceFieldName(field); return getFieldValue(sourceObj, sourceFieldName, targetObject, targetClass, field, breadcrumb); diff --git a/bull-common/src/main/java/com/expediagroup/transformer/utils/ReflectionUtils.java b/bull-common/src/main/java/com/expediagroup/transformer/utils/ReflectionUtils.java index 262340248..8fd5a154d 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/utils/ReflectionUtils.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/utils/ReflectionUtils.java @@ -382,7 +382,7 @@ public void setFieldValue(final Object target, final Field field, final Object f * @param field the field to set * @param fieldValue the value to set */ - protected void setFieldValueWithoutSetterMethod(final Object target, final Field field, final Object fieldValue) { + void setFieldValueWithoutSetterMethod(final Object target, final Field field, final Object fieldValue) { try { field.set(target, fieldValue); } catch (final Exception e) { @@ -618,7 +618,7 @@ public Class getArrayType(final Field arrayField) { * @param ex the exception * @return the exception to be thrown */ - protected RuntimeException handleReflectionException(final Exception ex) { + RuntimeException handleReflectionException(final Exception ex) { RuntimeException e; if (ex instanceof NoSuchMethodException) { e = new MissingMethodException("Method not found: " + ex.getMessage()); diff --git a/docs/site/markdown/glossary.md b/docs/site/markdown/glossary.md index 0a127e100..bfacbd893 100644 --- a/docs/site/markdown/glossary.md +++ b/docs/site/markdown/glossary.md @@ -4,8 +4,8 @@ # Glossary -| Word/Phrase/Abbreviation/Acronym | Definition | -| --- | --- | -| BULL | Bean Utils Light Library | -| BPE | Booking Payment Edge | -| BPAS | Booking Payment Availability Service | \ No newline at end of file +| Word/Phrase/Abbreviation/Acronym | Definition | +|----------------------------------|--------------------------------------| +| BULL | Bean Utils Light Library | +| BPE | Booking Payment Edge | +| BPAS | Booking Payment Availability Service | \ No newline at end of file diff --git a/docs/site/markdown/transformer/bean/performance.md b/docs/site/markdown/transformer/bean/performance.md index 2043942da..7546a510f 100644 --- a/docs/site/markdown/transformer/bean/performance.md +++ b/docs/site/markdown/transformer/bean/performance.md @@ -12,11 +12,11 @@ This page shows the transformer performance for the following objects: * Immutable objects extending another immutable object * Mixed objects -| | **Mutable** | **Immutable** | **Mixed** | -| :----------- | :-----------: | :-----------: | :-----------: | -| Simple objects (without nested objects) | ~0.011ms | ~0.018ms | NA | -| Complex objects (containing several nested object and several items in Map and Array objects) | ~0.37ms | ~0.21ms | ~0.22ms | -| CPU/Heap usage | [~0.2%/35 MB](docs/site/resources/images/stats/performance/mutableObject/jvmStats.jpg) | [~0.2%/30 MB](docs/site/resources/images/stats/performance/immutableObject/jvmStats.jpg) | [~0.2%/25 MB](docs/site/resources/images/stats/performance/mixedObject/jvmStats.jpg) | +| | **Mutable** | **Immutable** | **Mixed** | +|:----------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------:| +| Simple objects (without nested objects) | ~0.011ms | ~0.018ms | NA | +| Complex objects (containing several nested object and several items in Map and Array objects) | ~0.37ms | ~0.21ms | ~0.22ms | +| CPU/Heap usage | [~0.2%/35 MB](docs/site/resources/images/stats/performance/mutableObject/jvmStats.jpg) | [~0.2%/30 MB](docs/site/resources/images/stats/performance/immutableObject/jvmStats.jpg) | [~0.2%/25 MB](docs/site/resources/images/stats/performance/mixedObject/jvmStats.jpg) | Transformation time [screenshot](../images/stats/performance/transformationTime.png) @@ -27,11 +27,11 @@ The purpose was to compare the latency introduced by the library plus the memory The dashboard's screenshot shows the latency of the invoked downstream service (called BPAS) and the one where the library has been installed (BPE). Following the obtained results: -| | **Classic transformer** | **BeanUtils library** | -| :----------- | :-----------: | :-----------: | -| Throughput per second | 60 | 60 | -| Average CPU usage | 0.3% | 0.3% | -| Min/Max Heap Memory Usage (MB) | 90/320 | 90/320 | -| Average Latency than the downstream service | +2ms | +2ms | -| JVM stats screenshot | [screenshot](../images/stats/performance/realTestCase/classicTransformer/jvmStats.jpg) | [screenshot](../images/stats/performance/realTestCase/beanUtilsLib/jvmStats.jpg) | -| Dashboard screenshot | [screenshot](../images/stats/performance/realTestCase/classicTransformer/dashboard.jpg) | [screenshot](../images/stats/performance/realTestCase/beanUtilsLib/dashboard.jpg) | +| | **Classic transformer** | **BeanUtils library** | +|:--------------------------------------------|:---------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------:| +| Throughput per second | 60 | 60 | +| Average CPU usage | 0.3% | 0.3% | +| Min/Max Heap Memory Usage (MB) | 90/320 | 90/320 | +| Average Latency than the downstream service | +2ms | +2ms | +| JVM stats screenshot | [screenshot](../images/stats/performance/realTestCase/classicTransformer/jvmStats.jpg) | [screenshot](../images/stats/performance/realTestCase/beanUtilsLib/jvmStats.jpg) | +| Dashboard screenshot | [screenshot](../images/stats/performance/realTestCase/classicTransformer/dashboard.jpg) | [screenshot](../images/stats/performance/realTestCase/beanUtilsLib/dashboard.jpg) | diff --git a/docs/site/markdown/transformer/bean/thirdPartyLibComparison.md b/docs/site/markdown/transformer/bean/thirdPartyLibComparison.md index 65dae5992..9ee0115b3 100644 --- a/docs/site/markdown/transformer/bean/thirdPartyLibComparison.md +++ b/docs/site/markdown/transformer/bean/thirdPartyLibComparison.md @@ -12,24 +12,24 @@ This page compares the Transformer functionalities with the following Third-Part ## Functions -| | **BULL** | **Apache Bean Utils** | **Jackson** | **Dozer** | -| :----------- | :-----------: | :-----------: | :-----------: | :-----------: | -| Mutable bean copy | X | X | X | X+ | -| Mutable bean with nested objects | X | - | X | X+ | -| Mutable bean extending classes | X | - | X | X+ | -| Immutable bean copy | X | - | - | X* | -| Mixed bean copy | X | - | - | X+ | -| Copy of beans without getter and setter methods defined | X | - | - | - | -| Mutable Bean with different field's name | X | - | - | X+ | -| Mixed with different field's type | X | - | - | X+ | -| Immutable with different field's type | X | - | - | X+ | -| Mutable Bean containing collection type fields containing complex objects | X | - | X | X | -| Mixed Bean containing collection type fields containing complex objects | X | - | - | X+ | -| Immutable Bean containing collection type fields containing complex objects | X | - | - | X+ | -| Mutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | X | X | -| Mixed Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | -| Immutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | -| Annotation field validation | X | - | X | - | +| | **BULL** | **Apache Bean Utils** | **Jackson** | **Dozer** | +|:------------------------------------------------------------------------------------------------------------------------|:--------:|:---------------------:|:-----------:|:---------:| +| Mutable bean copy | X | X | X | X+ | +| Mutable bean with nested objects | X | - | X | X+ | +| Mutable bean extending classes | X | - | X | X+ | +| Immutable bean copy | X | - | - | X* | +| Mixed bean copy | X | - | - | X+ | +| Copy of beans without getter and setter methods defined | X | - | - | - | +| Mutable Bean with different field's name | X | - | - | X+ | +| Mixed with different field's type | X | - | - | X+ | +| Immutable with different field's type | X | - | - | X+ | +| Mutable Bean containing collection type fields containing complex objects | X | - | X | X | +| Mixed Bean containing collection type fields containing complex objects | X | - | - | X+ | +| Immutable Bean containing collection type fields containing complex objects | X | - | - | X+ | +| Mutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | X | X | +| Mixed Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | +| Immutable Bean containing containing Map type fields with nested Maps inside. e.g. `Map>` | X | - | - | X+ | +| Annotation field validation | X | - | X | - | _[*] Immutable types are not supported by Dozer. When a type doesn't have a no-arg constructor and all fields are final, Dozer can't perform the mapping. The workaround is introducing the Builder Pattern. An example can be found [here](http://codeslut.blogspot.com/2010/05/mapping-immutable-value-objects-with.html)_ From 9f872199f02019fe6c6fdc08cba008b8430e6b89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jun 2022 06:53:44 +0200 Subject: [PATCH 1651/1786] Bump wagon-ssh from 3.5.1 to 3.5.2 (#329) Bumps wagon-ssh from 3.5.1 to 3.5.2. --- updated-dependencies: - dependency-name: org.apache.maven.wagon:wagon-ssh dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0961079cd..4e2cec371 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ 2.3.1 - 3.5.1 + 3.5.2 0.12 github 3.12.0 From 58f46754ce5e9eb07acd43d28af6375130f225a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jun 2022 06:57:00 +0200 Subject: [PATCH 1652/1786] Bump checkstyle from 10.3 to 10.3.1 (#328) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.3 to 10.3.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.3...checkstyle-10.3.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4e2cec371..39105aca2 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.4.0 3.1.2 2.11.0 - 10.3 + 10.3.1 3.0.0-M4 1.6.13 3.1.2 From 607c412c313e97b78263c05ca516b09c8a551381 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Jul 2022 15:35:58 +0200 Subject: [PATCH 1653/1786] Bump testng from 7.6.0 to 7.6.1 (#330) Bumps [testng](https://github.com/cbeust/testng) from 7.6.0 to 7.6.1. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/commits) --- updated-dependencies: - dependency-name: org.testng:testng dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 39105aca2..f6381dc1b 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.12.0 4.6.1 - 7.6.0 + 7.6.1 3.23.1 6.2.3.Final From 64638a4987d220f01062f28a954ae4e7c8df46c4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 6 Jul 2022 11:50:20 +0200 Subject: [PATCH 1654/1786] modifies the bom module to make it importing only the required versions --- README.md | 2 ++ bull-bom/pom.xml | 43 +++++++++++++++++++++++++------------------ pom.xml | 2 +- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 4f0ed00f9..419f8ac92 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ It contains all the modules available in the project com.expediagroup.beans bull-bom x.y.z + pom + import ``` diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index fc7a6f7d8..78489da28 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 BULL - BOM bull-bom - jar + pom Contains all the modules available in the BULL project @@ -12,22 +12,29 @@ 2.2.2-SNAPSHOT - - - com.expediagroup.beans - bull-bean-transformer - ${project.version} - - - com.expediagroup.beans - bull-map-transformer - ${project.version} - - - com.expediagroup.beans - bull-converter - ${project.version} - - + + + + com.expediagroup.beans + bull-common + ${project.version} + + + com.expediagroup.beans + bull-bean-transformer + ${project.version} + + + com.expediagroup.beans + bull-map-transformer + ${project.version} + + + com.expediagroup.beans + bull-converter + ${project.version} + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index f6381dc1b..0ac9561a0 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ github 3.12.0 - [3.8.1,) + [3.6.1,) 3.0.1 3.4.0 3.1.2 From bd01e697c0311d1a9e6f05c895dccf8493362e1c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 6 Jul 2022 11:51:25 +0200 Subject: [PATCH 1655/1786] restores the maven required version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0ac9561a0..f6381dc1b 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ github 3.12.0 - [3.6.1,) + [3.8.1,) 3.0.1 3.4.0 3.1.2 From ac1a78b35dc264534fd754e7bf1ffc9587594be4 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 6 Jul 2022 15:34:01 +0200 Subject: [PATCH 1656/1786] Prepares the release --- CHANGELOG-JDK11.md | 3 +++ CHANGELOG.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index ab6ea0b8d..d9aee293d 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +### [2.1.2-jdk11] 2022.07.06 +* Adds the Bill of Materials (BOM) module + ### [2.1.1-jdk11] 2022.06.09 * Fixes an issue that was preventing skipping the injection for a given field. For more info about the feature see [here](README.md#skip-transformation-on-a-given-set-of-fields). diff --git a/CHANGELOG.md b/CHANGELOG.md index 2be203ba2..4bcd571f9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +### [2.2.2] 2022.07.06 +* Adds the Bill of Materials (BOM) module + ### [2.2.1] 2022.06.09 * Fixes an issue that was preventing skipping the injection for a given field. For more info about the feature see [here](README.md#skip-transformation-on-a-given-set-of-fields). From 926576fa3212649eb2915df75ba28afe326607ca Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Wed, 6 Jul 2022 15:45:00 +0200 Subject: [PATCH 1657/1786] Prepares the next release --- bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 2 +- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 1ffcb3116..5fc50842b 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.2-SNAPSHOT + 2.2.3-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index 78489da28..ff205bf9e 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.2-SNAPSHOT + 2.2.3-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index 05f5dd137..dc94c3107 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.2-SNAPSHOT + 2.2.3-SNAPSHOT diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index 3c796f4d4..a56e86272 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.2-SNAPSHOT + 2.2.3-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 41a6a1d1d..0666bdb86 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.2.2-SNAPSHOT + 2.2.3-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index a72283540..1956a64ca 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.2.2-SNAPSHOT + 2.2.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index f6381dc1b..3d94242b6 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.2.2-SNAPSHOT + 2.2.3-SNAPSHOT pom 2019 From 474759d7661a21e41dfbdc2bbc6ad98c282af818 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Jul 2022 22:28:33 +0200 Subject: [PATCH 1658/1786] Bump actions/cache from 3.0.4 to 3.0.5 (#331) Bumps [actions/cache](https://github.com/actions/cache) from 3.0.4 to 3.0.5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.4...v3.0.5) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index d9c5e14fd..56a07cf41 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 6c77f1d3c..6139177a7 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index a9ee1323e..d6684343d 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index f79a689ed..494f39b54 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From b5f7bc5f0f7c91f5a485faf23a42f311b9da158a Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 28 Jul 2022 09:00:59 +0200 Subject: [PATCH 1659/1786] Moves the PULL_REQUEST_TEMPLATE.md file under .github folder (#332) Co-authored-by: Fabio Borriello --- PULL_REQUEST_TEMPLATE.md => .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename PULL_REQUEST_TEMPLATE.md => .github/PULL_REQUEST_TEMPLATE.md (96%) diff --git a/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 96% rename from PULL_REQUEST_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md index 35afcfe4f..7cca2ee63 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -28,7 +28,7 @@ Please describe the tests that you ran to verify your changes. Please also note - [ ] Any dependent changes have been merged and published in downstream modules - [ ] My changes have no bad impacts on performances - [ ] My changes have been tested through Unit Tests and the overall coverage has not decreased. Check the coverall report for your branch: [here](https://coveralls.io/github/ExpediaGroup/bull) -- [ ] Any implemented change has been added in the [CHANGELOG.md](./CHANGELOG.md) file -- [ ] Any implemented change has been added in the [CHANGELOG-JDK11.md](./CHANGELOG-JDK11.md) file +- [ ] Any implemented change has been added in the [CHANGELOG.md](../CHANGELOG.md) file +- [ ] Any implemented change has been added in the [CHANGELOG-JDK11.md](../CHANGELOG-JDK11.md) file - [ ] My changes have been applied on a separate branch too with compatibility with Java 11. Follow this [instructions](https://github.com/ExpediaGroup/bull/blob/master/RELEASE.md#3-prepare-the-jdk11-release) for help. - [ ] The maven version has been increased. From b0faeb3ee737ac8701fdb4b6cdb6094c8c6ab880 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Aug 2022 09:44:48 +0200 Subject: [PATCH 1660/1786] Bump checkstyle from 10.3.1 to 10.3.2 (#333) * Bump checkstyle from 10.3.1 to 10.3.2 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.3.1 to 10.3.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.3.1...checkstyle-10.3.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3d94242b6..ef8e21661 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.4.0 3.1.2 2.11.0 - 10.3.1 + 10.3.2 3.0.0-M4 1.6.13 3.1.2 From 9447eadfd5a163f77a7a6822c9d588d70db0e230 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Aug 2022 08:21:00 +0200 Subject: [PATCH 1661/1786] Bump hibernate-validator from 6.2.3.Final to 6.2.4.Final (#335) * Bump hibernate-validator from 6.2.3.Final to 6.2.4.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.2.3.Final to 6.2.4.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.2.4.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.2.3.Final...6.2.4.Final) --- updated-dependencies: - dependency-name: org.hibernate.validator:hibernate-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ef8e21661..69c6cf13b 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 7.6.1 3.23.1 - 6.2.3.Final + 6.2.4.Final 3.5.0.Final 2.2.1.Final 1.7.36 From 4599cce78a0b019672dc0016a5e2cd9b7d6a95ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Aug 2022 08:21:50 +0200 Subject: [PATCH 1662/1786] Bump maven-site-plugin from 3.12.0 to 3.12.1 (#334) * Bump maven-site-plugin from 3.12.0 to 3.12.1 Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.12.0 to 3.12.1. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.12.0...maven-site-plugin-3.12.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * schedule the dependabot check at 10 o clock rome time Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/dependabot.yml | 2 ++ pom.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 57710eef3..09d69c1d3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,6 +6,8 @@ updates: directory: "/" schedule: interval: "daily" + time: "12:00" + timezone: "Etc/UTC" target-branch: develop reviewers: - fborriello diff --git a/pom.xml b/pom.xml index 69c6cf13b..71d884a79 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.5.2 0.12 github - 3.12.0 + 3.12.1 [3.8.1,) 3.0.1 From c38a0f66fbd708d9db9b9a2eada8adfd904a9cc0 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 5 Aug 2022 16:29:10 +0200 Subject: [PATCH 1663/1786] Trigger notification From d786f9c1a76e15769009b8677f0243d48c7192ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Aug 2022 17:12:41 +0200 Subject: [PATCH 1664/1786] Bump actions/cache from 3.0.5 to 3.0.6 (#336) * Bump actions/cache from 3.0.5 to 3.0.6 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.5 to 3.0.6. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.5...v3.0.6) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * moving env setting before Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 18 +++++++++--------- .../workflows/github-default-jdk11-actions.yml | 6 +++--- .../workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 56a07cf41..b2194668a 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.5 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.5 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -48,18 +48,18 @@ jobs: distribution: 'adopt' - name: "Test and Quality check" uses: nick-invision/retry@v2 - with: - max_attempts: 3 - timeout_minutes: 5 - retry_on: error - command: | - mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + with: + max_attempts: 3 + timeout_minutes: 5 + retry_on: error + command: | + mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode security-check: name: "Security check" runs-on: ubuntu-latest @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.5 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 6139177a7..33569402d 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.5 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.5 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.5 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index d6684343d..e612a3dbf 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.5 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 494f39b54..5ff806d2e 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.5 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 1f7de7832a612887d7d77c5618a3bae151cf8984 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Aug 2022 18:34:10 +0200 Subject: [PATCH 1665/1786] downgrades some dependency to test the GitHub actions after a dependabot PR --- .github/workflows/github-default-actions.yml | 6 +- .../github-default-jdk11-actions.yml | 6 +- .../bytecode/TransformerBytecodeAdapter.java | 106 +++++++++++ .../generator/bytecode/package-info.java | 27 +++ .../TransformerBytecodeAdapterTest.java | 169 ++++++++++++++++++ .../generator/bytecode/package-info.java | 19 ++ .../TransformerBytecodeAdapterExample.java | 73 ++++++++ .../sample/TransformerCtorThrows.java | 34 ++++ .../sample/TransformerCtorWithArgs.java | 34 ++++ .../sample/TransformerPrivateCtor.java | 35 ++++ .../bytecode/sample/package-info.java | 19 ++ .../beans/generator/core/Transformer.java | 32 ++++ .../beans/generator/core/TransformerSpec.java | 90 ++++++++++ .../error/TransformerGeneratorException.java | 33 ++++ .../generator/core/error/package-info.java | 19 ++ .../generator/core/mapping/BeanProperty.java | 63 +++++++ .../generator/core/mapping/JavaBeanCode.java | 91 ++++++++++ .../generator/core/mapping/MappingCode.java | 86 +++++++++ .../core/mapping/MappingCodeFactory.java | 83 +++++++++ .../generator/core/mapping/package-info.java | 22 +++ .../beans/generator/core/package-info.java | 25 +++ .../generator/core/TransformerSpecTest.java | 95 ++++++++++ .../core/mapping/BeanPropertyTest.java | 137 ++++++++++++++ .../core/mapping/JavaBeanCodeTest.java | 59 ++++++ .../core/mapping/MappingCodeFactoryTest.java | 95 ++++++++++ .../generator/core/mapping/package-info.java | 19 ++ .../beans/generator/core/package-info.java | 19 ++ .../immutable/ImmutableDestination.java | 29 +++ .../core/sample/immutable/package-info.java | 19 ++ .../core/sample/javabean/Destination.java | 29 +++ .../core/sample/javabean/Source.java | 33 ++++ .../sample/javabean/TransformerExample.java | 44 +++++ .../core/sample/javabean/package-info.java | 19 ++ .../core/sample/mixed/MixedDestination.java | 32 ++++ .../core/sample/mixed/package-info.java | 19 ++ .../transformer/constant/ClassType.java | 53 ++++++ .../transformer/constant/package-info.java | 19 ++ .../source/SourceTransformerSpec.java | 90 ++++++++++ .../generator/source/TransformerFile.java | 62 +++++++ .../source/TransformerSourceAdapter.java | 77 ++++++++ .../beans/generator/source/package-info.java | 30 ++++ .../source/SourceTransformerSpecTest.java | 115 ++++++++++++ .../generator/source/TransformerFileTest.java | 97 ++++++++++ .../source/TransformerSourceAdapterTest.java | 82 +++++++++ .../beans/generator/source/package-info.java | 19 ++ .../TransformerSourceAdapterExample.java | 60 +++++++ .../generator/source/sample/package-info.java | 19 ++ pom.xml | 2 +- 48 files changed, 2438 insertions(+), 7 deletions(-) create mode 100644 bull-transformer-generator/transformer-bytecode-adapter/src/main/java/com/expediagroup/beans/generator/bytecode/TransformerBytecodeAdapter.java create mode 100644 bull-transformer-generator/transformer-bytecode-adapter/src/main/java/com/expediagroup/beans/generator/bytecode/package-info.java create mode 100644 bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/TransformerBytecodeAdapterTest.java create mode 100644 bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/package-info.java create mode 100644 bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerBytecodeAdapterExample.java create mode 100644 bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerCtorThrows.java create mode 100644 bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerCtorWithArgs.java create mode 100644 bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerPrivateCtor.java create mode 100644 bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/package-info.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/Transformer.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/TransformerSpec.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/error/TransformerGeneratorException.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/error/package-info.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/BeanProperty.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/JavaBeanCode.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/MappingCode.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/MappingCodeFactory.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/package-info.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/package-info.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/TransformerSpecTest.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/BeanPropertyTest.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/JavaBeanCodeTest.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/MappingCodeFactoryTest.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/package-info.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/package-info.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/immutable/ImmutableDestination.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/immutable/package-info.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/Destination.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/Source.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/TransformerExample.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/package-info.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/mixed/MixedDestination.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/mixed/package-info.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/transformer/constant/ClassType.java create mode 100644 bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/transformer/constant/package-info.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/SourceTransformerSpec.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/TransformerFile.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/TransformerSourceAdapter.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/package-info.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/SourceTransformerSpecTest.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/TransformerFileTest.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/TransformerSourceAdapterTest.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/package-info.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/sample/TransformerSourceAdapterExample.java create mode 100644 bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/sample/package-info.java diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index b2194668a..4ea022612 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 33569402d..6c77f1d3c 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/bull-transformer-generator/transformer-bytecode-adapter/src/main/java/com/expediagroup/beans/generator/bytecode/TransformerBytecodeAdapter.java b/bull-transformer-generator/transformer-bytecode-adapter/src/main/java/com/expediagroup/beans/generator/bytecode/TransformerBytecodeAdapter.java new file mode 100644 index 000000000..7a947105c --- /dev/null +++ b/bull-transformer-generator/transformer-bytecode-adapter/src/main/java/com/expediagroup/beans/generator/bytecode/TransformerBytecodeAdapter.java @@ -0,0 +1,106 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.bytecode; + +import java.io.IOException; +import java.util.Map; + +import com.expediagroup.beans.generator.core.Transformer; +import com.expediagroup.beans.generator.core.TransformerSpec; +import com.expediagroup.beans.generator.core.error.TransformerGeneratorException; +import com.itranswarp.compiler.JavaStringCompiler; +import com.squareup.javapoet.JavaFile; + +import lombok.Builder; +import lombok.extern.slf4j.Slf4j; + +/** + * A bytecode adapter for {@link TransformerSpec} that compiles at runtime the source code + * represented by the model, and creates a new instance of {@link Transformer}. + * + * This component is intended for internal usage in Bull as it's a low-level wrapper for + * runtime compilation of models. Clients should prefer higher level interfaces + * such as {@code TransformerRegistry}. + */ +@Builder +@Slf4j +public final class TransformerBytecodeAdapter { + + /** + * The default Transformer package if none is specified. + */ + static final String DEFAULT_PACKAGE = "com.expediagroup.beans.transformer"; + + /** + * The Transformer model for generating source code. + */ + private final TransformerSpec spec; + + /** + * The Java package to use for the generated transformer classes. + */ + @Builder.Default + private final String packageName = DEFAULT_PACKAGE; + + /** + * The compiler instance to use at runtime. + */ + @Builder.Default + private final JavaStringCompiler compiler = new JavaStringCompiler(); + + /** + * Dynamically create a new {@link Transformer} instance from {@code source} to {@code destination}. + * @param the source type + * @param the destination type + * @param source the source class + * @param destination the destination class + * @return a new Transformer instance + */ + @SuppressWarnings("unchecked") + public Transformer newTransformer(final Class source, final Class destination) { + JavaFile javaFile = JavaFile.builder(packageName, spec.build(source, destination)).build(); + String transformerCode = javaFile.toString(); + String className = qualifiedName(javaFile); + try { + log.info("Compiling and loading '{}'", className); + log.debug("\n{}", transformerCode); + Map results = compiler.compile(javaFile.typeSpec.name + ".java", transformerCode); + Class> transformerClass = (Class>) compiler.loadClass(className, results); + return transformerClass.getDeclaredConstructor().newInstance(); + } catch (IOException e) { + throw new TransformerGeneratorException( + "There was an error compiling '" + className + "'", e); + } catch (ClassNotFoundException e) { + throw new TransformerGeneratorException( + "There was an error loading the compiled transformer '" + className + "'", e); + } catch (ReflectiveOperationException e) { + throw new TransformerGeneratorException( + "There was an error instantiating the transformer '" + className + "': " + + "check that the TransformerSpec used by this adapter " + + "generates a public no-args constructor " + + "and that it doesn't throw", e); + } + } + + /** + * Returns the fully qualified name of the class inside {@code javaFile}, for example {@code "com.foo.bar.Type"}. + * @param javaFile a Java file containing a class + * @return the fully qualified name of the class + */ + private static String qualifiedName(final JavaFile javaFile) { + return javaFile.packageName + "." + javaFile.typeSpec.name; + } +} diff --git a/bull-transformer-generator/transformer-bytecode-adapter/src/main/java/com/expediagroup/beans/generator/bytecode/package-info.java b/bull-transformer-generator/transformer-bytecode-adapter/src/main/java/com/expediagroup/beans/generator/bytecode/package-info.java new file mode 100644 index 000000000..7ba75bf0a --- /dev/null +++ b/bull-transformer-generator/transformer-bytecode-adapter/src/main/java/com/expediagroup/beans/generator/bytecode/package-info.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Contains the bytecode adapter classes, which can compile the source code + * represented by a {@link com.expediagroup.beans.generator.core.TransformerSpec} at runtime, + * and create a new instance of the generated {@link com.expediagroup.beans.generator.core.Transformer}. + *

      + * All transformer models implement the {@link com.expediagroup.beans.generator.core.Transformer} interface. + * The mapping code model is created using {@link com.expediagroup.beans.generator.core.mapping.MappingCode}. + */ +package com.expediagroup.beans.generator.core; diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/TransformerSpecTest.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/TransformerSpecTest.java new file mode 100644 index 000000000..e1258beda --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/TransformerSpecTest.java @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.lang.reflect.Type; + +import org.testng.annotations.Test; + +import com.expediagroup.beans.generator.core.mapping.MappingCodeFactory; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; + +/** + * Test for {@link TransformerSpec}. + */ +public class TransformerSpecTest { + private static final TypeName I_TRANSFORMER = TypeName.get(Transformer.class); + + /** + * The class to be tested. + */ + private final TransformerSpec underTest = new TransformerSpec(MappingCodeFactory.newInstance()); + + /** + * Should be named after source and destination types. + */ + @Test + public void shouldBeNamedAfterSourceAndDestinationTypes() { + // WHEN + TypeSpec generated = underTest.build(Source.class, Destination.class); + + // THEN + assertThat(generated.name).as("Transformer name does not include source or destination types") + .isEqualTo("SourceToDestinationTransformer"); + } + + /** + * Should implement transformer interface. + */ + @Test + public void shouldImplementTransformerInterface() { + // WHEN + TypeSpec generated = underTest.build(Source.class, Destination.class); + + // THEN + assertThat(isATransformer(generated)) + .as("Transformer does not implement interface %s", I_TRANSFORMER) + .isTrue(); + assertThat(findTransformMethod(generated, Source.class, Destination.class)) + .as("Transformer does not implement method: Destination transform(Source)") + .isNotNull(); + } + + /** + * Checks that spec implements Transformer. + * @param spec a TypeSpec + * @return true if the spec implements Transformer + */ + private boolean isATransformer(final TypeSpec spec) { + return spec.superinterfaces + .stream() + .anyMatch(typeName -> + typeName instanceof ParameterizedTypeName + && ((ParameterizedTypeName) typeName).rawType.equals(I_TRANSFORMER)); + } + + private MethodSpec findTransformMethod(final TypeSpec transformer, final Type sourceClass, final Type destinationClass) { + return transformer.methodSpecs.stream() + .filter(methodSpec -> + methodSpec.name.equals("transform") + && methodSpec.parameters.get(0).type.equals(TypeName.get(sourceClass)) + && methodSpec.returnType.equals(TypeName.get(destinationClass))) + .findFirst() + .orElse(null); + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/BeanPropertyTest.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/BeanPropertyTest.java new file mode 100644 index 000000000..770d08363 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/BeanPropertyTest.java @@ -0,0 +1,137 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.mapping; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.lang.reflect.Method; + +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.expediagroup.beans.generator.core.sample.javabean.Source; + +/** + * Tests for {@link BeanProperty}. + */ +public class BeanPropertyTest { + /** + * The class to be tested. + */ + private BeanProperty underTest; + + @BeforeClass + public void beforeClass() throws NoSuchMethodException { + final Method getAnInt = Source.class.getDeclaredMethod("getAnInt"); + underTest = new BeanProperty(getAnInt); + } + + @Test + public void shouldBeEqualToPropertyWithSameName() throws NoSuchMethodException { + // GIVEN + var setAnInt = Source.class.getDeclaredMethod("setAnInt", int.class); + + // WHEN + boolean actual = underTest.equals(new BeanProperty(setAnInt)); + + // THEN + assertThat(actual).isTrue(); + } + + @Test + public void shouldBeEqualToPropertyWithSameNameFromShortPrefixMethod() throws NoSuchMethodException { + // GIVEN + var isABoolean = Source.class.getDeclaredMethod("isABoolean"); + var setABoolean = Source.class.getDeclaredMethod("setABoolean", boolean.class); + + // WHEN + boolean actual = new BeanProperty(isABoolean).equals(new BeanProperty(setABoolean)); + + // THEN + assertThat(actual).isTrue(); + } + + @Test + public void shouldBeEqualToSelf() { + // WHEN + boolean actual = underTest.equals(underTest); + + // THEN + assertThat(actual).isTrue(); + } + + @Test + public void shouldNotBeEqualToPropertyWithDifferentName() throws NoSuchMethodException { + // GIVEN + var getAString = Source.class.getDeclaredMethod("getAString"); + + // WHEN + boolean actual = underTest.equals(new BeanProperty(getAString)); + + // THEN + assertThat(actual).isFalse(); + } + + @Test + public void shouldNotBeEqualToNull() { + // WHEN + boolean actual = underTest.equals(null); + + // THEN + assertThat(actual).isFalse(); + } + + @Test + public void shouldNotBeEqualToOtherType() { + // GIVEN + Object other = new Object(); + + // WHEN + boolean actual = underTest.equals(other); + + // THEN + assertThat(actual).isFalse(); + } + + @Test + public void shouldHaveSameHashCodeAsPropertyWithSameName() throws NoSuchMethodException { + // GIVEN + var setAnInt = new BeanProperty(Source.class.getDeclaredMethod("setAnInt", int.class)); + + // WHEN + int actual = underTest.hashCode(); + + // THEN + assertThat(actual).isEqualTo(setAnInt.hashCode()); + } + + @Test + public void shouldHaveDifferentHashCodeFromPropertyWithDifferentName() throws NoSuchMethodException { + // GIVEN + var getAString = new BeanProperty(Source.class.getDeclaredMethod("getAString")); + + // WHEN + int actual = underTest.hashCode(); + + // THEN + assertThat(actual).isNotEqualTo(getAString.hashCode()); + } + + @Test + public void shouldReturnPropertyNameAsString() { + assertThat(underTest.toString()).isEqualTo("anInt"); + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/JavaBeanCodeTest.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/JavaBeanCodeTest.java new file mode 100644 index 000000000..3f07de6aa --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/JavaBeanCodeTest.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.mapping; + +import static java.lang.String.format; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.testng.annotations.Test; + +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; +import com.expediagroup.transformer.utils.ClassUtils; +import com.squareup.javapoet.CodeBlock; + +/** + * Tests for {@link JavaBeanCode}. + */ +public class JavaBeanCodeTest { + /** + * The class to be tested. + */ + private final JavaBeanCode underTest = new JavaBeanCode(Source.class, Destination.class, new ClassUtils()); + + @Test + public void shouldInstantiateAndReturnDestination() { + // WHEN + CodeBlock block = underTest.build(); + + // THEN + assertThat(block.toString()) + .contains(format("%1$s destination = new %1$s();", Destination.class.getName())) + .contains("return destination;"); + } + + @Test + public void shouldMapMatchingProperties() { + // WHEN + CodeBlock block = underTest.build(); + + // THEN + assertThat(block.toString()) + .contains("destination.setABoolean(source.isABoolean());") + .contains("destination.setAString(source.getAString());"); + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/MappingCodeFactoryTest.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/MappingCodeFactoryTest.java new file mode 100644 index 000000000..5f70d9fcc --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/MappingCodeFactoryTest.java @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.mapping; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +import static com.expediagroup.transformer.constant.ClassType.UNSUPPORTED; + +import org.apache.commons.lang3.NotImplementedException; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import com.expediagroup.beans.generator.core.sample.immutable.ImmutableDestination; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; +import com.expediagroup.beans.generator.core.sample.mixed.MixedDestination; +import com.expediagroup.transformer.utils.ClassUtils; + +/** + * Tests for {@link MappingCodeFactory}. + */ +public class MappingCodeFactoryTest { + /** + * The class to be tested. + */ + private final MappingCodeFactory underTest = MappingCodeFactory.newInstance(); + + @Test + public void shouldReturnAnInstanceForMutableDestination() { + // WHEN + var mappingCode = underTest.of(Source.class, Destination.class); + + // THEN + assertThat(mappingCode).isNotNull(); + } + + /** + * TODO: remove this test after implementation of immutable mapping code. + */ + @Test(expectedExceptions = NotImplementedException.class) + public void shouldFailForImmutableDestination() { + underTest.of(Source.class, ImmutableDestination.class); + } + + /** + * TODO: remove this test after implementation of mixed mapping code. + */ + @Test(expectedExceptions = NotImplementedException.class) + public void shouldFailForMixedDestination() { + underTest.of(Source.class, MixedDestination.class); + } + + @Test(expectedExceptions = AssertionError.class, expectedExceptionsMessageRegExp = ".*UNSUPPORTED.*") + public void shouldFailForUnsupportedDestinationType() { + // GIVEN + ClassUtils classUtils = given(mock(ClassUtils.class).getClassType(any())) + .willReturn(UNSUPPORTED) + .getMock(); + MappingCodeFactory underTest = MappingCodeFactory.newInstance(classUtils); + + // WHEN + underTest.of(Source.class, Destination.class); + } + + @Test(dataProvider = "typePairs", expectedExceptions = IllegalArgumentException.class) + public void shouldFailIfAnyTypeIsNull(final Class source, final Class destination) { + underTest.of(source, destination); + } + + @DataProvider + private Object[][] typePairs() { + return new Object[][]{ + {null, Object.class}, + {Object.class, null}, + {null, null} + }; + } + +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/package-info.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/package-info.java new file mode 100644 index 000000000..d72423ce5 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/mapping/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Tests for mapping code block models. + */ +package com.expediagroup.beans.generator.core.mapping; diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/package-info.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/package-info.java new file mode 100644 index 000000000..465fa1fc6 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Tests for generator core model. + */ +package com.expediagroup.beans.generator.core; diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/immutable/ImmutableDestination.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/immutable/ImmutableDestination.java new file mode 100644 index 000000000..12052db6e --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/immutable/ImmutableDestination.java @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.sample.immutable; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * Sample class that represents an immutable destination type. + */ +@RequiredArgsConstructor +@Getter +public class ImmutableDestination { + final boolean aBoolean; + final String aString; +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/immutable/package-info.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/immutable/package-info.java new file mode 100644 index 000000000..bd22d7ab6 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/immutable/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Sample immutable classes for testing purposes. + */ +package com.expediagroup.beans.generator.core.sample.immutable; diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/Destination.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/Destination.java new file mode 100644 index 000000000..049a268b8 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/Destination.java @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.sample.javabean; + +import lombok.Getter; +import lombok.Setter; + +/** + * Sample class that represents a mutable destination type. + */ +@Getter +@Setter +public class Destination { + boolean aBoolean; + String aString; +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/Source.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/Source.java new file mode 100644 index 000000000..2f339e4b0 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/Source.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.sample.javabean; + +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +/** + * Sample class that represents a transformer's source type. + */ +@Getter +@Setter +public class Source { + int anInt; + String aString; + boolean aBoolean; + List longList; +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/TransformerExample.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/TransformerExample.java new file mode 100644 index 000000000..dd1156f31 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/TransformerExample.java @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.sample.javabean; + +import com.expediagroup.beans.generator.core.Transformer; +import com.expediagroup.beans.generator.core.TransformerSpec; +import com.expediagroup.beans.generator.core.mapping.MappingCodeFactory; + +/** + * Example used as reference for the generated code. + */ +@SuppressWarnings("unused") +public final class TransformerExample implements Transformer { + @Override + public Destination transform(final Source source) { // 'final' required by Checkstyle, not part of the generated code + Destination destination = new Destination(); + destination.setABoolean(source.isABoolean()); + destination.setAString(source.getAString()); + return destination; + } + + /** + * Entry point for manual testing. + * Run this to compare transformer serialization with the above reference code. + * @param args the args + */ + public static void main(final String[] args) { + System.out.println(new TransformerSpec(MappingCodeFactory.newInstance()) + .build(Source.class, Destination.class)); + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/package-info.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/package-info.java new file mode 100644 index 000000000..66d909d1f --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/javabean/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Sample JavaBean mutable classes for testing purposes. + */ +package com.expediagroup.beans.generator.core.sample.javabean; diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/mixed/MixedDestination.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/mixed/MixedDestination.java new file mode 100644 index 000000000..282d17692 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/mixed/MixedDestination.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.sample.mixed; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; + +/** + * Sample class that represents a mixed destination type. + */ +@RequiredArgsConstructor +@Getter +@Setter +public class MixedDestination { + final String aString; + final Long aLong; + boolean aBoolean; +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/mixed/package-info.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/mixed/package-info.java new file mode 100644 index 000000000..f9c350b7c --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/beans/generator/core/sample/mixed/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Sample mixed classes for testing purposes. + */ +package com.expediagroup.beans.generator.core.sample.mixed; diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/transformer/constant/ClassType.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/transformer/constant/ClassType.java new file mode 100644 index 000000000..8b49fd3c4 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/transformer/constant/ClassType.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.transformer.constant; + +import com.expediagroup.transformer.utils.ClassUtils; + +/** + * Class type definition. + * Note: this is a copy of {@code ClassType} in module bull-common, + * modified to add a new constant for testing purposes. + * When this class is referenced from the test classpath it replaces the original one, + * letting us stub the return value of {@link ClassUtils#getClassType(java.lang.Class)}. + */ +public enum ClassType { + /** + * The class is mutable. + */ + MUTABLE, + /** + * The class is immutable. + */ + IMMUTABLE, + /** + * The class contains both final and not final fields. + */ + MIXED, + /** + * A new class type for testing purposes only. + */ + UNSUPPORTED; + + /** + * Checks if a the class type instance is equal to the given one. + * @param classType the {@link ClassType} to which compare + * @return true if this is equals to the given class type + */ + public boolean is(final ClassType classType) { + return this == classType; + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/transformer/constant/package-info.java b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/transformer/constant/package-info.java new file mode 100644 index 000000000..5386f7e18 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/test/java/com/expediagroup/transformer/constant/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Copy of {@code ClassType} in module bull-common, modified for testing purposes. + */ +package com.expediagroup.transformer.constant; diff --git a/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/SourceTransformerSpec.java b/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/SourceTransformerSpec.java new file mode 100644 index 000000000..a939af793 --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/SourceTransformerSpec.java @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.source; + +import java.time.Clock; + +import javax.annotation.processing.Generated; + +import com.expediagroup.beans.generator.core.Transformer; +import com.expediagroup.beans.generator.core.TransformerSpec; +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.TypeSpec; + +import lombok.AllArgsConstructor; +import lombok.NonNull; + +/** + * A decorator of {@link TransformerSpec} which adds useful Javadoc and metadata to the transformer model. + * It's used to generate readable source files. + */ +@AllArgsConstructor +public class SourceTransformerSpec { + /** + * The transformer model to decorate for producing a source file. + */ + @NonNull + private final TransformerSpec spec; + + /** + * The clock to use for marking generation timestamps. + */ + @NonNull + private final Clock clock; + + /** + * Decorate a transformer model with additional metadata. + * @param transformerSpec a transformer model + */ + public SourceTransformerSpec(final TransformerSpec transformerSpec) { + this(transformerSpec, Clock.systemUTC()); + } + + /** + * Build a transformer model to map from a {@code source} to {@code destination} type. + * The model also contains Javadoc and additional metadata. + * @param the source type + * @param the destination type + * @param source the source to read values from + * @param destination the destination where to map values + * @return a transformer model + * @see TransformerSpec#build(Class, Class) + */ + public TypeSpec build(final Class source, final Class destination) { + return spec.build(source, destination) + .toBuilder() + .addJavadoc(docFor(source, destination)) + .addAnnotation(AnnotationSpec.builder(Generated.class) + .addMember("value", getClass().getName()) + .addMember("date", clock.instant().toString()) + .build()) + .build(); + } + + /** + * Creates a Javadoc for the transformer implementation + * that includes {@code source} and {@code destination} references. + * @param source the source type + * @param destination the destination type + * @return a JavaDoc comment + */ + private CodeBlock docFor(final Class source, final Class destination) { + return CodeBlock.of( + "A {@link $T} that can map an instance of {@code $T} to a new instance of {@code $T}.", + Transformer.class, source, destination); + } +} diff --git a/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/TransformerFile.java b/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/TransformerFile.java new file mode 100644 index 000000000..fd3ed248f --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/TransformerFile.java @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.source; + +import static lombok.AccessLevel.PROTECTED; + +import java.io.IOException; +import java.nio.file.Path; + +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.TypeSpec; + +import lombok.AllArgsConstructor; + +/** + * A {@link com.expediagroup.beans.generator.core.Transformer} implementation source file. + * This file can be written on disk using {@link #write()} + * and contains all the data needed to perform this operation. + */ +@AllArgsConstructor(access = PROTECTED) +public final class TransformerFile { + /** + * The transformer source model. + */ + private final TypeSpec typeSpec; + + /** + * The path where to write the file and package directories. + */ + private final Path basePath; + + /** + * The Java package of this source file. + */ + private final String packageName; + + /** + * Write this source file and package directories to disk. + * Returns the path where the source is actually written. + * @return the path where this source is written + * @throws IOException if a write error occurs + */ + public Path write() throws IOException { + return JavaFile.builder(packageName, typeSpec) + .skipJavaLangImports(true) + .build() + .writeToPath(basePath); + } +} diff --git a/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/TransformerSourceAdapter.java b/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/TransformerSourceAdapter.java new file mode 100644 index 000000000..8d5573c6a --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/TransformerSourceAdapter.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.source; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import com.expediagroup.beans.generator.core.Transformer; +import com.expediagroup.beans.generator.core.TransformerSpec; + +import lombok.Builder; + +/** + * A source adapter for {@link TransformerSpec} that creates a readable source file + * representation from the model. + *
      + * This component is for internal usage in Bull, it's intended as a low-level wrapper + * for compile-time conversion of models. Clients should prefer higher level interfaces + * such as {@code TransformerRegistry}. + */ +@Builder +public class TransformerSourceAdapter { + /** + * The default source path if none is specified. + */ + static final Path DEFAULT_PATH = Paths.get("generated-sources/bull"); + + /** + * The default transformer package if none is specified. + */ + static final String DEFAULT_PACKAGE = Transformer.class.getPackageName(); + + /** + * The path where to write the generated transformer sources. + * The tree of package directories will start from this location. + */ + @Builder.Default + private final Path basePath = DEFAULT_PATH; + + /** + * The Java package to use for the generated transformer sources. + */ + @Builder.Default + private final String packageName = DEFAULT_PACKAGE; + + /** + * The Transformer model for generating source code. + */ + private final TransformerSpec spec; + + /** + * Create a new file containing the source of a {@link Transformer} from {@code source} to {@code destination}. + * @param
      the source type + * @param the destination type + * @param source the source class + * @param destination the destination class + * @return a new Transformer source file + */ + public TransformerFile newTransformerFile(final Class source, final Class destination) { + return new TransformerFile( + new SourceTransformerSpec(spec).build(source, destination), basePath, packageName + ); + } +} diff --git a/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/package-info.java b/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/package-info.java new file mode 100644 index 000000000..a95bc2d2c --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/main/java/com/expediagroup/beans/generator/source/package-info.java @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Contains the source adapter classes, which take the transformers generated from the Core module + * and decorate them to produce readable source file representations. + *

      + * The main class is {@link com.expediagroup.beans.generator.source.TransformerSourceAdapter} that + * converts the source code represented by {@link com.expediagroup.beans.generator.core.TransformerSpec} + * into a {@link com.expediagroup.beans.generator.source.TransformerFile}, which encapsulates all the information + * to write that file on disk at a later time. + *

      + * This component is for internal usage in Bull, as it's intended as a low-level wrapper + * for compile-time conversion of models. Use it directly only if you need to customize the compile-time + * transformation and writing of models or, for example, if you need to implement a command-line utility. + * Clients should prefer higher level interfaces such as {@code TransformerRegistry}. + */ +package com.expediagroup.beans.generator.source; diff --git a/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/SourceTransformerSpecTest.java b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/SourceTransformerSpecTest.java new file mode 100644 index 000000000..a18a9b10b --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/SourceTransformerSpecTest.java @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.source; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.assertj.core.util.Lists.list; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; + +import javax.annotation.processing.Generated; + +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.expediagroup.beans.generator.core.TransformerSpec; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; + +/** + * Tests for {@link SourceTransformerSpec}. + */ +public class SourceTransformerSpecTest { + private final TypeSpec generated = TypeSpec.classBuilder("AtoBTransformer").build(); + + @Spy + private final Clock clock = Clock.fixed(Instant.EPOCH, ZoneId.systemDefault()); + + @Mock + private TransformerSpec spec; + + @InjectMocks + private SourceTransformerSpec sourceTransformerSpec; + + @BeforeMethod + public void setUp() { + MockitoAnnotations.openMocks(this); + when(spec.build(any(), any())).thenReturn(generated); + } + + @AfterMethod + public void tearDown() { + sourceTransformerSpec = null; + } + + @Test + public void shouldDecorateATransformerSpec() { + // WHEN + TypeSpec sourceModel = sourceTransformerSpec.build(Source.class, Destination.class); + + // THEN + assertSoftly(softly -> { + softly.assertThat(sourceModel.name).as("Name is unchanged").isEqualTo(generated.name); + softly.assertThat(sourceModel.javadoc.isEmpty()).as("Adds a Javadoc").isFalse(); + softly.assertThat(sourceModel.annotations).as("Adds a @Generated annotation") + .anyMatch(annotationSpec -> annotationSpec.type.equals(TypeName.get(Generated.class))); + }); + } + + @Test + public void shouldAnnotateGeneratedSourceWithTimestamp() { + // WHEN + TypeSpec sourceModel = sourceTransformerSpec.build(Source.class, Destination.class); + + // THEN + var expectedTimeStamp = list(CodeBlock.of(clock.instant().toString())); + assertThat(sourceModel.annotations) + .anyMatch(annotationSpec -> annotationSpec.members.containsValue(expectedTimeStamp)); + } + + @Test + public void shouldFailIfSpecIsNull() { + // WHEN + ThrowingCallable code = () -> new SourceTransformerSpec(null); + + // THEN + assertThatThrownBy(code).isInstanceOf(NullPointerException.class); + } + + @Test + public void shouldFailIfClockIsNull() { + // WHEN + ThrowingCallable code = () -> new SourceTransformerSpec(spec, null); + + // THEN + assertThatThrownBy(code).isInstanceOf(NullPointerException.class); + } +} diff --git a/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/TransformerFileTest.java b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/TransformerFileTest.java new file mode 100644 index 000000000..e5c375afe --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/TransformerFileTest.java @@ -0,0 +1,97 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.source; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.jimfs.Configuration; +import com.google.common.jimfs.Jimfs; +import com.squareup.javapoet.TypeSpec; + +/** + * Tests for {@link TransformerFile}. + */ +public class TransformerFileTest { + + private static final String DEFAULT_PACKAGE = ""; + + private final FileSystem fs = Jimfs.newFileSystem(Configuration.unix()); + + private final TypeSpec generated = TypeSpec.classBuilder("Generated").build(); + + private final String generatedFileName = generated.name + ".java"; + + private Path outputDir; + + @BeforeClass + public void setUp() throws IOException { + outputDir = fs.getPath("/out"); + Files.createDirectory(outputDir); + } + + @Test + public void shouldWriteSourceInDefaultPackage() throws IOException { + // GIVEN + TransformerFile transformerFile = new TransformerFile(generated, outputDir, DEFAULT_PACKAGE); + + // WHEN + Path generatedSource = transformerFile.write(); + + // THEN + assertThat(generatedSource).startsWith(outputDir) + .hasFileName(generatedFileName) + .hasContent(generated.toString()); + } + + @Test + public void shouldWriteSourceInsidePackage() throws IOException { + // GIVEN + String packageName = "com.foo.bar"; + TransformerFile transformerFile = new TransformerFile(generated, outputDir, packageName); + + // WHEN + Path generatedSource = transformerFile.write(); + + // THEN + String expectedContent = String.format("package %s;\n\n%s", packageName, generated); + assertThat(generatedSource).startsWith(outputDir.resolve("com/foo/bar/")) + .hasFileName(generatedFileName) + .hasContent(expectedContent); + } + + @Test + public void shouldFailWriteIfDirectoryDoesNotExist() { + // GIVEN + Path nonExistent = fs.getPath("/non/existent"); + TransformerFile transformerFile = new TransformerFile(generated, nonExistent, DEFAULT_PACKAGE); + + // WHEN + ThrowingCallable code = transformerFile::write; + + // THEN + assertThatThrownBy(code).isInstanceOf(IOException.class); + } +} diff --git a/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/TransformerSourceAdapterTest.java b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/TransformerSourceAdapterTest.java new file mode 100644 index 000000000..7481677b6 --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/TransformerSourceAdapterTest.java @@ -0,0 +1,82 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.source; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.when; + +import java.nio.file.Paths; + +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.expediagroup.beans.generator.core.TransformerSpec; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; +import com.squareup.javapoet.TypeSpec; + +/** + * Tests for {@link TransformerSourceAdapter}. + */ +public class TransformerSourceAdapterTest { + private final TypeSpec generated = TypeSpec.classBuilder("AtoBTransformer").build(); + + @Mock + private TransformerSpec spec; + + @BeforeMethod + public void setUp() { + MockitoAnnotations.openMocks(this); + when(spec.build(any(), any())).thenReturn(generated); + } + + @Test + public void shouldCreateNewTransformerFile() { + // GIVEN + var basePath = Paths.get("./target"); + var packageName = "foo.bar"; + var transformerSourceAdapter = TransformerSourceAdapter.builder() + .basePath(basePath) + .packageName(packageName) + .spec(spec) + .build(); + + // WHEN + TransformerFile result = transformerSourceAdapter.newTransformerFile(Source.class, Destination.class); + + // THEN + assertThat(result).extracting("basePath", "packageName") + .containsExactly(basePath, packageName); + } + + @Test + public void shouldCreateNewTransformerFileWithDefaultValues() { + // GIVEN + var transformerSourceAdapter = TransformerSourceAdapter.builder() + .spec(spec) + .build(); + + // WHEN + TransformerFile result = transformerSourceAdapter.newTransformerFile(Source.class, Destination.class); + + // THEN + assertThat(result).extracting("basePath", "packageName") + .containsExactly(TransformerSourceAdapter.DEFAULT_PATH, TransformerSourceAdapter.DEFAULT_PACKAGE); + } +} diff --git a/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/package-info.java b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/package-info.java new file mode 100644 index 000000000..ebdd07e56 --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Tests for the source adapter. + */ +package com.expediagroup.beans.generator.source; diff --git a/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/sample/TransformerSourceAdapterExample.java b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/sample/TransformerSourceAdapterExample.java new file mode 100644 index 000000000..d8b1e1a7d --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/sample/TransformerSourceAdapterExample.java @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.source.sample; + +import static lombok.AccessLevel.PRIVATE; + +import java.io.IOException; + +import com.expediagroup.beans.generator.core.TransformerSpec; +import com.expediagroup.beans.generator.core.mapping.MappingCodeFactory; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; +import com.expediagroup.beans.generator.source.TransformerSourceAdapter; + +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * Example of generating and using a Transformer at runtime. + */ +@Slf4j +@NoArgsConstructor(access = PRIVATE) +public final class TransformerSourceAdapterExample { + /** + * Entry point for manual testing. + * Run this to compare the usage of a generated transformer with the above reference result. + * @param args the args + */ + public static void main(final String[] args) { + // create a transformer model + var spec = new TransformerSpec(MappingCodeFactory.newInstance()); + // create a bytecode adapter for the model + // with default destination path and Java package + var source = TransformerSourceAdapter.builder() + .spec(spec) + .build(); + // generate a new Transformer source file + var transformerFile = source.newTransformerFile(Source.class, Destination.class); + // write file to disk + try { + var sourcePath = transformerFile.write(); + log.info("find generated source at: {}", sourcePath.toAbsolutePath()); + } catch (IOException e) { + log.error("could not write source: {}", e.getMessage(), e); + } + } +} diff --git a/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/sample/package-info.java b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/sample/package-info.java new file mode 100644 index 000000000..30222eabd --- /dev/null +++ b/bull-transformer-generator/transformer-source-adapter/src/test/java/com/expediagroup/beans/generator/source/sample/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Example usage of the source adapter. + */ +package com.expediagroup.beans.generator.source.sample; diff --git a/pom.xml b/pom.xml index 71d884a79..69c6cf13b 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.5.2 0.12 github - 3.12.1 + 3.12.0 [3.8.1,) 3.0.1 From 5ff19ad4f21c9d5bbc72ca64749c5c9acf66e71c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Sat, 6 Aug 2022 18:39:24 +0200 Subject: [PATCH 1666/1786] Adds the maven enforcer plugin --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 69c6cf13b..d9f6f9a5c 100644 --- a/pom.xml +++ b/pom.xml @@ -89,6 +89,7 @@ 3.0.0-M4 1.6.13 3.1.2 + 3.1.0 false @@ -690,6 +691,7 @@ org.apache.maven.plugins maven-enforcer-plugin + ${maven-enforcer-plugin.version} enforce-maven From 99900dee31bcfb7cf3447cfce2b6561685da74cc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Aug 2022 07:17:35 +0200 Subject: [PATCH 1667/1786] changing dependabot time schedule --- .github/dependabot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 09d69c1d3..b98ff0ad3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,8 +6,7 @@ updates: directory: "/" schedule: interval: "daily" - time: "12:00" - timezone: "Etc/UTC" + time: "11:00" # UTC target-branch: develop reviewers: - fborriello @@ -20,6 +19,7 @@ updates: directory: "/" schedule: interval: daily + time: "11:00" # UTC open-pull-requests-limit: 10 target-branch: develop reviewers: From 6d099becb823254d738cf47219d980f0391e602d Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Aug 2022 07:18:43 +0200 Subject: [PATCH 1668/1786] changing dependabot time schedule --- .github/dependabot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b98ff0ad3..7fbc72952 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,7 +6,7 @@ updates: directory: "/" schedule: interval: "daily" - time: "11:00" # UTC + time: "11:00" # Check for npm updates at 11am UTC target-branch: develop reviewers: - fborriello @@ -19,7 +19,7 @@ updates: directory: "/" schedule: interval: daily - time: "11:00" # UTC + time: "11:00" # Check for npm updates at 11am UTC open-pull-requests-limit: 10 target-branch: develop reviewers: From 824afcf50154e2f386186dfb5d2a329b28654e77 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Aug 2022 08:02:56 +0200 Subject: [PATCH 1669/1786] changing dependabot time schedule --- .github/dependabot.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7fbc72952..1d348f85a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,7 +6,8 @@ updates: directory: "/" schedule: interval: "daily" - time: "11:00" # Check for npm updates at 11am UTC + time: "11:00" + timezone: "UTC" target-branch: develop reviewers: - fborriello @@ -19,7 +20,8 @@ updates: directory: "/" schedule: interval: daily - time: "11:00" # Check for npm updates at 11am UTC + time: "11:00" + timezone: "UTC" open-pull-requests-limit: 10 target-branch: develop reviewers: From 38fa2e98325c6284ca1dd91817c0ad87c273205e Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Aug 2022 08:03:19 +0200 Subject: [PATCH 1670/1786] changing dependabot time schedule --- .github/dependabot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1d348f85a..5900aef05 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,7 +6,7 @@ updates: directory: "/" schedule: interval: "daily" - time: "11:00" + time: "11:30" timezone: "UTC" target-branch: develop reviewers: @@ -20,7 +20,7 @@ updates: directory: "/" schedule: interval: daily - time: "11:00" + time: "11:30" timezone: "UTC" open-pull-requests-limit: 10 target-branch: develop From 052c18bc49d6d85f2fe3b31dd026373056102c77 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Aug 2022 08:28:07 +0200 Subject: [PATCH 1671/1786] Tryies a different approach for retrieving the coverall token --- .github/workflows/github-default-actions.yml | 2 +- .github/workflows/github-default-jdk11-actions.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 4ea022612..7a1bcaca9 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -59,7 +59,7 @@ jobs: timeout_minutes: 5 retry_on: error command: | - mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode + mvn verify jacoco:report-aggregate coveralls:report -D repoToken=${{ secrets.COVERALLS_TOKEN }} sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode security-check: name: "Security check" runs-on: ubuntu-latest diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 6c77f1d3c..0dc7b52b2 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -53,7 +53,7 @@ jobs: timeout_minutes: 5 retry_on: error command: | - mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode + mvn verify jacoco:report-aggregate coveralls:report -D repoToken=${{ secrets.COVERALLS_TOKEN }} sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From bac6be8f18ce38a7e36d41ce04d59f7ea9a05c59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Aug 2022 08:35:04 +0200 Subject: [PATCH 1672/1786] Bump actions/cache from 3.0.4 to 3.0.4 (#337) * Bump actions/cache from 3.0.4 to 3.0.6 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.4 to 3.0.6. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.4...v3.0.6) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * downgrade the version to test the dependabot config Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello Co-authored-by: Fabio Borriello --- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index e612a3dbf..a9ee1323e 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 5ff806d2e..f79a689ed 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From ef2fa2c02399902b547d77c8d219b8b2228a3e49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Aug 2022 08:35:36 +0200 Subject: [PATCH 1673/1786] Bump maven-site-plugin from 3.12.0 to 3.12.1 (#338) Bumps [maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.12.0 to 3.12.1. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.12.0...maven-site-plugin-3.12.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d9f6f9a5c..0b8612395 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.5.2 0.12 github - 3.12.0 + 3.12.1 [3.8.1,) 3.0.1 From 37adbc7841cd804acc364cb19bdec98d0abaa3ba Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Aug 2022 14:10:42 +0200 Subject: [PATCH 1674/1786] Tryies a different approach for retrieving the coverall token --- .github/workflows/github-default-actions.yml | 4 ++-- .github/workflows/github-default-jdk11-actions.yml | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 7a1bcaca9..bb34fdc24 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -53,13 +53,13 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} - COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + COVERALLS_IO_TOKEN: ${{ secrets.COVERALLS_IO_TOKEN }} with: max_attempts: 3 timeout_minutes: 5 retry_on: error command: | - mvn verify jacoco:report-aggregate coveralls:report -D repoToken=${{ secrets.COVERALLS_TOKEN }} sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode + mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_IO_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode security-check: name: "Security check" runs-on: ubuntu-latest diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 0dc7b52b2..c75b33c66 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -48,18 +48,18 @@ jobs: distribution: 'adopt' - name: "Test and Quality check" uses: nick-invision/retry@v2 - with: - max_attempts: 3 - timeout_minutes: 5 - retry_on: error - command: | - mvn verify jacoco:report-aggregate coveralls:report -D repoToken=${{ secrets.COVERALLS_TOKEN }} sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode env: SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SOURCE_BRANCH: ${{ steps.build_info.outputs.SOURCE_BRANCH }} - COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + COVERALLS_IO_TOKEN: ${{ secrets.COVERALLS_IO_TOKEN }} + with: + max_attempts: 3 + timeout_minutes: 5 + retry_on: error + command: | + mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_IO_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode security-check: name: "Security check" runs-on: ubuntu-latest From 9216c2e18eb9ca8bb5a51e157553c64bb46316bd Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Aug 2022 14:11:34 +0200 Subject: [PATCH 1675/1786] Tryies a different approach for retrieving the coverall token --- .github/workflows/github-default-actions.yml | 2 +- .github/workflows/github-default-jdk11-actions.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index bb34fdc24..79a674177 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -56,7 +56,7 @@ jobs: COVERALLS_IO_TOKEN: ${{ secrets.COVERALLS_IO_TOKEN }} with: max_attempts: 3 - timeout_minutes: 5 + timeout_minutes: 8 retry_on: error command: | mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_IO_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index c75b33c66..579851104 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -56,7 +56,7 @@ jobs: COVERALLS_IO_TOKEN: ${{ secrets.COVERALLS_IO_TOKEN }} with: max_attempts: 3 - timeout_minutes: 5 + timeout_minutes: 8 retry_on: error command: | mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_IO_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode From 6521a98a08e415d54ae3016b90f120cb668c8fce Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 8 Aug 2022 14:12:32 +0200 Subject: [PATCH 1676/1786] Tryies a different approach for retrieving the coverall token --- .github/workflows/github-default-actions.yml | 2 +- .github/workflows/github-default-jdk11-actions.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 79a674177..2aadae3d0 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -56,7 +56,7 @@ jobs: COVERALLS_IO_TOKEN: ${{ secrets.COVERALLS_IO_TOKEN }} with: max_attempts: 3 - timeout_minutes: 8 + timeout_minutes: 10 retry_on: error command: | mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_IO_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 579851104..3c747e779 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -56,7 +56,7 @@ jobs: COVERALLS_IO_TOKEN: ${{ secrets.COVERALLS_IO_TOKEN }} with: max_attempts: 3 - timeout_minutes: 8 + timeout_minutes: 10 retry_on: error command: | mvn verify jacoco:report-aggregate coveralls:report -D repoToken=$COVERALLS_IO_TOKEN sonar:sonar -D sonar.projectKey=BULL -D sonar.organization=$SONAR_ORGANIZATION -D sonar.host.url=https://sonarcloud.io -D sonar.login=$SONAR_TOKEN -D sonar.branch.name=$SOURCE_BRANCH -P compatibility-mode From 78cfc1ab096ad57bde4c8d640a108329654549e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Aug 2022 14:25:01 +0200 Subject: [PATCH 1677/1786] Bump actions/cache from 3.0.4 to 3.0.6 (#339) Bumps [actions/cache](https://github.com/actions/cache) from 3.0.4 to 3.0.6. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.4...v3.0.6) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 2aadae3d0..f3c11e0ab 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 3c747e779..95e9fe91a 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index a9ee1323e..e612a3dbf 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index f79a689ed..5ff806d2e 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.4 + uses: actions/cache@v3.0.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From a6aec4d8521aa7d2fbed43a3ac8147066bc01e5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Aug 2022 18:05:03 +0200 Subject: [PATCH 1678/1786] Bump actions/cache from 3.0.6 to 3.0.7 (#340) * Bump actions/cache from 3.0.6 to 3.0.7 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.6 to 3.0.7. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.6...v3.0.7) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index f3c11e0ab..9d76de3b1 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.7 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.7 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.7 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 95e9fe91a..85f03d7e5 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.7 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.7 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.7 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index e612a3dbf..25f14e225 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.7 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 5ff806d2e..12f1fe151 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.6 + uses: actions/cache@v3.0.7 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 7dec52b78791b2b388dee87c83753fa9aa7d9812 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Aug 2022 18:05:37 +0200 Subject: [PATCH 1679/1786] Bump mockito-core from 4.6.1 to 4.7.0 (#342) * Bump mockito-core from 4.6.1 to 4.7.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 4.6.1 to 4.7.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.6.1...v4.7.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0b8612395..2483fe91a 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.6.1 + 4.7.0 7.6.1 3.23.1 From 5805e8d6af2c444100df6d5fc67d017bfe4fd976 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Aug 2022 18:05:58 +0200 Subject: [PATCH 1680/1786] Bump maven-javadoc-plugin from 3.4.0 to 3.4.1 (#341) * Bump maven-javadoc-plugin from 3.4.0 to 3.4.1 Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.4.0 to 3.4.1. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.4.0...maven-javadoc-plugin-3.4.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2483fe91a..778d354a9 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ [3.8.1,) 3.0.1 - 3.4.0 + 3.4.1 3.1.2 2.11.0 10.3.2 From 1f6dc95c19999d3cdbe5f9246ff6c7edbcdefbea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Aug 2022 14:29:23 +0200 Subject: [PATCH 1681/1786] Bump slf4j-api from 1.7.36 to 2.0.0 (#343) * Bump slf4j-api from 1.7.36 to 2.0.0 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.36 to 2.0.0. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.36...v_2.0.0) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 778d354a9..3f2a9f5d2 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.4.Final 3.5.0.Final 2.2.1.Final - 1.7.36 + 2.0.0 3.0.0 0.8.8 From da75e9c3679a7866154c8ed39d8ee0226f6cf474 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Aug 2022 14:29:36 +0200 Subject: [PATCH 1682/1786] Bump actions/cache from 3.0.7 to 3.0.8 (#344) * Bump actions/cache from 3.0.7 to 3.0.8 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.7 to 3.0.8. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.7...v3.0.8) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 9d76de3b1..20d9cce11 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.7 + uses: actions/cache@v3.0.8 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.7 + uses: actions/cache@v3.0.8 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.7 + uses: actions/cache@v3.0.8 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 85f03d7e5..49c10454e 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.7 + uses: actions/cache@v3.0.8 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.7 + uses: actions/cache@v3.0.8 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.7 + uses: actions/cache@v3.0.8 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 25f14e225..3d893949b 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.7 + uses: actions/cache@v3.0.8 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 12f1fe151..e27cce03d 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.7 + uses: actions/cache@v3.0.8 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 3639a1d1c9b7cdb3936647ec3e70169c2644bda2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Aug 2022 18:51:00 +0200 Subject: [PATCH 1683/1786] Bump maven-checkstyle-plugin from 3.1.2 to 3.2.0 (#345) * Bump maven-checkstyle-plugin from 3.1.2 to 3.2.0 Bumps [maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.1.2 to 3.2.0. - [Release notes](https://github.com/apache/maven-checkstyle-plugin/releases) - [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.1.2...maven-checkstyle-plugin-3.2.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3f2a9f5d2..f2511dfcf 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ [3.8.1,) 3.0.1 3.4.1 - 3.1.2 + 3.2.0 2.11.0 10.3.2 3.0.0-M4 From d1cb421efcc83c20668d27ed23f3c2353883cd47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Aug 2022 18:25:17 +0200 Subject: [PATCH 1684/1786] Bump checkstyle from 10.3.2 to 10.3.3 (#346) * Bump checkstyle from 10.3.2 to 10.3.3 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.3.2 to 10.3.3. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.3.2...checkstyle-10.3.3) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f2511dfcf..6bd56f1bc 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.4.1 3.2.0 2.11.0 - 10.3.2 + 10.3.3 3.0.0-M4 1.6.13 3.1.2 From ad260296dde55d7ff16ac04c4f138ecbc016bc90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Sep 2022 15:52:57 +0200 Subject: [PATCH 1685/1786] Bump versions-maven-plugin from 2.11.0 to 2.12.0 (#349) * Bump versions-maven-plugin from 2.11.0 to 2.12.0 Bumps [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) from 2.11.0 to 2.12.0. - [Release notes](https://github.com/mojohaus/versions-maven-plugin/releases) - [Changelog](https://github.com/mojohaus/versions-maven-plugin/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions-maven-plugin/compare/versions-maven-plugin-2.11.0...versions-maven-plugin-2.12.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6bd56f1bc..2a8fe31fa 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.0.1 3.4.1 3.2.0 - 2.11.0 + 2.12.0 10.3.3 3.0.0-M4 1.6.13 From 82c131b9104a80024f3d454d7c17d5151881dd48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Sep 2022 04:53:24 +0000 Subject: [PATCH 1686/1786] Bump mockito-core from 4.7.0 to 4.8.0 (#350) * Bump mockito-core from 4.7.0 to 4.8.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 4.7.0 to 4.8.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.7.0...v4.8.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2a8fe31fa..13022f4d2 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.7.0 + 4.8.0 7.6.1 3.23.1 From 7a546f0165250fa7cc839fb1191b01b45e9e7bbc Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Fri, 9 Sep 2022 16:01:13 +0200 Subject: [PATCH 1687/1786] updates the code style rules --- config/ide/intellij/BULLCodeStyle.xml | 28 ++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/config/ide/intellij/BULLCodeStyle.xml b/config/ide/intellij/BULLCodeStyle.xml index 3fd083cbb..62800778f 100644 --- a/config/ide/intellij/BULLCodeStyle.xml +++ b/config/ide/intellij/BULLCodeStyle.xml @@ -1,4 +1,4 @@ - + + + + + + + + + \ No newline at end of file From cbeb5ce007da5fd655d8bbb358bed4ea2d9e6a1d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Sep 2022 14:22:00 +0200 Subject: [PATCH 1688/1786] Bump hibernate-validator from 6.2.4.Final to 6.2.5.Final (#352) * Bump hibernate-validator from 6.2.4.Final to 6.2.5.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.2.4.Final to 6.2.5.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/6.2.5.Final/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.2.4.Final...6.2.5.Final) --- updated-dependencies: - dependency-name: org.hibernate.validator:hibernate-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 13022f4d2..aceaf48d3 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 7.6.1 3.23.1 - 6.2.4.Final + 6.2.5.Final 3.5.0.Final 2.2.1.Final 2.0.0 From 40dd13c5926915a4e6bbd6645067d7f867d88b86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Sep 2022 08:20:45 +0200 Subject: [PATCH 1689/1786] Bump slf4j-api from 2.0.0 to 2.0.1 (#353) * Bump slf4j-api from 2.0.0 to 2.0.1 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.0...v_2.0.1) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aceaf48d3..efa2152d5 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.5.Final 3.5.0.Final 2.2.1.Final - 2.0.0 + 2.0.1 3.0.0 0.8.8 From eab34899a12d2fc57355c0866be4c6cad0894dcb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 14:16:31 +0200 Subject: [PATCH 1690/1786] Bump slf4j-api from 2.0.1 to 2.0.2 (#354) * Bump slf4j-api from 2.0.1 to 2.0.2 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 2.0.1 to 2.0.2. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/commits) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index efa2152d5..5c06eb74f 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.5.Final 3.5.0.Final 2.2.1.Final - 2.0.1 + 2.0.2 3.0.0 0.8.8 From 754a9976a9cfa22ee8cd699e8fa89767d3df3a2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 12:51:39 +0000 Subject: [PATCH 1691/1786] Bump checkstyle from 10.3.3 to 10.3.4 (#355) * Bump checkstyle from 10.3.3 to 10.3.4 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.3.3 to 10.3.4. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.3.3...checkstyle-10.3.4) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5c06eb74f..46a744dd3 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.4.1 3.2.0 2.12.0 - 10.3.3 + 10.3.4 3.0.0-M4 1.6.13 3.1.2 From edbd0b085baccc139e454a7429a854ea4d220f8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Sep 2022 05:59:27 -0700 Subject: [PATCH 1692/1786] Bump slf4j-api from 2.0.2 to 2.0.3 (#356) * Bump slf4j-api from 2.0.2 to 2.0.3 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 2.0.2 to 2.0.3. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.2...v_2.0.3) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 46a744dd3..b0993a664 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.5.Final 3.5.0.Final 2.2.1.Final - 2.0.2 + 2.0.3 3.0.0 0.8.8 From e6b6063a1bc34244aa514d54e866123c3da587b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 18:39:33 +0200 Subject: [PATCH 1693/1786] Bump actions/cache from 3.0.8 to 3.0.9 (#357) * Bump actions/cache from 3.0.8 to 3.0.9 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.8 to 3.0.9. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.8...v3.0.9) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 20d9cce11..55f9e2bcc 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 49c10454e..a4731b2ff 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 3d893949b..ee2d8c33e 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index e27cce03d..f93377a3a 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From dc336b5cd04e03392161ea56499b6c58d0921d0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 15:13:12 +0200 Subject: [PATCH 1694/1786] Bump actions/cache from 3.0.9 to 3.0.10 (#358) * Bump actions/cache from 3.0.9 to 3.0.10 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.9 to 3.0.10. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.9...v3.0.10) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 55f9e2bcc..7afae3cf1 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index a4731b2ff..b59df8211 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index ee2d8c33e..533d523ef 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index f93377a3a..65bed85a2 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From a29b685a518a2817af72791a13f94667688d2629 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Oct 2022 07:25:32 +0200 Subject: [PATCH 1695/1786] Bump actions/cache from 3.0.10 to 3.0.11 (#359) * Bump actions/cache from 3.0.10 to 3.0.11 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.10 to 3.0.11. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.10...v3.0.11) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 7afae3cf1..8efeea97c 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.10 + uses: actions/cache@v3.0.11 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.10 + uses: actions/cache@v3.0.11 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.10 + uses: actions/cache@v3.0.11 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index b59df8211..6bcc451c6 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.10 + uses: actions/cache@v3.0.11 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.10 + uses: actions/cache@v3.0.11 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.10 + uses: actions/cache@v3.0.11 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 533d523ef..d50daad9c 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.10 + uses: actions/cache@v3.0.11 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 65bed85a2..99948e7bd 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.10 + uses: actions/cache@v3.0.11 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 1e491f03d1ba6ce65e23d5788c48b0e3ad425d6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Oct 2022 11:59:24 +0000 Subject: [PATCH 1696/1786] Bump mockito-core from 4.8.0 to 4.8.1 (#361) * Bump mockito-core from 4.8.0 to 4.8.1 Bumps [mockito-core](https://github.com/mockito/mockito) from 4.8.0 to 4.8.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.8.0...v4.8.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b0993a664..d1c165310 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.8.0 + 4.8.1 7.6.1 3.23.1 From cf0da48051a3ed2e9f5d72e29e20df8cb557aadc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Oct 2022 12:02:42 +0000 Subject: [PATCH 1697/1786] Bump versions-maven-plugin from 2.12.0 to 2.13.0 (#360) * Bump versions-maven-plugin from 2.12.0 to 2.13.0 Bumps [versions-maven-plugin](https://github.com/mojohaus/versions-maven-plugin) from 2.12.0 to 2.13.0. - [Release notes](https://github.com/mojohaus/versions-maven-plugin/releases) - [Changelog](https://github.com/mojohaus/versions-maven-plugin/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions-maven-plugin/compare/versions-maven-plugin-2.12.0...2.13.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d1c165310..d72fd60fc 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.0.1 3.4.1 3.2.0 - 2.12.0 + 2.13.0 10.3.4 3.0.0-M4 1.6.13 From bbd69c22a35eae3277aae98e5d956a45f7daeebb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 11:26:51 +0000 Subject: [PATCH 1698/1786] Bump checkstyle from 10.3.4 to 10.4 (#362) * Bump checkstyle from 10.3.4 to 10.4 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.3.4 to 10.4. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.3.4...checkstyle-10.4) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d72fd60fc..aa8139df2 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.4.1 3.2.0 2.13.0 - 10.3.4 + 10.4 3.0.0-M4 1.6.13 3.1.2 From a9fe9d7b7960f9273933ee80a58d415cb63488f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Nov 2022 11:46:50 +0000 Subject: [PATCH 1699/1786] Bump mockito-core from 4.8.1 to 4.9.0 (#363) * Bump mockito-core from 4.8.1 to 4.9.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 4.8.1 to 4.9.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.8.1...v4.9.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aa8139df2..4ea68282d 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.8.1 + 4.9.0 7.6.1 3.23.1 From ec44e0ed34e3a3057c464640e9703dfe3634e646 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Nov 2022 11:10:38 +0000 Subject: [PATCH 1700/1786] Bump slf4j-api from 2.0.3 to 2.0.4 (#364) * Bump slf4j-api from 2.0.3 to 2.0.4 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 2.0.3 to 2.0.4. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.3...v_2.0.4) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ea68282d..e4d7ba755 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.5.Final 3.5.0.Final 2.2.1.Final - 2.0.3 + 2.0.4 3.0.0 0.8.8 From 62483020efaac24d6571c7451e3549c6af71e5d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Nov 2022 12:05:28 +0000 Subject: [PATCH 1701/1786] Bump slf4j-api from 2.0.4 to 2.0.5 (#366) * Bump slf4j-api from 2.0.4 to 2.0.5 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 2.0.4 to 2.0.5. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.4...v_2.0.5) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e4d7ba755..c11ca0028 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 6.2.5.Final 3.5.0.Final 2.2.1.Final - 2.0.4 + 2.0.5 3.0.0 0.8.8 From c69cd7d6235ab4ae89f05ccdcb3f0b5a51f76513 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Nov 2022 12:42:59 +0000 Subject: [PATCH 1702/1786] Bump checkstyle from 10.4 to 10.5.0 (#365) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.4 to 10.5.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.4...checkstyle-10.5.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c11ca0028..df4cfe9f1 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.4.1 3.2.0 2.13.0 - 10.4 + 10.5.0 3.0.0-M4 1.6.13 3.1.2 From de35ea1b88de2a19278796779f70223a0dfc11c1 Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Thu, 1 Dec 2022 12:00:43 +0100 Subject: [PATCH 1703/1786] Add new feature to transform an object as is (#367) * replaces javax with jakarta * Add the possibility to customize the special types * adds the missing dependency * Reaches the required coverage * prepare the release * prepare the release * minor: changelog cleanup * [maven-release-plugin] prepare release 2.2.3 * [maven-release-plugin] prepare for next development iteration Co-authored-by: Fabio Borriello --- CHANGELOG-JDK11.md | 4 ++- CHANGELOG.md | 4 +++ README.md | 25 +++++++++++++ bull-bean-transformer/pom.xml | 2 +- bull-bom/pom.xml | 2 +- bull-common/pom.xml | 9 +++-- .../transformer/utils/ClassUtils.java | 33 ++++++++++++----- .../transformer/validator/Validator.java | 2 +- .../transformer/validator/ValidatorImpl.java | 18 +++++----- .../sample/immutable/ImmutableToFoo.java | 2 +- .../ImmutableToFooCustomAnnotation.java | 2 +- .../immutable/ImmutableToFooDiffFields.java | 2 +- ...ImmutableToFooMissingCustomAnnotation.java | 2 +- .../immutable/ImmutableToFooSubClass.java | 2 +- .../ImmutableToSubFooCustomAnnotation.java | 2 +- .../beans/sample/mixed/MixedToFoo.java | 2 +- .../MixedToFooMissingAllArgsConstructor.java | 2 +- .../mixed/MixedToFooMissingConstructor.java | 2 +- .../transformer/utils/ClassUtilsTest.java | 36 +++++++++++++++++-- .../utils/ReflectionUtilsTest.java | 4 +-- bull-converter/pom.xml | 2 +- bull-map-transformer/pom.xml | 2 +- bull-report/pom.xml | 2 +- pom.xml | 17 ++++++--- 24 files changed, 137 insertions(+), 43 deletions(-) diff --git a/CHANGELOG-JDK11.md b/CHANGELOG-JDK11.md index d9aee293d..416b468c7 100755 --- a/CHANGELOG-JDK11.md +++ b/CHANGELOG-JDK11.md @@ -2,8 +2,10 @@ All notable changes to this project will be documented in this file. -### [2.1.2-jdk11] 2022.07.06 +### [2.1.3-jdk11] 2022.12.01 * Adds the Bill of Materials (BOM) module +* Replaces javax with jakarta +* Add the possibility to customize the special types avoiding any transformation on them ### [2.1.1-jdk11] 2022.06.09 * Fixes an issue that was preventing skipping the injection for a given field. For more info about the feature see [here](README.md#skip-transformation-on-a-given-set-of-fields). diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bcd571f9..03937d152 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +### [2.2.3] 2022.12.01 +* Replaces javax with jakarta +* Add the possibility to customize the special types avoiding any transformation on them + ### [2.2.2] 2022.07.06 * Adds the Bill of Materials (BOM) module diff --git a/README.md b/README.md index 419f8ac92..f92c6213b 100644 --- a/README.md +++ b/README.md @@ -653,6 +653,31 @@ beanUtils.getTransformer() .transform(fromBean2, toBean); ``` +### Keep a field type value from the source object as is: + +Given: + +```java +public class FromBean { public class ToBean { + private final String name; private String name; + private final DateTime dateTime; private final DateTime dateTime; + + // all args constructor // constructor + // getters... // getters and setters... +} } +``` + +if you need to keep the value of a field type from the source object as it, you can add all the types you want to keep as they are +by doing: + +```java +ClassUtils.CUSTOM_SPECIAL_TYPES.add(DateTime.class); + +ToBean toBean = new ToBean(); +beanUtils.getTransformer() + .transform(fromBean, toBean); +``` + ### Not existing field in the source object: In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should gets the field value from that method. ```java diff --git a/bull-bean-transformer/pom.xml b/bull-bean-transformer/pom.xml index 5fc50842b..dd9d20de0 100644 --- a/bull-bean-transformer/pom.xml +++ b/bull-bean-transformer/pom.xml @@ -8,7 +8,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.3-SNAPSHOT + 2.2.4-SNAPSHOT diff --git a/bull-bom/pom.xml b/bull-bom/pom.xml index ff205bf9e..7c18d4394 100644 --- a/bull-bom/pom.xml +++ b/bull-bom/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.3-SNAPSHOT + 2.2.4-SNAPSHOT diff --git a/bull-common/pom.xml b/bull-common/pom.xml index dc94c3107..b91006e85 100644 --- a/bull-common/pom.xml +++ b/bull-common/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.3-SNAPSHOT + 2.2.4-SNAPSHOT @@ -50,7 +50,12 @@ org.glassfish - javax.el + jakarta.el + + + joda-time + joda-time + test diff --git a/bull-common/src/main/java/com/expediagroup/transformer/utils/ClassUtils.java b/bull-common/src/main/java/com/expediagroup/transformer/utils/ClassUtils.java index 848c786bf..7690af05a 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/utils/ClassUtils.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/utils/ClassUtils.java @@ -52,6 +52,7 @@ import java.util.ArrayList; import java.util.Currency; import java.util.Date; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -78,6 +79,11 @@ public final class ClassUtils { */ public static final String BUILD_METHOD_NAME = "build"; + /** + * Custom special types. + */ + public static final Set> CUSTOM_SPECIAL_TYPES = new HashSet<>(); + /** * Class nullability error message constant. */ @@ -92,7 +98,12 @@ public final class ClassUtils { * Primitive types list. */ private static final Set> PRIMITIVE_TYPES = of(String.class, Boolean.class, Integer.class, Long.class, - Double.class, BigDecimal.class, BigInteger.class, Short.class, Float.class, Character.class, Byte.class, Void.class); + Double.class, BigDecimal.class, BigInteger.class, Short.class, Float.class, Character.class, Byte.class, Void.class); + + /** + * Special type list. + */ + private static final Set> SPECIAL_TYPES = of(Currency.class, Locale.class, Temporal.class, Date.class, Properties.class); /** * Method Handles lookup. @@ -163,13 +174,19 @@ public boolean isPrimitiveTypeArray(final Class clazz) { * @return true if is special type, false otherwise */ public boolean isSpecialType(final Class clazz) { - final String cacheKey = "isSpecial-" + clazz.getName(); - return CACHE_MANAGER.getFromCache(cacheKey, Boolean.class).orElseGet(() -> { - final Boolean res = clazz.equals(Currency.class) || clazz.equals(Locale.class) || Temporal.class.isAssignableFrom(clazz) - || clazz.equals(Date.class) || clazz.equals(Properties.class) || clazz.isSynthetic(); - CACHE_MANAGER.cacheObject(cacheKey, res); - return res; - }); + return clazz.isSynthetic() || SPECIAL_TYPES.stream() + .anyMatch(specialTypeClazz -> clazz.equals(specialTypeClazz) || specialTypeClazz.isAssignableFrom(clazz)) + || isCustomSpecialType(clazz); + } + + /** + * Checks if the given class is a custom provided special type. + * @param clazz the class to check + * @return true if is special type, false otherwise + */ + private boolean isCustomSpecialType(final Class clazz) { + return CUSTOM_SPECIAL_TYPES.stream() + .anyMatch(customTypeClazz -> clazz.equals(customTypeClazz) || customTypeClazz.isAssignableFrom(clazz)); } /** diff --git a/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java b/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java index fe4489cf4..30a2e27db 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/validator/Validator.java @@ -20,7 +20,7 @@ import java.util.List; import java.util.Set; -import javax.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolation; import com.expediagroup.transformer.error.InvalidBeanException; diff --git a/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java b/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java index c882edf2f..921057473 100644 --- a/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java +++ b/bull-common/src/main/java/com/expediagroup/transformer/validator/ValidatorImpl.java @@ -18,7 +18,7 @@ import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; -import static javax.validation.Validation.buildDefaultValidatorFactory; +import static jakarta.validation.Validation.buildDefaultValidatorFactory; import static org.apache.commons.lang3.StringUtils.SPACE; @@ -26,7 +26,7 @@ import java.util.Set; import java.util.function.Function; -import javax.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolation; import com.expediagroup.transformer.cache.CacheManager; import com.expediagroup.transformer.cache.CacheManagerFactory; @@ -96,15 +96,17 @@ private Function, String> getConstraintViolationMess /** * Creates the validator. - * @return a {@link javax.validation.Validator} instance. + * @return a {@link jakarta.validation.Validator} instance. */ - private javax.validation.Validator getValidator() { + private jakarta.validation.Validator getValidator() { var cacheKey = "BeanValidator"; - return cacheManager.getFromCache(cacheKey, javax.validation.Validator.class) + return cacheManager.getFromCache(cacheKey, jakarta.validation.Validator.class) .orElseGet(() -> { - var validator = buildDefaultValidatorFactory().getValidator(); - cacheManager.cacheObject(cacheKey, validator); - return validator; + try (var validatorFactory = buildDefaultValidatorFactory()) { + var validator = validatorFactory.getValidator(); + cacheManager.cacheObject(cacheKey, validator); + return validator; + } }); } } diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java index 7e961dce3..31b81550e 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFoo.java @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java index a65284bb8..5f6735f91 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooCustomAnnotation.java @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.expediagroup.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java index 0b4926669..37b7a4782 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooDiffFields.java @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java index 5e603d815..9ad6050bb 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooMissingCustomAnnotation.java @@ -15,7 +15,7 @@ */ package com.expediagroup.beans.sample.immutable; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.expediagroup.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java index 7c0351b7a..01a88cd0f 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToFooSubClass.java @@ -19,7 +19,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.ToString; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java index fdd30c04a..cb21126f4 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/immutable/ImmutableToSubFooCustomAnnotation.java @@ -18,7 +18,7 @@ import java.util.List; import java.util.Map; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.expediagroup.transformer.annotation.ConstructorArg; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java index 34c3255a2..9ef318a3a 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFoo.java @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java index eb0f2ca8a..26d27cfe6 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java @@ -18,7 +18,7 @@ import java.math.BigInteger; import java.util.List; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import com.expediagroup.beans.sample.immutable.ImmutableToSubFoo; diff --git a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java index d3917083e..0c18175c5 100644 --- a/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java +++ b/bull-common/src/test/java/com/expediagroup/beans/sample/mixed/MixedToFooMissingConstructor.java @@ -17,7 +17,7 @@ import java.math.BigInteger; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java index dc8fa55ca..f4510e86b 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ClassUtilsTest.java @@ -41,8 +41,11 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; +import org.joda.time.DateTime; +import org.joda.time.LocalDateTime; +import org.joda.time.base.BaseLocal; import org.mockito.InjectMocks; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -179,13 +182,42 @@ public void testIsSpecialTypeWorksAsExpected(final String testCaseDescription, f */ @DataProvider private Object[][] dataSpecialTypeObjectTesting() { + ClassUtils.CUSTOM_SPECIAL_TYPES.clear(); return new Object[][] { {"Tests that the method returns true if the class is a special type object", Locale.class, true}, {"Tests that the method returns false if the class is not a special type object", BigDecimal.class, false}, {"Tests that the method returns true if the class is an instance of Temporal interface", Instant.class, true}, {"Tests that the method returns true if the class is an instance of Properties class", Properties.class, true}, {"Tests that the method returns true if the class is an instance of Currency class", Currency.class, true}, - {"Tests that the method returns true if the class is an instance of Date class", Date.class, true} + {"Tests that the method returns true if the class is an instance of Date class", Date.class, true}, + {"Tests that the method returns false if the class is an instance of DateTime class", DateTime.class, false} + }; + } + + /** + * Tests that the method {@code isSpecialType} returns the expected value in case of custom special types. + * @param testCaseDescription the test case description + * @param testClass the class to test + * @param expectedResult the expected result + */ + @Test(dataProvider = "dataCustomSpecialTypeObjectTesting") + public void testIsCustomSpecialTypeWorksAsExpected(final String testCaseDescription, final Class testClass, final boolean expectedResult) { + // GIVEN + + // WHEN + boolean actual = underTest.isSpecialType(testClass); + + // THEN + assertThat(actual).isEqualTo(expectedResult); + } + + @DataProvider + private Object[][] dataCustomSpecialTypeObjectTesting() { + ClassUtils.CUSTOM_SPECIAL_TYPES.addAll(List.of(FromFooSimple.class, BaseLocal.class)); + return new Object[][] { + {"Tests that the method returns true if the class is an instance of DateTime class", LocalDateTime.class, true}, + {"Tests that the method returns false if the class is an instance of Properties class", ImmutableToFoo.class, false}, + {"Tests that the method returns true if the class is a custom special type object", FromFooSimple.class, true} }; } diff --git a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java index 9b4108598..2eeb3b108 100644 --- a/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java +++ b/bull-common/src/test/java/com/expediagroup/transformer/utils/ReflectionUtilsTest.java @@ -41,8 +41,8 @@ import java.util.Map; import java.util.Optional; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.mockito.InjectMocks; diff --git a/bull-converter/pom.xml b/bull-converter/pom.xml index a56e86272..6edc35a61 100644 --- a/bull-converter/pom.xml +++ b/bull-converter/pom.xml @@ -9,7 +9,7 @@ com.expediagroup.beans bean-utils-library-parent - 2.2.3-SNAPSHOT + 2.2.4-SNAPSHOT diff --git a/bull-map-transformer/pom.xml b/bull-map-transformer/pom.xml index 0666bdb86..f215df12a 100644 --- a/bull-map-transformer/pom.xml +++ b/bull-map-transformer/pom.xml @@ -9,7 +9,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.2.3-SNAPSHOT + 2.2.4-SNAPSHOT diff --git a/bull-report/pom.xml b/bull-report/pom.xml index 1956a64ca..0fe09015c 100644 --- a/bull-report/pom.xml +++ b/bull-report/pom.xml @@ -8,7 +8,7 @@ bean-utils-library-parent com.expediagroup.beans - 2.2.3-SNAPSHOT + 2.2.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index df4cfe9f1..cd8c523b7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.expediagroup.beans bean-utils-library-parent https://github.com/ExpediaGroup/bull - 2.2.3-SNAPSHOT + 2.2.4-SNAPSHOT pom 2019 @@ -56,12 +56,13 @@ 4.9.0 7.6.1 3.23.1 + 2.12.1 - 6.2.5.Final + 8.0.0.Final 3.5.0.Final 2.2.1.Final 2.0.5 - 3.0.0 + 4.0.2 0.8.8 1.0 @@ -163,8 +164,8 @@ org.glassfish - javax.el - ${glassfish.javax.el.version} + jakarta.el + ${glassfish.jakarta.el.version} @@ -205,6 +206,12 @@ ${assertj-core.version} test + + joda-time + joda-time + ${joda-time.version} + test + From 0a78eae5c00df418215aa9d8f12f68a9b23254b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Dec 2022 11:10:18 +0000 Subject: [PATCH 1704/1786] Bump joda-time from 2.12.1 to 2.12.2 (#368) * Bump joda-time from 2.12.1 to 2.12.2 Bumps [joda-time](https://github.com/JodaOrg/joda-time) from 2.12.1 to 2.12.2. - [Release notes](https://github.com/JodaOrg/joda-time/releases) - [Changelog](https://github.com/JodaOrg/joda-time/blob/main/RELEASE-NOTES.txt) - [Commits](https://github.com/JodaOrg/joda-time/commits) --- updated-dependencies: - dependency-name: joda-time:joda-time dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cd8c523b7..0c1d7b7b2 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 4.9.0 7.6.1 3.23.1 - 2.12.1 + 2.12.2 8.0.0.Final 3.5.0.Final From a72cf19381f457a7b5f121d664c0b204ea43d8f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 Dec 2022 10:38:53 +0100 Subject: [PATCH 1705/1786] Bump testng from 7.6.1 to 7.7.0 (#369) * Bump testng from 7.6.1 to 7.7.0 Bumps [testng](https://github.com/cbeust/testng) from 7.6.1 to 7.7.0. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/compare/7.6.1...7.7.0) --- updated-dependencies: - dependency-name: org.testng:testng dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0c1d7b7b2..9cfff2e45 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.12.0 4.9.0 - 7.6.1 + 7.7.0 3.23.1 2.12.2 From 9d06d8dd6a95506ebefe20485c9615a1ebd7e6e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 16:27:57 +0100 Subject: [PATCH 1706/1786] Bump slf4j-api from 2.0.5 to 2.0.6 (#370) * Bump slf4j-api from 2.0.5 to 2.0.6 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 2.0.5 to 2.0.6. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.5...v_2.0.6) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9cfff2e45..efba029f3 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ 8.0.0.Final 3.5.0.Final 2.2.1.Final - 2.0.5 + 2.0.6 4.0.2 0.8.8 From 259f15676e5d8d6cab5b358be217037980aea692 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Dec 2022 17:58:57 +0000 Subject: [PATCH 1707/1786] Bump versions-maven-plugin from 2.13.0 to 2.14.0 (#371) * Bump versions-maven-plugin from 2.13.0 to 2.14.0 Bumps [versions-maven-plugin](https://github.com/mojohaus/versions) from 2.13.0 to 2.14.0. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.13.0...2.14.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index efba029f3..4011a6f38 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.0.1 3.4.1 3.2.0 - 2.13.0 + 2.14.0 10.5.0 3.0.0-M4 1.6.13 From f060c989d2fb1491292031d88f740470c8836fe5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Dec 2022 11:15:39 +0000 Subject: [PATCH 1708/1786] Bump mockito-core from 4.9.0 to 4.10.0 (#372) Bumps [mockito-core](https://github.com/mockito/mockito) from 4.9.0 to 4.10.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.9.0...v4.10.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4011a6f38..8300c6738 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.9.0 + 4.10.0 7.7.0 3.23.1 2.12.2 From 97b6e429a2aecaf1f094ce0686b9a121c1ac8e8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Dec 2022 13:38:31 +0000 Subject: [PATCH 1709/1786] Bump versions-maven-plugin from 2.14.0 to 2.14.1 (#373) * Bump versions-maven-plugin from 2.14.0 to 2.14.1 Bumps [versions-maven-plugin](https://github.com/mojohaus/versions) from 2.14.0 to 2.14.1. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.14.0...2.14.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8300c6738..4e567f95e 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.0.1 3.4.1 3.2.0 - 2.14.0 + 2.14.1 10.5.0 3.0.0-M4 1.6.13 From 032e79467b46fea7fdd22c4c93a6888fb9f23660 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Dec 2022 07:19:17 +0000 Subject: [PATCH 1710/1786] Bump wagon-ssh from 3.5.2 to 3.5.3 (#376) * Bump wagon-ssh from 3.5.2 to 3.5.3 Bumps wagon-ssh from 3.5.2 to 3.5.3. --- updated-dependencies: - dependency-name: org.apache.maven.wagon:wagon-ssh dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4e567f95e..fbc25f5c9 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 2.3.1 - 3.5.2 + 3.5.3 0.12 github 3.12.1 From 03e324aef76ec9156a256e6944807345ca76cbdf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Dec 2022 07:22:08 +0000 Subject: [PATCH 1711/1786] Bump versions-maven-plugin from 2.14.1 to 2.14.2 (#378) * Bump versions-maven-plugin from 2.14.1 to 2.14.2 Bumps [versions-maven-plugin](https://github.com/mojohaus/versions) from 2.14.1 to 2.14.2. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.14.1...2.14.2) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fbc25f5c9..8eb24ae0a 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.0.1 3.4.1 3.2.0 - 2.14.1 + 2.14.2 10.5.0 3.0.0-M4 1.6.13 From 22521d81b400dc1378834066570c3b953ffd28ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Dec 2022 07:25:31 +0000 Subject: [PATCH 1712/1786] Bump actions/cache from 3.0.11 to 3.2.1 (#377) * Bump actions/cache from 3.0.11 to 3.2.1 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.11 to 3.2.1. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.11...v3.2.1) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 8efeea97c..db2d3f260 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.2.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.2.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.2.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 6bcc451c6..f622867e8 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.2.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.2.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.2.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index d50daad9c..a50913498 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.2.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 99948e7bd..4dae39b62 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.0.11 + uses: actions/cache@v3.2.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From a4bb503f073cadc9f473e502fdbd33e7fb5cf7db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Dec 2022 15:01:49 +0000 Subject: [PATCH 1713/1786] Bump actions/cache from 3.2.1 to 3.2.2 (#379) * Bump actions/cache from 3.2.1 to 3.2.2 Bumps [actions/cache](https://github.com/actions/cache) from 3.2.1 to 3.2.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.1...v3.2.2) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index db2d3f260..eb843eb1f 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.1 + uses: actions/cache@v3.2.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.1 + uses: actions/cache@v3.2.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.1 + uses: actions/cache@v3.2.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index f622867e8..e00bbe78b 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.1 + uses: actions/cache@v3.2.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.1 + uses: actions/cache@v3.2.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.1 + uses: actions/cache@v3.2.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index a50913498..afc442ef9 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.1 + uses: actions/cache@v3.2.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 4dae39b62..141b9501c 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.1 + uses: actions/cache@v3.2.2 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From aabe40e4dfdb9d3bc32a6336c8cfc6f42f0099f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Dec 2022 08:25:06 +0000 Subject: [PATCH 1714/1786] Bump testng from 7.7.0 to 7.7.1 (#381) * Bump testng from 7.7.0 to 7.7.1 Bumps [testng](https://github.com/cbeust/testng) from 7.7.0 to 7.7.1. - [Release notes](https://github.com/cbeust/testng/releases) - [Changelog](https://github.com/cbeust/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/cbeust/testng/compare/7.7.0...7.7.1) --- updated-dependencies: - dependency-name: org.testng:testng dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8eb24ae0a..6a168bd68 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.12.0 4.10.0 - 7.7.0 + 7.7.1 3.23.1 2.12.2 From 86b3cab82a5c6195192e772f526308c95883cf31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Dec 2022 10:03:24 +0100 Subject: [PATCH 1715/1786] Bump mockito-core from 4.10.0 to 4.11.0 (#380) * Bump mockito-core from 4.10.0 to 4.11.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 4.10.0 to 4.11.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.10.0...v4.11.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6a168bd68..df501acd0 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.18.24 3.12.0 - 4.10.0 + 4.11.0 7.7.1 3.23.1 2.12.2 From b6581c4868de4f5f0828b1b112efa26a7397af6d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:04:55 +0000 Subject: [PATCH 1716/1786] Bump checkstyle from 10.5.0 to 10.6.0 (#382) Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.5.0 to 10.6.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.5.0...checkstyle-10.6.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index df501acd0..7ef23a8b2 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.4.1 3.2.0 2.14.2 - 10.5.0 + 10.6.0 3.0.0-M4 1.6.13 3.1.2 From 934a8ba80ebfff1ea33db7969e2b425fea6b7aa5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 13:33:07 +0000 Subject: [PATCH 1717/1786] Bump assertj-core from 3.23.1 to 3.24.0 (#383) Bumps assertj-core from 3.23.1 to 3.24.0. --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7ef23a8b2..7fad2fc4a 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 4.11.0 7.7.1 - 3.23.1 + 3.24.0 2.12.2 8.0.0.Final From da7da8b76223c9bcc6792787753fddf22a982a95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:55:46 +0100 Subject: [PATCH 1718/1786] Bump assertj-core from 3.24.0 to 3.24.1 (#384) * Bump assertj-core from 3.24.0 to 3.24.1 Bumps assertj-core from 3.24.0 to 3.24.1. --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7fad2fc4a..aa241259d 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 4.11.0 7.7.1 - 3.24.0 + 3.24.1 2.12.2 8.0.0.Final From 9f29ec364ac3f0ddaccbc35b909c6904c3ad923c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:56:14 +0100 Subject: [PATCH 1719/1786] Bump actions/cache from 3.2.2 to 3.2.3 (#385) * Bump actions/cache from 3.2.2 to 3.2.3 Bumps [actions/cache](https://github.com/actions/cache) from 3.2.2 to 3.2.3. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.2...v3.2.3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index eb843eb1f..5f892a29e 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.2 + uses: actions/cache@v3.2.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.2 + uses: actions/cache@v3.2.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.2 + uses: actions/cache@v3.2.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index e00bbe78b..f342b4de4 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.2 + uses: actions/cache@v3.2.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.2 + uses: actions/cache@v3.2.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.2 + uses: actions/cache@v3.2.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index afc442ef9..fe24ba998 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.2 + uses: actions/cache@v3.2.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 141b9501c..65887f608 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.2 + uses: actions/cache@v3.2.3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 78e681ff3bb367db62a72fd15bcd0ec32c097450 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 11:16:17 +0000 Subject: [PATCH 1720/1786] Bump maven-checkstyle-plugin from 3.2.0 to 3.2.1 (#386) * Bump maven-checkstyle-plugin from 3.2.0 to 3.2.1 Bumps [maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.2.0 to 3.2.1. - [Release notes](https://github.com/apache/maven-checkstyle-plugin/releases) - [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.2.0...maven-checkstyle-plugin-3.2.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aa241259d..8ababa895 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ [3.8.1,) 3.0.1 3.4.1 - 3.2.0 + 3.2.1 2.14.2 10.6.0 3.0.0-M4 From 19ef9b03f39e303e38729a012b90c6f5a2d74b45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Jan 2023 16:46:17 +0000 Subject: [PATCH 1721/1786] Bump assertj-core from 3.24.1 to 3.24.2 (#388) * Bump assertj-core from 3.24.1 to 3.24.2 Bumps assertj-core from 3.24.1 to 3.24.2. --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8ababa895..5d91e750b 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 4.11.0 7.7.1 - 3.24.1 + 3.24.2 2.12.2 8.0.0.Final From 8f64056b4c768ce1658ab4e7de60e19e3318019f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 07:24:33 -0500 Subject: [PATCH 1722/1786] Bump actions/cache from 3.2.3 to 3.2.4 (#389) * Bump actions/cache from 3.2.3 to 3.2.4 Bumps [actions/cache](https://github.com/actions/cache) from 3.2.3 to 3.2.4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.3...v3.2.4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 5f892a29e..0e1f893dd 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.3 + uses: actions/cache@v3.2.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.3 + uses: actions/cache@v3.2.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.3 + uses: actions/cache@v3.2.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index f342b4de4..f1b13164e 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.3 + uses: actions/cache@v3.2.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.3 + uses: actions/cache@v3.2.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.3 + uses: actions/cache@v3.2.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index fe24ba998..3f2d856e1 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.3 + uses: actions/cache@v3.2.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 65887f608..643814be3 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.3 + uses: actions/cache@v3.2.4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 1f83b2a69709d2bfc28eb11cdcff788c97ac3b51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 15:09:02 +0000 Subject: [PATCH 1723/1786] Bump checkstyle from 10.6.0 to 10.7.0 (#391) * Bump checkstyle from 10.6.0 to 10.7.0 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.6.0 to 10.7.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.6.0...checkstyle-10.7.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5d91e750b..71758387d 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.4.1 3.2.1 2.14.2 - 10.6.0 + 10.7.0 3.0.0-M4 1.6.13 3.1.2 From 03a608740f131fd411bf0f821321ce8ff2d4382e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 15:15:23 +0000 Subject: [PATCH 1724/1786] Bump maven-enforcer-plugin from 3.1.0 to 3.2.1 (#390) * Bump maven-enforcer-plugin from 3.1.0 to 3.2.1 Bumps [maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.1.0 to 3.2.1. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.1.0...enforcer-3.2.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 71758387d..49377d555 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ 3.0.0-M4 1.6.13 3.1.2 - 3.1.0 + 3.2.1 false From 44d37aa6c3b215b54df13a61a79fe281f8cb1495 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Feb 2023 14:19:37 +0100 Subject: [PATCH 1725/1786] Bump lombok from 1.18.24 to 1.18.26 (#392) * Bump lombok from 1.18.24 to 1.18.26 Bumps [lombok](https://github.com/projectlombok/lombok) from 1.18.24 to 1.18.26. - [Release notes](https://github.com/projectlombok/lombok/releases) - [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/projectlombok/lombok/compare/v1.18.24...v1.18.26) --- updated-dependencies: - dependency-name: org.projectlombok:lombok dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 49377d555..5358b216e 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 15 ${jdk.version} ${jdk.version} - 1.18.24 + 1.18.26 3.12.0 4.11.0 From ea19798748ed1df4ec4e1dbcb5765a9af0ddf946 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Feb 2023 12:41:20 +0000 Subject: [PATCH 1726/1786] Bump actions/cache from 3.2.4 to 3.2.5 (#393) * Bump actions/cache from 3.2.4 to 3.2.5 Bumps [actions/cache](https://github.com/actions/cache) from 3.2.4 to 3.2.5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.4...v3.2.5) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 0e1f893dd..a39bcfda6 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.4 + uses: actions/cache@v3.2.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.4 + uses: actions/cache@v3.2.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.4 + uses: actions/cache@v3.2.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index f1b13164e..b94c44c8b 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.4 + uses: actions/cache@v3.2.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.4 + uses: actions/cache@v3.2.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.4 + uses: actions/cache@v3.2.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 3f2d856e1..e87de47e2 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.4 + uses: actions/cache@v3.2.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 643814be3..0ab956621 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.4 + uses: actions/cache@v3.2.5 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From bc83d23275eb67090e0d87e0841605a609340b01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:03:30 +0100 Subject: [PATCH 1727/1786] Bump maven-javadoc-plugin from 3.4.1 to 3.5.0 (#394) * Bump maven-javadoc-plugin from 3.4.1 to 3.5.0 Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.4.1 to 3.5.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.4.1...maven-javadoc-plugin-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5358b216e..70597f86c 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ [3.8.1,) 3.0.1 - 3.4.1 + 3.5.0 3.2.1 2.14.2 10.7.0 From 7e5f282e96d7a0c12ddba65199019374b49eddd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 14:38:04 +0000 Subject: [PATCH 1728/1786] Bump actions/cache from 3.2.5 to 3.2.6 (#395) * Bump actions/cache from 3.2.5 to 3.2.6 Bumps [actions/cache](https://github.com/actions/cache) from 3.2.5 to 3.2.6. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.5...v3.2.6) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index a39bcfda6..8faa3781a 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.5 + uses: actions/cache@v3.2.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.5 + uses: actions/cache@v3.2.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.5 + uses: actions/cache@v3.2.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index b94c44c8b..3776a6f7b 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.5 + uses: actions/cache@v3.2.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.5 + uses: actions/cache@v3.2.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.5 + uses: actions/cache@v3.2.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index e87de47e2..c12dcc1b3 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.5 + uses: actions/cache@v3.2.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 0ab956621..34d1526c2 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.5 + uses: actions/cache@v3.2.6 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 8ad8037d80ccadc5867478af4083dcfd1d41f3e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 13:16:33 +0000 Subject: [PATCH 1729/1786] Bump versions-maven-plugin from 2.14.2 to 2.15.0 (#396) * Bump versions-maven-plugin from 2.14.2 to 2.15.0 Bumps [versions-maven-plugin](https://github.com/mojohaus/versions) from 2.14.2 to 2.15.0. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.14.2...2.15.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 70597f86c..e298cb17b 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.0.1 3.5.0 3.2.1 - 2.14.2 + 2.15.0 10.7.0 3.0.0-M4 1.6.13 From 9496fceabda1eae841579f735600a020f8b8706d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 13:38:26 +0000 Subject: [PATCH 1730/1786] Bump checkstyle from 10.7.0 to 10.8.0 (#397) * Bump checkstyle from 10.7.0 to 10.8.0 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.7.0 to 10.8.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.7.0...checkstyle-10.8.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e298cb17b..04a578fc1 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.2.1 2.15.0 - 10.7.0 + 10.8.0 3.0.0-M4 1.6.13 3.1.2 From 847d693f1d7398abcc706b4d7c55492e9549b711 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Mar 2023 14:25:33 +0100 Subject: [PATCH 1731/1786] Bump actions/cache from 3.2.6 to 3.3.0 (#399) * Bump actions/cache from 3.2.6 to 3.3.0 Bumps [actions/cache](https://github.com/actions/cache) from 3.2.6 to 3.3.0. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.2.6...v3.3.0) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 8faa3781a..40c17b32e 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.6 + uses: actions/cache@v3.3.0 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.6 + uses: actions/cache@v3.3.0 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.6 + uses: actions/cache@v3.3.0 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 3776a6f7b..09d08bfda 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.6 + uses: actions/cache@v3.3.0 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.6 + uses: actions/cache@v3.3.0 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.2.6 + uses: actions/cache@v3.3.0 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index c12dcc1b3..403c32f01 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.6 + uses: actions/cache@v3.3.0 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 34d1526c2..dd680879b 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.2.6 + uses: actions/cache@v3.3.0 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 41b55f14cdf290ce9369c1e4254a91bdad3b02df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Mar 2023 13:28:31 +0000 Subject: [PATCH 1732/1786] Bump checkstyle from 10.8.0 to 10.8.1 (#398) * Bump checkstyle from 10.8.0 to 10.8.1 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.8.0 to 10.8.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.8.0...checkstyle-10.8.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 04a578fc1..db3f9c1cc 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.2.1 2.15.0 - 10.8.0 + 10.8.1 3.0.0-M4 1.6.13 3.1.2 From 27737dd2392db7a40e9956df68303f6e8e729797 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:18:19 +0000 Subject: [PATCH 1733/1786] Bump actions/cache from 3.3.0 to 3.3.1 (#400) * Bump actions/cache from 3.3.0 to 3.3.1 Bumps [actions/cache](https://github.com/actions/cache) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.3.0...v3.3.1) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 40c17b32e..3a9a38aa1 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.3.0 + uses: actions/cache@v3.3.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.3.0 + uses: actions/cache@v3.3.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.3.0 + uses: actions/cache@v3.3.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 09d08bfda..b79758bbd 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.3.0 + uses: actions/cache@v3.3.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.3.0 + uses: actions/cache@v3.3.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.3.0 + uses: actions/cache@v3.3.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 403c32f01..e24a6fb2e 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.3.0 + uses: actions/cache@v3.3.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index dd680879b..851385cda 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: "Cache Maven repository" - uses: actions/cache@v3.3.0 + uses: actions/cache@v3.3.1 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From c92ce7c80fe34e3d80b1d6537d83ae07af06aba8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 14:59:41 +0000 Subject: [PATCH 1734/1786] Bump checkstyle from 10.8.1 to 10.9.0 (#401) * Bump checkstyle from 10.8.1 to 10.9.0 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.8.1 to 10.9.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.8.1...checkstyle-10.9.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index db3f9c1cc..485d630d0 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.2.1 2.15.0 - 10.8.1 + 10.9.0 3.0.0-M4 1.6.13 3.1.2 From 8d6088736ab5b48f144a06556e6d4192e3f9eb8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 16:07:10 +0000 Subject: [PATCH 1735/1786] Bump checkstyle from 10.9.0 to 10.9.1 (#402) * Bump checkstyle from 10.9.0 to 10.9.1 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.9.0 to 10.9.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.9.0...checkstyle-10.9.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 485d630d0..019ddbda9 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.2.1 2.15.0 - 10.9.0 + 10.9.1 3.0.0-M4 1.6.13 3.1.2 From 6d2f7349edd731a18d917d873fab77371811b03c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Mar 2023 09:20:14 +0000 Subject: [PATCH 1736/1786] Bump slf4j-api from 2.0.6 to 2.0.7 (#405) * Bump slf4j-api from 2.0.6 to 2.0.7 Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 2.0.6 to 2.0.7. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/commits) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 019ddbda9..033a1e387 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ 8.0.0.Final 3.5.0.Final 2.2.1.Final - 2.0.6 + 2.0.7 4.0.2 0.8.8 From 6f18f1abd704c1cf972396f41c7d4aca7c67667f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Mar 2023 09:26:00 +0000 Subject: [PATCH 1737/1786] Bump checkstyle from 10.9.1 to 10.9.2 (#404) * Bump checkstyle from 10.9.1 to 10.9.2 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.9.1 to 10.9.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.9.1...checkstyle-10.9.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 033a1e387..27a86fac8 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.2.1 2.15.0 - 10.9.1 + 10.9.2 3.0.0-M4 1.6.13 3.1.2 From d7b333bc81f1dd17825e92102f0112722df72794 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 13:29:22 +0000 Subject: [PATCH 1738/1786] Bump joda-time from 2.12.2 to 2.12.3 (#406) * Bump joda-time from 2.12.2 to 2.12.3 Bumps [joda-time](https://github.com/JodaOrg/joda-time) from 2.12.2 to 2.12.3. - [Release notes](https://github.com/JodaOrg/joda-time/releases) - [Changelog](https://github.com/JodaOrg/joda-time/blob/main/RELEASE-NOTES.txt) - [Commits](https://github.com/JodaOrg/joda-time/compare/2.12.2...v2.12.3) --- updated-dependencies: - dependency-name: joda-time:joda-time dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 27a86fac8..ddfaa9172 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 4.11.0 7.7.1 3.24.2 - 2.12.2 + 2.12.3 8.0.0.Final 3.5.0.Final From e408e798b29ac913ac0de1b9bdbaf496628705b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 16:19:36 +0000 Subject: [PATCH 1739/1786] Bump joda-time from 2.12.3 to 2.12.4 (#407) * Bump joda-time from 2.12.3 to 2.12.4 Bumps [joda-time](https://github.com/JodaOrg/joda-time) from 2.12.3 to 2.12.4. - [Release notes](https://github.com/JodaOrg/joda-time/releases) - [Changelog](https://github.com/JodaOrg/joda-time/blob/main/RELEASE-NOTES.txt) - [Commits](https://github.com/JodaOrg/joda-time/compare/v2.12.3...v2.12.4) --- updated-dependencies: - dependency-name: joda-time:joda-time dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ddfaa9172..842f62bcc 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 4.11.0 7.7.1 3.24.2 - 2.12.3 + 2.12.4 8.0.0.Final 3.5.0.Final From 43f2b18276ac41c74576f477e245f6717713b563 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 15:46:30 +0000 Subject: [PATCH 1740/1786] Bump checkstyle from 10.9.2 to 10.9.3 (#409) * Bump checkstyle from 10.9.2 to 10.9.3 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.9.2 to 10.9.3. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.9.2...checkstyle-10.9.3) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification * Trigger notification * Update README.md minor change * Trigger notification * updates copyright date * updates copyright dates --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello Co-authored-by: Fabio Borriello --- README.md | 2 +- .../src/main/java/com/expediagroup/beans/BeanUtils.java | 2 +- .../src/main/java/com/expediagroup/beans/package-info.java | 2 +- .../java/com/expediagroup/beans/populator/ArrayPopulator.java | 2 +- .../com/expediagroup/beans/populator/CollectionPopulator.java | 2 +- .../com/expediagroup/beans/populator/ICollectionPopulator.java | 2 +- .../java/com/expediagroup/beans/populator/MapPopulator.java | 2 +- .../com/expediagroup/beans/populator/OptionalPopulator.java | 2 +- .../main/java/com/expediagroup/beans/populator/Populator.java | 2 +- .../java/com/expediagroup/beans/populator/PopulatorFactory.java | 2 +- .../java/com/expediagroup/beans/populator/package-info.java | 2 +- .../expediagroup/beans/transformer/AbstractBeanTransformer.java | 2 +- .../com/expediagroup/beans/transformer/BeanTransformer.java | 2 +- .../com/expediagroup/beans/transformer/TransformerImpl.java | 2 +- .../java/com/expediagroup/beans/transformer/package-info.java | 2 +- bull-bean-transformer/src/main/resources/logback.xml | 2 +- .../src/test/java/com/expediagroup/beans/BeanUtilsTest.java | 2 +- .../src/test/java/com/expediagroup/beans/package-info.java | 2 +- .../com/expediagroup/beans/performance/PerformanceTest.java | 2 +- .../java/com/expediagroup/beans/performance/package-info.java | 2 +- .../com/expediagroup/beans/populator/ArrayPopulatorTest.java | 2 +- .../com/expediagroup/beans/populator/PopulatorFactoryTest.java | 2 +- .../java/com/expediagroup/beans/populator/package-info.java | 2 +- .../beans/transformer/AbstractBeanTransformerTest.java | 2 +- .../com/expediagroup/beans/transformer/BeanTransformerTest.java | 2 +- .../beans/transformer/BuilderObjectTransformationTest.java | 2 +- .../beans/transformer/ImmutableObjectTransformationTest.java | 2 +- .../beans/transformer/MixedObjectTransformationTest.java | 2 +- .../beans/transformer/MutableObjectTransformationTest.java | 2 +- .../java/com/expediagroup/beans/transformer/package-info.java | 2 +- bull-bean-transformer/src/test/resources/logback-test.xml | 2 +- .../java/com/expediagroup/transformer/AbstractTransformer.java | 2 +- .../src/main/java/com/expediagroup/transformer/Transformer.java | 2 +- .../com/expediagroup/transformer/annotation/ConstructorArg.java | 2 +- .../com/expediagroup/transformer/annotation/package-info.java | 2 +- .../main/java/com/expediagroup/transformer/base/Defaults.java | 2 +- .../java/com/expediagroup/transformer/base/package-info.java | 2 +- .../java/com/expediagroup/transformer/cache/CacheManager.java | 2 +- .../com/expediagroup/transformer/cache/CacheManagerFactory.java | 2 +- .../java/com/expediagroup/transformer/cache/package-info.java | 2 +- .../java/com/expediagroup/transformer/constant/ClassType.java | 2 +- .../java/com/expediagroup/transformer/constant/Filters.java | 2 +- .../com/expediagroup/transformer/constant/MethodPrefix.java | 2 +- .../java/com/expediagroup/transformer/constant/Punctuation.java | 2 +- .../com/expediagroup/transformer/constant/package-info.java | 2 +- .../transformer/error/InstanceCreationException.java | 2 +- .../expediagroup/transformer/error/InvalidBeanException.java | 2 +- .../transformer/error/InvalidFunctionException.java | 2 +- .../expediagroup/transformer/error/MissingFieldException.java | 2 +- .../expediagroup/transformer/error/MissingMethodException.java | 2 +- .../java/com/expediagroup/transformer/error/package-info.java | 2 +- .../java/com/expediagroup/transformer/model/EmptyValue.java | 2 +- .../java/com/expediagroup/transformer/model/FieldMapping.java | 2 +- .../com/expediagroup/transformer/model/FieldTransformer.java | 2 +- .../main/java/com/expediagroup/transformer/model/ItemType.java | 2 +- .../java/com/expediagroup/transformer/model/MapElemType.java | 2 +- .../main/java/com/expediagroup/transformer/model/MapType.java | 2 +- .../com/expediagroup/transformer/model/TransformerSettings.java | 2 +- .../java/com/expediagroup/transformer/model/package-info.java | 2 +- .../main/java/com/expediagroup/transformer/package-info.java | 2 +- .../java/com/expediagroup/transformer/utils/ClassUtils.java | 2 +- .../com/expediagroup/transformer/utils/ReflectionUtils.java | 2 +- .../java/com/expediagroup/transformer/utils/package-info.java | 2 +- .../java/com/expediagroup/transformer/validator/Validator.java | 2 +- .../com/expediagroup/transformer/validator/ValidatorImpl.java | 2 +- .../com/expediagroup/transformer/validator/package-info.java | 2 +- .../src/test/java/com/expediagroup/beans/package-info.java | 2 +- .../test/java/com/expediagroup/beans/sample/AbstractClass.java | 2 +- .../src/test/java/com/expediagroup/beans/sample/FromFoo.java | 2 +- .../java/com/expediagroup/beans/sample/FromFooAdvFields.java | 2 +- .../src/test/java/com/expediagroup/beans/sample/FromFooMap.java | 2 +- .../test/java/com/expediagroup/beans/sample/FromFooNoField.java | 2 +- .../expediagroup/beans/sample/FromFooOnlyPrimitiveTypes.java | 2 +- .../test/java/com/expediagroup/beans/sample/FromFooSimple.java | 2 +- .../expediagroup/beans/sample/FromFooSimpleBooleanField.java | 2 +- .../com/expediagroup/beans/sample/FromFooSimpleNoGetters.java | 2 +- .../java/com/expediagroup/beans/sample/FromFooSubClass.java | 2 +- .../expediagroup/beans/sample/FromFooWithPrimitiveFields.java | 2 +- .../src/test/java/com/expediagroup/beans/sample/FromSubFoo.java | 2 +- .../src/test/java/com/expediagroup/beans/sample/ISubClass.java | 2 +- .../expediagroup/beans/sample/immutable/ImmutableFlatToFoo.java | 2 +- .../com/expediagroup/beans/sample/immutable/ImmutableToFoo.java | 2 +- .../beans/sample/immutable/ImmutableToFooAdvFields.java | 2 +- .../beans/sample/immutable/ImmutableToFooCustomAnnotation.java | 2 +- .../beans/sample/immutable/ImmutableToFooDiffFields.java | 2 +- .../beans/sample/immutable/ImmutableToFooDiffTypesFields.java | 2 +- .../expediagroup/beans/sample/immutable/ImmutableToFooMap.java | 2 +- .../sample/immutable/ImmutableToFooMissingCustomAnnotation.java | 2 +- .../beans/sample/immutable/ImmutableToFooNoConstructors.java | 2 +- .../beans/sample/immutable/ImmutableToFooNotExistingFields.java | 2 +- .../beans/sample/immutable/ImmutableToFooSimple.java | 2 +- .../beans/sample/immutable/ImmutableToFooSimpleBoolean.java | 2 +- .../beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java | 2 +- .../beans/sample/immutable/ImmutableToFooSubClass.java | 2 +- .../beans/sample/immutable/ImmutableToFooWithBuilder.java | 2 +- .../expediagroup/beans/sample/immutable/ImmutableToSubFoo.java | 2 +- .../sample/immutable/ImmutableToSubFooCustomAnnotation.java | 2 +- .../com/expediagroup/beans/sample/immutable/package-info.java | 2 +- .../java/com/expediagroup/beans/sample/mixed/MixedToFoo.java | 2 +- .../expediagroup/beans/sample/mixed/MixedToFooDiffFields.java | 2 +- .../beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java | 2 +- .../beans/sample/mixed/MixedToFooMissingConstructor.java | 2 +- .../expediagroup/beans/sample/mixed/MixedToFooMissingField.java | 2 +- .../beans/sample/mixed/MixedToFooNotExistingFields.java | 2 +- .../beans/sample/mixed/MixedToFooSimpleNotExistingFields.java | 2 +- .../expediagroup/beans/sample/mixed/MixedToFooStaticField.java | 2 +- .../expediagroup/beans/sample/mixed/MixedToFooWithBuilder.java | 2 +- .../beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java | 2 +- .../java/com/expediagroup/beans/sample/mixed/package-info.java | 2 +- .../com/expediagroup/beans/sample/mutable/MutableToFoo.java | 2 +- .../beans/sample/mutable/MutableToFooAdvFields.java | 2 +- .../expediagroup/beans/sample/mutable/MutableToFooInvalid.java | 2 +- .../beans/sample/mutable/MutableToFooNotExistingFields.java | 2 +- .../expediagroup/beans/sample/mutable/MutableToFooSimple.java | 2 +- .../beans/sample/mutable/MutableToFooSimpleNoSetters.java | 2 +- .../expediagroup/beans/sample/mutable/MutableToFooSubClass.java | 2 +- .../beans/sample/mutable/MutableToFooWithBuilder.java | 2 +- .../mutable/MutableToFooWithBuilderMultipleConstructor.java | 2 +- .../beans/sample/mutable/MutableToFooWithWrongBuilder.java | 2 +- .../com/expediagroup/beans/sample/mutable/MutableToSubFoo.java | 2 +- .../com/expediagroup/beans/sample/mutable/package-info.java | 2 +- .../test/java/com/expediagroup/beans/sample/package-info.java | 2 +- .../com/expediagroup/transformer/AbstractTransformerTest.java | 2 +- .../java/com/expediagroup/transformer/base/DefaultsTest.java | 2 +- .../java/com/expediagroup/transformer/base/package-info.java | 2 +- .../expediagroup/transformer/cache/CacheManagerFactoryTest.java | 2 +- .../com/expediagroup/transformer/cache/CacheManagerTest.java | 2 +- .../java/com/expediagroup/transformer/cache/package-info.java | 2 +- .../test/java/com/expediagroup/transformer/package-info.java | 2 +- .../java/com/expediagroup/transformer/utils/ClassUtilsTest.java | 2 +- .../com/expediagroup/transformer/utils/ReflectionUtilsTest.java | 2 +- .../java/com/expediagroup/transformer/utils/package-info.java | 2 +- .../com/expediagroup/transformer/validator/ValidatorTest.java | 2 +- .../com/expediagroup/transformer/validator/package-info.java | 2 +- bull-common/src/test/resources/logback-test.xml | 2 +- .../main/java/com/expediagroup/beans/conversion/Converter.java | 2 +- .../java/com/expediagroup/beans/conversion/ConverterImpl.java | 2 +- .../beans/conversion/analyzer/ConversionAnalyzer.java | 2 +- .../expediagroup/beans/conversion/analyzer/package-info.java | 2 +- .../beans/conversion/error/TypeConversionException.java | 2 +- .../com/expediagroup/beans/conversion/error/package-info.java | 2 +- .../java/com/expediagroup/beans/conversion/package-info.java | 2 +- .../beans/conversion/processor/ConversionProcessor.java | 2 +- .../beans/conversion/processor/ConversionProcessorFactory.java | 2 +- .../processor/impl/BigDecimalConversionProcessor.java | 2 +- .../processor/impl/BigIntegerConversionProcessor.java | 2 +- .../conversion/processor/impl/BooleanConversionProcessor.java | 2 +- .../conversion/processor/impl/ByteArrayConversionProcessor.java | 2 +- .../conversion/processor/impl/ByteConversionProcessor.java | 2 +- .../conversion/processor/impl/CharacterConversionProcessor.java | 2 +- .../conversion/processor/impl/DoubleConversionProcessor.java | 2 +- .../conversion/processor/impl/FloatConversionProcessor.java | 2 +- .../conversion/processor/impl/IntegerConversionProcessor.java | 2 +- .../conversion/processor/impl/LongConversionProcessor.java | 2 +- .../conversion/processor/impl/ShortConversionProcessor.java | 2 +- .../conversion/processor/impl/StringConversionProcessor.java | 2 +- .../beans/conversion/processor/impl/package-info.java | 2 +- .../expediagroup/beans/conversion/processor/package-info.java | 2 +- .../expediagroup/beans/conversion/AbstractConversionTest.java | 2 +- .../java/com/expediagroup/beans/conversion/ConverterTest.java | 2 +- .../beans/conversion/analyzer/ConversionAnalyzerTest.java | 2 +- .../expediagroup/beans/conversion/analyzer/package-info.java | 2 +- .../java/com/expediagroup/beans/conversion/package-info.java | 2 +- .../conversion/processor/ConversionProcessorFactoryTest.java | 2 +- .../conversion/processor/impl/BigDecimalConversionTest.java | 2 +- .../conversion/processor/impl/BigIntegerConversionTest.java | 2 +- .../beans/conversion/processor/impl/BooleanConversionTest.java | 2 +- .../conversion/processor/impl/ByteArrayConversionTest.java | 2 +- .../beans/conversion/processor/impl/ByteConversionTest.java | 2 +- .../conversion/processor/impl/CharacterConversionTest.java | 2 +- .../beans/conversion/processor/impl/DoubleConversionTest.java | 2 +- .../beans/conversion/processor/impl/FloatConversionTest.java | 2 +- .../beans/conversion/processor/impl/IntegerConversionTest.java | 2 +- .../beans/conversion/processor/impl/LongConversionTest.java | 2 +- .../beans/conversion/processor/impl/ShortConversionTest.java | 2 +- .../beans/conversion/processor/impl/StringConversionTest.java | 2 +- .../beans/conversion/processor/impl/package-info.java | 2 +- .../expediagroup/beans/conversion/processor/package-info.java | 2 +- .../src/main/java/com/expediagroup/map/MapUtils.java | 2 +- .../src/main/java/com/expediagroup/map/package-info.java | 2 +- .../expediagroup/map/transformer/AbstractMapTransformer.java | 2 +- .../java/com/expediagroup/map/transformer/MapTransformer.java | 2 +- .../com/expediagroup/map/transformer/MapTransformerImpl.java | 2 +- .../map/transformer/model/MapTransformerSettings.java | 2 +- .../com/expediagroup/map/transformer/model/package-info.java | 2 +- .../java/com/expediagroup/map/transformer/package-info.java | 2 +- bull-map-transformer/src/main/resources/logback.xml | 2 +- .../src/test/java/com/expediagroup/map/MapUtilsTest.java | 2 +- .../src/test/java/com/expediagroup/map/package-info.java | 2 +- .../com/expediagroup/map/transformer/MapTransformerTest.java | 2 +- .../java/com/expediagroup/map/transformer/package-info.java | 2 +- .../beans/generator/bytecode/TransformerBytecodeAdapter.java | 2 +- .../com/expediagroup/beans/generator/bytecode/package-info.java | 2 +- .../generator/bytecode/TransformerBytecodeAdapterTest.java | 2 +- .../com/expediagroup/beans/generator/bytecode/package-info.java | 2 +- .../bytecode/sample/TransformerBytecodeAdapterExample.java | 2 +- .../beans/generator/bytecode/sample/TransformerCtorThrows.java | 2 +- .../generator/bytecode/sample/TransformerCtorWithArgs.java | 2 +- .../beans/generator/bytecode/sample/TransformerPrivateCtor.java | 2 +- .../beans/generator/bytecode/sample/package-info.java | 2 +- .../java/com/expediagroup/beans/generator/core/Transformer.java | 2 +- .../com/expediagroup/beans/generator/core/TransformerSpec.java | 2 +- .../generator/core/error/TransformerGeneratorException.java | 2 +- .../expediagroup/beans/generator/core/error/package-info.java | 2 +- .../expediagroup/beans/generator/core/mapping/BeanProperty.java | 2 +- .../expediagroup/beans/generator/core/mapping/JavaBeanCode.java | 2 +- .../expediagroup/beans/generator/core/mapping/MappingCode.java | 2 +- .../beans/generator/core/mapping/MappingCodeFactory.java | 2 +- .../expediagroup/beans/generator/core/mapping/package-info.java | 2 +- .../com/expediagroup/beans/generator/core/package-info.java | 2 +- .../expediagroup/beans/generator/core/TransformerSpecTest.java | 2 +- .../beans/generator/core/mapping/BeanPropertyTest.java | 2 +- .../beans/generator/core/mapping/JavaBeanCodeTest.java | 2 +- .../beans/generator/core/mapping/MappingCodeFactoryTest.java | 2 +- .../expediagroup/beans/generator/core/mapping/package-info.java | 2 +- .../com/expediagroup/beans/generator/core/package-info.java | 2 +- .../generator/core/sample/immutable/ImmutableDestination.java | 2 +- .../beans/generator/core/sample/immutable/package-info.java | 2 +- .../beans/generator/core/sample/javabean/Destination.java | 2 +- .../beans/generator/core/sample/javabean/Source.java | 2 +- .../generator/core/sample/javabean/TransformerExample.java | 2 +- .../beans/generator/core/sample/javabean/package-info.java | 2 +- .../beans/generator/core/sample/mixed/MixedDestination.java | 2 +- .../beans/generator/core/sample/mixed/package-info.java | 2 +- .../java/com/expediagroup/transformer/constant/ClassType.java | 2 +- .../com/expediagroup/transformer/constant/package-info.java | 2 +- .../beans/generator/source/SourceTransformerSpec.java | 2 +- .../expediagroup/beans/generator/source/TransformerFile.java | 2 +- .../beans/generator/source/TransformerSourceAdapter.java | 2 +- .../com/expediagroup/beans/generator/source/package-info.java | 2 +- .../beans/generator/source/SourceTransformerSpecTest.java | 2 +- .../beans/generator/source/TransformerFileTest.java | 2 +- .../beans/generator/source/TransformerSourceAdapterTest.java | 2 +- .../com/expediagroup/beans/generator/source/package-info.java | 2 +- .../source/sample/TransformerSourceAdapterExample.java | 2 +- .../beans/generator/source/sample/package-info.java | 2 +- pom.xml | 2 +- 237 files changed, 237 insertions(+), 237 deletions(-) diff --git a/README.md b/README.md index f92c6213b..0b108b817 100644 --- a/README.md +++ b/README.md @@ -1071,4 +1071,4 @@ For any question, proposal, or help, please refer to the slack channel: [#bull]( This project is available under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html). -Copyright 2018-2021 Expedia Inc. \ No newline at end of file +Copyright 2018-2023 Expedia Inc. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java index 1cc762d47..8b3233dbd 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java index 14bb9e8e5..372ae47e1 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java index a8d70c109..85fa0453f 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java index 5168e7853..8ed33ed6a 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java index ae98a405a..a8e6b34e5 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java index 51473a062..9ca2d8b9d 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java index 9770be260..8be588544 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java index 478182813..4e52dfd72 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java index 91d2070c6..6c473e23b 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java index 8fb1b860e..58c93cdf5 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java index 663c81787..41907c5d4 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java index e1a71f63f..7c346acbc 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java index 5069f8268..f030a620b 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java index 0dba08fbf..1d8581a38 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2019-2022 Expedia, Inc. + * Copyright (C) 2018-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/resources/logback.xml b/bull-bean-transformer/src/main/resources/logback.xml index 4c13cc321..4e90e861b 100644 --- a/bull-bean-transformer/src/main/resources/logback.xml +++ b/bull-bean-transformer/src/main/resources/logback.xml @@ -1,5 +1,5 @@ 8.0.0.Final 3.5.0.Final From 2656e80cdfe52109866e21d4518b2c119e9379cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:11:12 +0200 Subject: [PATCH 1742/1786] Bump jacoco-maven-plugin from 0.8.8 to 0.8.9 (#411) * Bump jacoco-maven-plugin from 0.8.8 to 0.8.9 Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.8 to 0.8.9. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.8...v0.8.9) --- updated-dependencies: - dependency-name: org.jacoco:jacoco-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 68f99f33d..3e11080c0 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ 2.0.7 4.0.2 - 0.8.8 + 0.8.9 1.0 0.98 1.0 From b7f7cc92dd78cc83d8b3faf3ae6febf56efb4fe5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 14:16:32 +0200 Subject: [PATCH 1743/1786] Bump maven-enforcer-plugin from 3.2.1 to 3.3.0 (#412) * Bump maven-enforcer-plugin from 3.2.1 to 3.3.0 Bumps [maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.2.1 to 3.3.0. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.2.1...enforcer-3.3.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3e11080c0..577fa93a3 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ 3.0.0-M4 1.6.13 3.1.2 - 3.2.1 + 3.3.0 false From 004e41b62cec2557e76e27580cffd30efdb15cb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Apr 2023 14:29:19 +0200 Subject: [PATCH 1744/1786] Bump maven-checkstyle-plugin from 3.2.1 to 3.2.2 (#414) * Bump maven-checkstyle-plugin from 3.2.1 to 3.2.2 Bumps [maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.2.1 to 3.2.2. - [Release notes](https://github.com/apache/maven-checkstyle-plugin/releases) - [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.2.1...maven-checkstyle-plugin-3.2.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 577fa93a3..ef1dfcdfe 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ [3.8.1,) 3.0.1 3.5.0 - 3.2.1 + 3.2.2 2.15.0 10.9.3 3.0.0-M4 From 2cbd2e011863c2f8db172812bada93891f333fed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Apr 2023 12:06:08 +0000 Subject: [PATCH 1745/1786] Bump jacoco-maven-plugin from 0.8.9 to 0.8.10 (#415) * Bump jacoco-maven-plugin from 0.8.9 to 0.8.10 Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.9 to 0.8.10. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.9...v0.8.10) --- updated-dependencies: - dependency-name: org.jacoco:jacoco-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ef1dfcdfe..b79b818d9 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ 2.0.7 4.0.2 - 0.8.9 + 0.8.10 1.0 0.98 1.0 From 586b358568c2a7a6f312a344dab3416c0203a076 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 15:48:41 +0000 Subject: [PATCH 1746/1786] Bump checkstyle from 10.9.3 to 10.10.0 (#416) * Bump checkstyle from 10.9.3 to 10.10.0 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.9.3 to 10.10.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.9.3...checkstyle-10.10.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b79b818d9..95766636b 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.2.2 2.15.0 - 10.9.3 + 10.10.0 3.0.0-M4 1.6.13 3.1.2 From 8a31fb157d5465d3ad8437ff09ebaaa755b74011 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 02:55:56 +0200 Subject: [PATCH 1747/1786] Bump maven-gpg-plugin from 3.0.1 to 3.1.0 (#417) * Bump maven-gpg-plugin from 3.0.1 to 3.1.0 Bumps [maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.0.1 to 3.1.0. - [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.0.1...maven-gpg-plugin-3.1.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-gpg-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 95766636b..81717b7c3 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ 3.12.1 [3.8.1,) - 3.0.1 + 3.1.0 3.5.0 3.2.2 2.15.0 From 5460657a7a8c4cc379b4cdd8301d71699dbc055c Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Tue, 9 May 2023 03:09:35 +0200 Subject: [PATCH 1748/1786] Copyright dates update (#418) * Bump maven-gpg-plugin from 3.0.1 to 3.1.0 (#417) * Bump maven-gpg-plugin from 3.0.1 to 3.1.0 Bumps [maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.0.1 to 3.1.0. - [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.0.1...maven-gpg-plugin-3.1.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-gpg-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello * updates copyright dates * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .../src/main/java/com/expediagroup/beans/BeanUtils.java | 2 +- .../src/main/java/com/expediagroup/beans/package-info.java | 2 +- .../java/com/expediagroup/beans/populator/ArrayPopulator.java | 2 +- .../com/expediagroup/beans/populator/CollectionPopulator.java | 2 +- .../com/expediagroup/beans/populator/ICollectionPopulator.java | 2 +- .../java/com/expediagroup/beans/populator/MapPopulator.java | 2 +- .../com/expediagroup/beans/populator/OptionalPopulator.java | 2 +- .../main/java/com/expediagroup/beans/populator/Populator.java | 2 +- .../java/com/expediagroup/beans/populator/PopulatorFactory.java | 2 +- .../java/com/expediagroup/beans/populator/package-info.java | 2 +- .../expediagroup/beans/transformer/AbstractBeanTransformer.java | 2 +- .../com/expediagroup/beans/transformer/BeanTransformer.java | 2 +- .../com/expediagroup/beans/transformer/TransformerImpl.java | 2 +- .../java/com/expediagroup/beans/transformer/package-info.java | 2 +- bull-bean-transformer/src/main/resources/logback.xml | 2 +- .../src/test/java/com/expediagroup/beans/BeanUtilsTest.java | 2 +- .../src/test/java/com/expediagroup/beans/package-info.java | 2 +- .../com/expediagroup/beans/performance/PerformanceTest.java | 2 +- .../java/com/expediagroup/beans/performance/package-info.java | 2 +- .../com/expediagroup/beans/populator/ArrayPopulatorTest.java | 2 +- .../com/expediagroup/beans/populator/PopulatorFactoryTest.java | 2 +- .../java/com/expediagroup/beans/populator/package-info.java | 2 +- .../beans/transformer/AbstractBeanTransformerTest.java | 2 +- .../com/expediagroup/beans/transformer/BeanTransformerTest.java | 2 +- .../beans/transformer/BuilderObjectTransformationTest.java | 2 +- .../beans/transformer/ImmutableObjectTransformationTest.java | 2 +- .../beans/transformer/MixedObjectTransformationTest.java | 2 +- .../beans/transformer/MutableObjectTransformationTest.java | 2 +- .../java/com/expediagroup/beans/transformer/package-info.java | 2 +- bull-bean-transformer/src/test/resources/logback-test.xml | 2 +- .../java/com/expediagroup/transformer/AbstractTransformer.java | 2 +- .../src/main/java/com/expediagroup/transformer/Transformer.java | 2 +- .../com/expediagroup/transformer/annotation/ConstructorArg.java | 2 +- .../com/expediagroup/transformer/annotation/package-info.java | 2 +- .../main/java/com/expediagroup/transformer/base/Defaults.java | 2 +- .../java/com/expediagroup/transformer/base/package-info.java | 2 +- .../java/com/expediagroup/transformer/cache/CacheManager.java | 2 +- .../com/expediagroup/transformer/cache/CacheManagerFactory.java | 2 +- .../java/com/expediagroup/transformer/cache/package-info.java | 2 +- .../java/com/expediagroup/transformer/constant/ClassType.java | 2 +- .../java/com/expediagroup/transformer/constant/Filters.java | 2 +- .../com/expediagroup/transformer/constant/MethodPrefix.java | 2 +- .../java/com/expediagroup/transformer/constant/Punctuation.java | 2 +- .../com/expediagroup/transformer/constant/package-info.java | 2 +- .../transformer/error/InstanceCreationException.java | 2 +- .../expediagroup/transformer/error/InvalidBeanException.java | 2 +- .../transformer/error/InvalidFunctionException.java | 2 +- .../expediagroup/transformer/error/MissingFieldException.java | 2 +- .../expediagroup/transformer/error/MissingMethodException.java | 2 +- .../java/com/expediagroup/transformer/error/package-info.java | 2 +- .../java/com/expediagroup/transformer/model/EmptyValue.java | 2 +- .../java/com/expediagroup/transformer/model/FieldMapping.java | 2 +- .../com/expediagroup/transformer/model/FieldTransformer.java | 2 +- .../main/java/com/expediagroup/transformer/model/ItemType.java | 2 +- .../java/com/expediagroup/transformer/model/MapElemType.java | 2 +- .../main/java/com/expediagroup/transformer/model/MapType.java | 2 +- .../com/expediagroup/transformer/model/TransformerSettings.java | 2 +- .../java/com/expediagroup/transformer/model/package-info.java | 2 +- .../main/java/com/expediagroup/transformer/package-info.java | 2 +- .../java/com/expediagroup/transformer/utils/ClassUtils.java | 2 +- .../com/expediagroup/transformer/utils/ReflectionUtils.java | 2 +- .../java/com/expediagroup/transformer/utils/package-info.java | 2 +- .../java/com/expediagroup/transformer/validator/Validator.java | 2 +- .../com/expediagroup/transformer/validator/ValidatorImpl.java | 2 +- .../com/expediagroup/transformer/validator/package-info.java | 2 +- .../src/test/java/com/expediagroup/beans/package-info.java | 2 +- .../test/java/com/expediagroup/beans/sample/AbstractClass.java | 2 +- .../src/test/java/com/expediagroup/beans/sample/FromFoo.java | 2 +- .../java/com/expediagroup/beans/sample/FromFooAdvFields.java | 2 +- .../src/test/java/com/expediagroup/beans/sample/FromFooMap.java | 2 +- .../test/java/com/expediagroup/beans/sample/FromFooNoField.java | 2 +- .../expediagroup/beans/sample/FromFooOnlyPrimitiveTypes.java | 2 +- .../test/java/com/expediagroup/beans/sample/FromFooSimple.java | 2 +- .../expediagroup/beans/sample/FromFooSimpleBooleanField.java | 2 +- .../com/expediagroup/beans/sample/FromFooSimpleNoGetters.java | 2 +- .../java/com/expediagroup/beans/sample/FromFooSubClass.java | 2 +- .../expediagroup/beans/sample/FromFooWithPrimitiveFields.java | 2 +- .../src/test/java/com/expediagroup/beans/sample/FromSubFoo.java | 2 +- .../src/test/java/com/expediagroup/beans/sample/ISubClass.java | 2 +- .../expediagroup/beans/sample/immutable/ImmutableFlatToFoo.java | 2 +- .../com/expediagroup/beans/sample/immutable/ImmutableToFoo.java | 2 +- .../beans/sample/immutable/ImmutableToFooAdvFields.java | 2 +- .../beans/sample/immutable/ImmutableToFooCustomAnnotation.java | 2 +- .../beans/sample/immutable/ImmutableToFooDiffFields.java | 2 +- .../beans/sample/immutable/ImmutableToFooDiffTypesFields.java | 2 +- .../expediagroup/beans/sample/immutable/ImmutableToFooMap.java | 2 +- .../sample/immutable/ImmutableToFooMissingCustomAnnotation.java | 2 +- .../beans/sample/immutable/ImmutableToFooNoConstructors.java | 2 +- .../beans/sample/immutable/ImmutableToFooNotExistingFields.java | 2 +- .../beans/sample/immutable/ImmutableToFooSimple.java | 2 +- .../beans/sample/immutable/ImmutableToFooSimpleBoolean.java | 2 +- .../beans/sample/immutable/ImmutableToFooSimpleWrongTypes.java | 2 +- .../beans/sample/immutable/ImmutableToFooSubClass.java | 2 +- .../beans/sample/immutable/ImmutableToFooWithBuilder.java | 2 +- .../expediagroup/beans/sample/immutable/ImmutableToSubFoo.java | 2 +- .../sample/immutable/ImmutableToSubFooCustomAnnotation.java | 2 +- .../com/expediagroup/beans/sample/immutable/package-info.java | 2 +- .../java/com/expediagroup/beans/sample/mixed/MixedToFoo.java | 2 +- .../expediagroup/beans/sample/mixed/MixedToFooDiffFields.java | 2 +- .../beans/sample/mixed/MixedToFooMissingAllArgsConstructor.java | 2 +- .../beans/sample/mixed/MixedToFooMissingConstructor.java | 2 +- .../expediagroup/beans/sample/mixed/MixedToFooMissingField.java | 2 +- .../beans/sample/mixed/MixedToFooNotExistingFields.java | 2 +- .../beans/sample/mixed/MixedToFooSimpleNotExistingFields.java | 2 +- .../expediagroup/beans/sample/mixed/MixedToFooStaticField.java | 2 +- .../expediagroup/beans/sample/mixed/MixedToFooWithBuilder.java | 2 +- .../beans/sample/mixed/MutableToFooOnlyPrimitiveTypes.java | 2 +- .../java/com/expediagroup/beans/sample/mixed/package-info.java | 2 +- .../com/expediagroup/beans/sample/mutable/MutableToFoo.java | 2 +- .../beans/sample/mutable/MutableToFooAdvFields.java | 2 +- .../expediagroup/beans/sample/mutable/MutableToFooInvalid.java | 2 +- .../beans/sample/mutable/MutableToFooNotExistingFields.java | 2 +- .../expediagroup/beans/sample/mutable/MutableToFooSimple.java | 2 +- .../beans/sample/mutable/MutableToFooSimpleNoSetters.java | 2 +- .../expediagroup/beans/sample/mutable/MutableToFooSubClass.java | 2 +- .../beans/sample/mutable/MutableToFooWithBuilder.java | 2 +- .../mutable/MutableToFooWithBuilderMultipleConstructor.java | 2 +- .../beans/sample/mutable/MutableToFooWithWrongBuilder.java | 2 +- .../com/expediagroup/beans/sample/mutable/MutableToSubFoo.java | 2 +- .../com/expediagroup/beans/sample/mutable/package-info.java | 2 +- .../test/java/com/expediagroup/beans/sample/package-info.java | 2 +- .../com/expediagroup/transformer/AbstractTransformerTest.java | 2 +- .../java/com/expediagroup/transformer/base/DefaultsTest.java | 2 +- .../java/com/expediagroup/transformer/base/package-info.java | 2 +- .../expediagroup/transformer/cache/CacheManagerFactoryTest.java | 2 +- .../com/expediagroup/transformer/cache/CacheManagerTest.java | 2 +- .../java/com/expediagroup/transformer/cache/package-info.java | 2 +- .../test/java/com/expediagroup/transformer/package-info.java | 2 +- .../java/com/expediagroup/transformer/utils/ClassUtilsTest.java | 2 +- .../com/expediagroup/transformer/utils/ReflectionUtilsTest.java | 2 +- .../java/com/expediagroup/transformer/utils/package-info.java | 2 +- .../com/expediagroup/transformer/validator/ValidatorTest.java | 2 +- .../com/expediagroup/transformer/validator/package-info.java | 2 +- bull-common/src/test/resources/logback-test.xml | 2 +- .../main/java/com/expediagroup/beans/conversion/Converter.java | 2 +- .../java/com/expediagroup/beans/conversion/ConverterImpl.java | 2 +- .../beans/conversion/analyzer/ConversionAnalyzer.java | 2 +- .../expediagroup/beans/conversion/analyzer/package-info.java | 2 +- .../beans/conversion/error/TypeConversionException.java | 2 +- .../com/expediagroup/beans/conversion/error/package-info.java | 2 +- .../java/com/expediagroup/beans/conversion/package-info.java | 2 +- .../beans/conversion/processor/ConversionProcessor.java | 2 +- .../beans/conversion/processor/ConversionProcessorFactory.java | 2 +- .../processor/impl/BigDecimalConversionProcessor.java | 2 +- .../processor/impl/BigIntegerConversionProcessor.java | 2 +- .../conversion/processor/impl/BooleanConversionProcessor.java | 2 +- .../conversion/processor/impl/ByteArrayConversionProcessor.java | 2 +- .../conversion/processor/impl/ByteConversionProcessor.java | 2 +- .../conversion/processor/impl/CharacterConversionProcessor.java | 2 +- .../conversion/processor/impl/DoubleConversionProcessor.java | 2 +- .../conversion/processor/impl/FloatConversionProcessor.java | 2 +- .../conversion/processor/impl/IntegerConversionProcessor.java | 2 +- .../conversion/processor/impl/LongConversionProcessor.java | 2 +- .../conversion/processor/impl/ShortConversionProcessor.java | 2 +- .../conversion/processor/impl/StringConversionProcessor.java | 2 +- .../beans/conversion/processor/impl/package-info.java | 2 +- .../expediagroup/beans/conversion/processor/package-info.java | 2 +- .../expediagroup/beans/conversion/AbstractConversionTest.java | 2 +- .../java/com/expediagroup/beans/conversion/ConverterTest.java | 2 +- .../beans/conversion/analyzer/ConversionAnalyzerTest.java | 2 +- .../expediagroup/beans/conversion/analyzer/package-info.java | 2 +- .../java/com/expediagroup/beans/conversion/package-info.java | 2 +- .../conversion/processor/ConversionProcessorFactoryTest.java | 2 +- .../conversion/processor/impl/BigDecimalConversionTest.java | 2 +- .../conversion/processor/impl/BigIntegerConversionTest.java | 2 +- .../beans/conversion/processor/impl/BooleanConversionTest.java | 2 +- .../conversion/processor/impl/ByteArrayConversionTest.java | 2 +- .../beans/conversion/processor/impl/ByteConversionTest.java | 2 +- .../conversion/processor/impl/CharacterConversionTest.java | 2 +- .../beans/conversion/processor/impl/DoubleConversionTest.java | 2 +- .../beans/conversion/processor/impl/FloatConversionTest.java | 2 +- .../beans/conversion/processor/impl/IntegerConversionTest.java | 2 +- .../beans/conversion/processor/impl/LongConversionTest.java | 2 +- .../beans/conversion/processor/impl/ShortConversionTest.java | 2 +- .../beans/conversion/processor/impl/StringConversionTest.java | 2 +- .../beans/conversion/processor/impl/package-info.java | 2 +- .../expediagroup/beans/conversion/processor/package-info.java | 2 +- .../src/main/java/com/expediagroup/map/MapUtils.java | 2 +- .../src/main/java/com/expediagroup/map/package-info.java | 2 +- .../expediagroup/map/transformer/AbstractMapTransformer.java | 2 +- .../java/com/expediagroup/map/transformer/MapTransformer.java | 2 +- .../com/expediagroup/map/transformer/MapTransformerImpl.java | 2 +- .../map/transformer/model/MapTransformerSettings.java | 2 +- .../com/expediagroup/map/transformer/model/package-info.java | 2 +- .../java/com/expediagroup/map/transformer/package-info.java | 2 +- bull-map-transformer/src/main/resources/logback.xml | 2 +- .../src/test/java/com/expediagroup/map/MapUtilsTest.java | 2 +- .../src/test/java/com/expediagroup/map/package-info.java | 2 +- .../com/expediagroup/map/transformer/MapTransformerTest.java | 2 +- .../java/com/expediagroup/map/transformer/package-info.java | 2 +- pom.xml | 2 +- 191 files changed, 191 insertions(+), 191 deletions(-) diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java index 8b3233dbd..3fddc6b21 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/BeanUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java index 372ae47e1..812f40655 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java index 85fa0453f..9e358437b 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ArrayPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java index 8ed33ed6a..9ca26bd4c 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/CollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java index a8e6b34e5..7cd185eb5 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/ICollectionPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java index 9ca2d8b9d..d5a12d15d 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/MapPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java index 8be588544..3756bba3c 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/OptionalPopulator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java index 4e52dfd72..f9651f207 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/Populator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java index 6c473e23b..7ff88537e 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/PopulatorFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java index 58c93cdf5..6989bcb60 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/populator/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java index 41907c5d4..d3c795591 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/AbstractBeanTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java index 7c346acbc..d2e8a53c6 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/BeanTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java index f030a620b..7134aacce 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/TransformerImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java index 1d8581a38..f176d0118 100644 --- a/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java +++ b/bull-bean-transformer/src/main/java/com/expediagroup/beans/transformer/package-info.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2023 Expedia, Inc. + * Copyright (C) 2019-2023 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/bull-bean-transformer/src/main/resources/logback.xml b/bull-bean-transformer/src/main/resources/logback.xml index 4e90e861b..cc8a0afd7 100644 --- a/bull-bean-transformer/src/main/resources/logback.xml +++ b/bull-bean-transformer/src/main/resources/logback.xml @@ -1,5 +1,5 @@ [3.8.1,) - 3.0.1 + 3.1.0 3.5.0 3.2.2 2.15.0 From 25e6e2e993dc80eabf1ad741f765d7632802edb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 16:49:57 +0200 Subject: [PATCH 1749/1786] Bump checkstyle from 10.10.0 to 10.11.0 (#419) * Bump checkstyle from 10.10.0 to 10.11.0 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.10.0 to 10.11.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.10.0...checkstyle-10.11.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 81717b7c3..03614a0b7 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.2.2 2.15.0 - 10.10.0 + 10.11.0 3.0.0-M4 1.6.13 3.1.2 From c2f1d6d320b1700a570f8eb8d2b9802324f50198 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 May 2023 13:56:12 +0000 Subject: [PATCH 1750/1786] Bump testng from 7.7.1 to 7.8.0 (#421) * Bump testng from 7.7.1 to 7.8.0 Bumps [testng](https://github.com/testng-team/testng) from 7.7.1 to 7.8.0. - [Release notes](https://github.com/testng-team/testng/releases) - [Changelog](https://github.com/testng-team/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/testng-team/testng/compare/7.7.1...7.8.0) --- updated-dependencies: - dependency-name: org.testng:testng dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification * changes the checkstyle encoding tag name --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 03614a0b7..a5a991849 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.12.0 4.11.0 - 7.7.1 + 7.8.0 3.24.2 2.12.5 @@ -503,7 +503,7 @@ config/checkstyle/rules.xml config/checkstyle/suppression.xml - UTF-8 + UTF-8 true true ${checkstyle.check.skip} From d1de2dc45bea5e2660f3d6a57b9644d806bffcd3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 10:10:50 +0000 Subject: [PATCH 1751/1786] Bump maven-checkstyle-plugin from 3.2.2 to 3.3.0 (#422) * Bump maven-checkstyle-plugin from 3.2.2 to 3.3.0 Bumps [maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.2.2 to 3.3.0. - [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.2.2...maven-checkstyle-plugin-3.3.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a5a991849..98ccf65e7 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ [3.8.1,) 3.1.0 3.5.0 - 3.2.2 + 3.3.0 2.15.0 10.11.0 3.0.0-M4 From deb5f6ee90562ddfd6334b9a409b9a0efbd654de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 12:20:44 +0000 Subject: [PATCH 1752/1786] Bump checkstyle from 10.11.0 to 10.12.0 (#424) * Bump checkstyle from 10.11.0 to 10.12.0 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.11.0 to 10.12.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.11.0...checkstyle-10.12.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 98ccf65e7..a2a458dcf 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.3.0 2.15.0 - 10.11.0 + 10.12.0 3.0.0-M4 1.6.13 3.1.2 From 7ab05fbab27249d2d7edde79c04f15a69245b34c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 14:24:21 +0200 Subject: [PATCH 1753/1786] Bump lombok from 1.18.26 to 1.18.28 (#423) * Bump lombok from 1.18.26 to 1.18.28 Bumps [lombok](https://github.com/projectlombok/lombok) from 1.18.26 to 1.18.28. - [Release notes](https://github.com/projectlombok/lombok/releases) - [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/projectlombok/lombok/compare/v1.18.26...v1.18.28) --- updated-dependencies: - dependency-name: org.projectlombok:lombok dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a2a458dcf..611d03f35 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 15 ${jdk.version} ${jdk.version} - 1.18.26 + 1.18.28 3.12.0 4.11.0 From d81f837a114974e50a7ea84b1cd07e397ba753f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 16:11:13 +0200 Subject: [PATCH 1754/1786] Bump jboss-logging from 3.5.0.Final to 3.5.1.Final (#425) * Bump jboss-logging from 3.5.0.Final to 3.5.1.Final Bumps [jboss-logging](https://github.com/jboss-logging/jboss-logging) from 3.5.0.Final to 3.5.1.Final. - [Release notes](https://github.com/jboss-logging/jboss-logging/releases) - [Commits](https://github.com/jboss-logging/jboss-logging/compare/3.5.0.Final...3.5.1.Final) --- updated-dependencies: - dependency-name: org.jboss.logging:jboss-logging dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 611d03f35..27f805775 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 2.12.5 8.0.0.Final - 3.5.0.Final + 3.5.1.Final 2.2.1.Final 2.0.7 4.0.2 From 3dfbe20af7b4416d5b572057b3a888cc40c9fdb1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 17:08:08 +0200 Subject: [PATCH 1755/1786] Bump versions-maven-plugin from 2.15.0 to 2.16.0 (#426) * Bump versions-maven-plugin from 2.15.0 to 2.16.0 Bumps [versions-maven-plugin](https://github.com/mojohaus/versions) from 2.15.0 to 2.16.0. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.15.0...2.16.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 27f805775..4bbae27d6 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.1.0 3.5.0 3.3.0 - 2.15.0 + 2.16.0 10.12.0 3.0.0-M4 1.6.13 From 24eb0cdd092ccaa8d0ef2b9877c7e29eaaed5fac Mon Sep 17 00:00:00 2001 From: Fabio Borriello Date: Mon, 26 Jun 2023 10:22:52 +0200 Subject: [PATCH 1756/1786] Updates the maven cache path on CI/CD configuration (#427) Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 3a9a38aa1..b37dde347 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -15,7 +15,7 @@ jobs: - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: - path: ~/.m2 + path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK set-up" @@ -34,7 +34,7 @@ jobs: - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: - path: ~/.m2 + path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "Extract build information" @@ -71,7 +71,7 @@ jobs: - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: - path: ~/.m2 + path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK set-up" diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index b79758bbd..023a2318b 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -15,7 +15,7 @@ jobs: - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: - path: ~/.m2 + path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK 11 set-up" @@ -34,7 +34,7 @@ jobs: - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: - path: ~/.m2 + path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "Extract build information" @@ -71,7 +71,7 @@ jobs: - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: - path: ~/.m2 + path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK 11 set-up" diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index e24a6fb2e..f690b77a8 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -14,7 +14,7 @@ jobs: - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: - path: ~/.m2 + path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "Extract build information" diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 851385cda..80795e231 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -14,7 +14,7 @@ jobs: - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: - path: ~/.m2 + path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "Extract build information" From bebd90850f64fe84d7a30fa3b68fe60878f6ed73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 15:47:50 +0000 Subject: [PATCH 1757/1786] Bump checkstyle from 10.12.0 to 10.12.1 (#428) * Bump checkstyle from 10.12.0 to 10.12.1 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 10.12.0 to 10.12.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.0...checkstyle-10.12.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4bbae27d6..c60e97ca5 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.3.0 2.16.0 - 10.12.0 + 10.12.1 3.0.0-M4 1.6.13 3.1.2 From e65ab6b4cd50626816a521329fbfcb408ae0e66a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Jul 2023 10:16:03 +0000 Subject: [PATCH 1758/1786] Bump jboss-logging from 3.5.1.Final to 3.5.2.Final (#429) * Bump jboss-logging from 3.5.1.Final to 3.5.2.Final Bumps [jboss-logging](https://github.com/jboss-logging/jboss-logging) from 3.5.1.Final to 3.5.2.Final. - [Release notes](https://github.com/jboss-logging/jboss-logging/releases) - [Commits](https://github.com/jboss-logging/jboss-logging/compare/3.5.1.Final...3.5.2.Final) --- updated-dependencies: - dependency-name: org.jboss.logging:jboss-logging dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c60e97ca5..a85cc5019 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 2.12.5 8.0.0.Final - 3.5.1.Final + 3.5.2.Final 2.2.1.Final 2.0.7 4.0.2 From 9063bcd619492b52ac78641d0b674c712a6a0d96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 15:36:45 +0000 Subject: [PATCH 1759/1786] Bump jboss-logging from 3.5.2.Final to 3.5.3.Final (#430) * Bump jboss-logging from 3.5.2.Final to 3.5.3.Final Bumps [jboss-logging](https://github.com/jboss-logging/jboss-logging) from 3.5.2.Final to 3.5.3.Final. - [Release notes](https://github.com/jboss-logging/jboss-logging/releases) - [Commits](https://github.com/jboss-logging/jboss-logging/compare/3.5.2.Final...3.5.3.Final) --- updated-dependencies: - dependency-name: org.jboss.logging:jboss-logging dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a85cc5019..0c239a4c6 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 2.12.5 8.0.0.Final - 3.5.2.Final + 3.5.3.Final 2.2.1.Final 2.0.7 4.0.2 From 79d8d36ba9cae0d3cf6cb41fe6dbb067ed635dcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 10:08:01 +0200 Subject: [PATCH 1760/1786] Bump com.puppycrawl.tools:checkstyle from 10.12.1 to 10.12.2 (#432) * Bump com.puppycrawl.tools:checkstyle from 10.12.1 to 10.12.2 Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.12.1 to 10.12.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.1...checkstyle-10.12.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0c239a4c6..65c8c65f1 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.3.0 2.16.0 - 10.12.1 + 10.12.2 3.0.0-M4 1.6.13 3.1.2 From c6573fa4cf6304e990007f9429e280611d21b68e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 10:08:24 +0200 Subject: [PATCH 1761/1786] Bump org.apache.commons:commons-lang3 from 3.12.0 to 3.13.0 (#431) * Bump org.apache.commons:commons-lang3 from 3.12.0 to 3.13.0 Bumps org.apache.commons:commons-lang3 from 3.12.0 to 3.13.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 65c8c65f1..43977e011 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ ${jdk.version} ${jdk.version} 1.18.28 - 3.12.0 + 3.13.0 4.11.0 7.8.0 From 95fa39e6b103022aff6d8306afb6c85223eb6c2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:12:59 +0000 Subject: [PATCH 1762/1786] Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.3.0 to 3.4.0 (#433) * Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.3.0 to 3.4.0 Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.3.0...enforcer-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 43977e011..5d5a77eb9 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ 3.0.0-M4 1.6.13 3.1.2 - 3.3.0 + 3.4.0 false From c43d5cdbc1c6b9aa8554a84d7dc17d9915cdc062 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 15:13:46 +0200 Subject: [PATCH 1763/1786] Bump com.puppycrawl.tools:checkstyle from 10.12.2 to 10.12.3 (#434) * Bump com.puppycrawl.tools:checkstyle from 10.12.2 to 10.12.3 Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.12.2 to 10.12.3. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.2...checkstyle-10.12.3) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5d5a77eb9..d84286a35 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.5.0 3.3.0 2.16.0 - 10.12.2 + 10.12.3 3.0.0-M4 1.6.13 3.1.2 From 747473dffc3d390dc461d24c4f1fbd5887f05902 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 12:20:53 +0000 Subject: [PATCH 1764/1786] Bump org.slf4j:slf4j-api from 2.0.7 to 2.0.9 (#435) * Bump org.slf4j:slf4j-api from 2.0.7 to 2.0.9 Bumps org.slf4j:slf4j-api from 2.0.7 to 2.0.9. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d84286a35..7cbbc7b1e 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ 8.0.0.Final 3.5.3.Final 2.2.1.Final - 2.0.7 + 2.0.9 4.0.2 0.8.10 From 6c89ee3cb51a7eac3f395d079d7a679065d53b3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 13:29:16 +0200 Subject: [PATCH 1765/1786] Bump actions/checkout from 3 to 4 (#436) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index b37dde347..caab242fc 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -11,7 +11,7 @@ jobs: name: "Build" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: @@ -30,7 +30,7 @@ jobs: name: "Test and quality check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: @@ -80,7 +80,7 @@ jobs: java-version: '15' distribution: 'adopt' - name: "Checkout repository" - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" uses: github/codeql-action/init@v2 diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 023a2318b..be5f3e57a 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -11,7 +11,7 @@ jobs: name: "Build" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: @@ -30,7 +30,7 @@ jobs: name: "Test and quality check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: @@ -80,7 +80,7 @@ jobs: java-version: '11' distribution: 'adopt' - name: "Checkout repository" - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" uses: github/codeql-action/init@v2 diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index f690b77a8..529efe1d9 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -10,7 +10,7 @@ jobs: name: "BULL Release" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 80795e231..721b579e6 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -10,7 +10,7 @@ jobs: name: "BULL Release" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Cache Maven repository" uses: actions/cache@v3.3.1 with: From 7d4f588173a1d0379438d66ea9aa4034073b3e5b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 13:25:05 +0000 Subject: [PATCH 1766/1786] Bump actions/cache from 3.3.1 to 3.3.2 (#438) * Bump actions/cache from 3.3.1 to 3.3.2 Bumps [actions/cache](https://github.com/actions/cache) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.3.1...v3.3.2) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index caab242fc..30f27173e 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: "Cache Maven repository" - uses: actions/cache@v3.3.1 + uses: actions/cache@v3.3.2 with: path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: "Cache Maven repository" - uses: actions/cache@v3.3.1 + uses: actions/cache@v3.3.2 with: path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.3.1 + uses: actions/cache@v3.3.2 with: path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index be5f3e57a..1593bfad8 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: "Cache Maven repository" - uses: actions/cache@v3.3.1 + uses: actions/cache@v3.3.2 with: path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: "Cache Maven repository" - uses: actions/cache@v3.3.1 + uses: actions/cache@v3.3.2 with: path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -69,7 +69,7 @@ jobs: security-events: write steps: - name: "Cache Maven repository" - uses: actions/cache@v3.3.1 + uses: actions/cache@v3.3.2 with: path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 529efe1d9..9ab44bd9a 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: "Cache Maven repository" - uses: actions/cache@v3.3.1 + uses: actions/cache@v3.3.2 with: path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index 721b579e6..a48fd83c8 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: "Cache Maven repository" - uses: actions/cache@v3.3.1 + uses: actions/cache@v3.3.2 with: path: $HOME/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From ef0722bc86404ef376b20548c67b3d6c672b563d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 13:44:41 +0000 Subject: [PATCH 1767/1786] Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.0 to 3.4.1 (#439) * Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.0 to 3.4.1 Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.4.0 to 3.4.1. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.4.0...enforcer-3.4.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7cbbc7b1e..5c23acc55 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ 3.0.0-M4 1.6.13 3.1.2 - 3.4.0 + 3.4.1 false From f21b0737410533eb4191b7cc8a8a3995acd0c830 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 15:54:23 +0000 Subject: [PATCH 1768/1786] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0 (#440) * Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.5.0...maven-javadoc-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5c23acc55..453e18c70 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ [3.8.1,) 3.1.0 - 3.5.0 + 3.6.0 3.3.0 2.16.0 10.12.3 From f89edbe2ee089224414d9f36665161f58e0121d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 16:28:29 +0000 Subject: [PATCH 1769/1786] Bump org.codehaus.mojo:versions-maven-plugin from 2.16.0 to 2.16.1 (#442) * Bump org.codehaus.mojo:versions-maven-plugin from 2.16.0 to 2.16.1 Bumps [org.codehaus.mojo:versions-maven-plugin](https://github.com/mojohaus/versions) from 2.16.0 to 2.16.1. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.16.0...2.16.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 453e18c70..7fd802b51 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.1.0 3.6.0 3.3.0 - 2.16.0 + 2.16.1 10.12.3 3.0.0-M4 1.6.13 From 0c4118ecca5501d7c86feeb56317b29a1057503d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 16:32:43 +0000 Subject: [PATCH 1770/1786] Bump org.projectlombok:lombok from 1.18.28 to 1.18.30 (#441) * Bump org.projectlombok:lombok from 1.18.28 to 1.18.30 Bumps [org.projectlombok:lombok](https://github.com/projectlombok/lombok) from 1.18.28 to 1.18.30. - [Release notes](https://github.com/projectlombok/lombok/releases) - [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown) - [Commits](https://github.com/projectlombok/lombok/compare/v1.18.28...v1.18.30) --- updated-dependencies: - dependency-name: org.projectlombok:lombok dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7fd802b51..204040a00 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 15 ${jdk.version} ${jdk.version} - 1.18.28 + 1.18.30 3.13.0 4.11.0 From 5ddda1e6f9c137cf2714497aa1349a901051f554 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:34:39 +0200 Subject: [PATCH 1771/1786] Bump com.puppycrawl.tools:checkstyle from 10.12.3 to 10.12.4 (#443) * Bump com.puppycrawl.tools:checkstyle from 10.12.3 to 10.12.4 Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.12.3 to 10.12.4. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.3...checkstyle-10.12.4) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 204040a00..bbd16dfc7 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.6.0 3.3.0 2.16.1 - 10.12.3 + 10.12.4 3.0.0-M4 1.6.13 3.1.2 From f60e7205aa0e6180f8ee3b41e0bdc186fb6d783c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 13:51:55 +0000 Subject: [PATCH 1772/1786] Bump org.jacoco:jacoco-maven-plugin from 0.8.10 to 0.8.11 (#444) * Bump org.jacoco:jacoco-maven-plugin from 0.8.10 to 0.8.11 Bumps [org.jacoco:jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.10 to 0.8.11. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.10...v0.8.11) --- updated-dependencies: - dependency-name: org.jacoco:jacoco-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bbd16dfc7..8fae089ac 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ 2.0.9 4.0.2 - 0.8.10 + 0.8.11 1.0 0.98 1.0 From bc4ceae33a1261e7603e242ec471443a0e64fc4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:53:48 +0000 Subject: [PATCH 1773/1786] Bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.3.0 to 3.3.1 (#445) * Bump org.apache.maven.plugins:maven-checkstyle-plugin Bumps [org.apache.maven.plugins:maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.3.0 to 3.3.1. - [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.3.0...maven-checkstyle-plugin-3.3.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8fae089ac..cde8ad897 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ [3.8.1,) 3.1.0 3.6.0 - 3.3.0 + 3.3.1 2.16.1 10.12.4 3.0.0-M4 From b83872e1d69ab2e8fd848bca774df17797e9bb27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Nov 2023 06:22:45 +0000 Subject: [PATCH 1774/1786] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.0 to 3.6.2 (#446) * Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.0 to 3.6.2 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.6.0 to 3.6.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.0...maven-javadoc-plugin-3.6.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cde8ad897..f74534418 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ [3.8.1,) 3.1.0 - 3.6.0 + 3.6.2 3.3.1 2.16.1 10.12.4 From e381826d9450753b1e4ea99a0369ac2cc1af4ab4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Nov 2023 15:27:42 +0100 Subject: [PATCH 1775/1786] Bump com.puppycrawl.tools:checkstyle from 10.12.4 to 10.12.5 (#447) * Bump com.puppycrawl.tools:checkstyle from 10.12.4 to 10.12.5 Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.12.4 to 10.12.5. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.4...checkstyle-10.12.5) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f74534418..75a2e1372 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.6.2 3.3.1 2.16.1 - 10.12.4 + 10.12.5 3.0.0-M4 1.6.13 3.1.2 From 4a023917bee453cad713126c3b923b68a7a9101d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Nov 2023 13:02:08 +0000 Subject: [PATCH 1776/1786] Bump org.codehaus.mojo:versions-maven-plugin from 2.16.1 to 2.16.2 (#448) * Bump org.codehaus.mojo:versions-maven-plugin from 2.16.1 to 2.16.2 Bumps [org.codehaus.mojo:versions-maven-plugin](https://github.com/mojohaus/versions) from 2.16.1 to 2.16.2. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.16.1...2.16.2) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 75a2e1372..84eb447a9 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.1.0 3.6.2 3.3.1 - 2.16.1 + 2.16.2 10.12.5 3.0.0-M4 1.6.13 From 5b23d88ab20c27c6118935e3d700f464a079c7fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:01:45 +0000 Subject: [PATCH 1777/1786] Bump org.apache.commons:commons-lang3 from 3.13.0 to 3.14.0 (#449) Bumps org.apache.commons:commons-lang3 from 3.13.0 to 3.14.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 84eb447a9..92c4fa651 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ ${jdk.version} ${jdk.version} 1.18.30 - 3.13.0 + 3.14.0 4.11.0 7.8.0 From 1d722c67863e548685c8a601a57a5d4b00119c3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 14:05:57 +0100 Subject: [PATCH 1778/1786] Bump actions/setup-java from 3 to 4 (#450) * Bump actions/setup-java from 3 to 4 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 6 +++--- .github/workflows/github-default-jdk11-actions.yml | 6 +++--- .github/workflows/github-jdk11-release-actions.yml | 2 +- .github/workflows/github-release-actions.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 30f27173e..4057d84d1 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -19,7 +19,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK set-up" - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '15' distribution: 'adopt' @@ -42,7 +42,7 @@ jobs: run: | echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "JDK set-up" - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '15' distribution: 'adopt' @@ -75,7 +75,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK set-up" - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '15' distribution: 'adopt' diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 1593bfad8..95423edba 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -19,7 +19,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK 11 set-up" - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '11' distribution: 'adopt' @@ -42,7 +42,7 @@ jobs: run: | echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} - name: "JDK 11 set-up" - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '11' distribution: 'adopt' @@ -75,7 +75,7 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: "JDK 11 set-up" - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '11' distribution: 'adopt' diff --git a/.github/workflows/github-jdk11-release-actions.yml b/.github/workflows/github-jdk11-release-actions.yml index 9ab44bd9a..61d06d6e6 100644 --- a/.github/workflows/github-jdk11-release-actions.yml +++ b/.github/workflows/github-jdk11-release-actions.yml @@ -29,7 +29,7 @@ jobs: run: | mvn versions:set -D newVersion=${TAG_NAME} - name: "JDK set-up" - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '11' distribution: 'adopt' diff --git a/.github/workflows/github-release-actions.yml b/.github/workflows/github-release-actions.yml index a48fd83c8..c4cbe8821 100644 --- a/.github/workflows/github-release-actions.yml +++ b/.github/workflows/github-release-actions.yml @@ -29,7 +29,7 @@ jobs: run: | mvn versions:set -D newVersion=${TAG_NAME} - name: "JDK set-up" - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '15' distribution: 'adopt' From 003e5548f57be50945da2e77a39ac3c3cfca381a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 09:22:46 +0000 Subject: [PATCH 1779/1786] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.2 to 3.6.3 (#451) * Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.2 to 3.6.3 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.6.2 to 3.6.3. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.2...maven-javadoc-plugin-3.6.3) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 92c4fa651..02c43bb1b 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ [3.8.1,) 3.1.0 - 3.6.2 + 3.6.3 3.3.1 2.16.2 10.12.5 From a14a4ec6b0e26b09f9d36eec09215ae45c7c1546 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 12:09:41 +0000 Subject: [PATCH 1780/1786] Bump com.puppycrawl.tools:checkstyle from 10.12.5 to 10.12.6 (#452) * Bump com.puppycrawl.tools:checkstyle from 10.12.5 to 10.12.6 Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.12.5 to 10.12.6. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.5...checkstyle-10.12.6) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 02c43bb1b..d48e59b0e 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.6.3 3.3.1 2.16.2 - 10.12.5 + 10.12.6 3.0.0-M4 1.6.13 3.1.2 From 488bf4a89cf7949c91aae0226d2be28b2f49a800 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 17:27:19 +0000 Subject: [PATCH 1781/1786] Bump github/codeql-action from 2 to 3 (#453) * Bump github/codeql-action from 2 to 3 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v2...v3) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- .github/workflows/github-default-actions.yml | 4 ++-- .github/workflows/github-default-jdk11-actions.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-default-actions.yml b/.github/workflows/github-default-actions.yml index 4057d84d1..7c3c9bcf9 100644 --- a/.github/workflows/github-default-actions.yml +++ b/.github/workflows/github-default-actions.yml @@ -83,10 +83,10 @@ jobs: uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: 'java' - run: | mvn clean install -B -DskipTests -P fast - name: "Perform Analysis" - uses: github/codeql-action/analyze@v2 \ No newline at end of file + uses: github/codeql-action/analyze@v3 \ No newline at end of file diff --git a/.github/workflows/github-default-jdk11-actions.yml b/.github/workflows/github-default-jdk11-actions.yml index 95423edba..8f5187efc 100644 --- a/.github/workflows/github-default-jdk11-actions.yml +++ b/.github/workflows/github-default-jdk11-actions.yml @@ -83,10 +83,10 @@ jobs: uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: "Initialize CodeQL" - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: 'java' - run: | mvn clean install -B -DskipTests -P fast - name: "Perform Analysis" - uses: github/codeql-action/analyze@v2 \ No newline at end of file + uses: github/codeql-action/analyze@v3 \ No newline at end of file From 38352060b316bd100dab1a0ce388f9c8c26b6e33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Dec 2023 10:06:59 +0100 Subject: [PATCH 1782/1786] Bump org.testng:testng from 7.8.0 to 7.9.0 (#454) * Bump org.testng:testng from 7.8.0 to 7.9.0 Bumps [org.testng:testng](https://github.com/testng-team/testng) from 7.8.0 to 7.9.0. - [Release notes](https://github.com/testng-team/testng/releases) - [Changelog](https://github.com/testng-team/testng/blob/master/CHANGES.txt) - [Commits](https://github.com/testng-team/testng/compare/7.8.0...7.9.0) --- updated-dependencies: - dependency-name: org.testng:testng dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d48e59b0e..a2cd975e8 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.14.0 4.11.0 - 7.8.0 + 7.9.0 3.24.2 2.12.5 From 703112344f419d2522383a8f52908abba6abfa2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 19:45:30 +0000 Subject: [PATCH 1783/1786] Bump org.slf4j:slf4j-api from 2.0.9 to 2.0.10 (#455) * Bump org.slf4j:slf4j-api from 2.0.9 to 2.0.10 Bumps org.slf4j:slf4j-api from 2.0.9 to 2.0.10. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a2cd975e8..3d11cd0d8 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ 8.0.0.Final 3.5.3.Final 2.2.1.Final - 2.0.9 + 2.0.10 4.0.2 0.8.11 From 6c32cdc2c70fa2541783e6ab9d2882500953d50a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 16:21:47 +0000 Subject: [PATCH 1784/1786] Bump com.puppycrawl.tools:checkstyle from 10.12.6 to 10.12.7 (#456) * Bump com.puppycrawl.tools:checkstyle from 10.12.6 to 10.12.7 Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.12.6 to 10.12.7. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.12.6...checkstyle-10.12.7) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3d11cd0d8..2e7aad678 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.6.3 3.3.1 2.16.2 - 10.12.6 + 10.12.7 3.0.0-M4 1.6.13 3.1.2 From a4ad09a94a0c49cb3ff3aeef445aa25aba9b9f5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 16:24:37 +0000 Subject: [PATCH 1785/1786] Bump org.assertj:assertj-core from 3.24.2 to 3.25.0 (#457) * Bump org.assertj:assertj-core from 3.24.2 to 3.25.0 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.24.2 to 3.25.0. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.24.2...assertj-build-3.25.0) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2e7aad678..9f55646da 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 4.11.0 7.9.0 - 3.24.2 + 3.25.0 2.12.5 8.0.0.Final From b10688b020ab3630024feac7372e642846973ae6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 13:24:06 +0000 Subject: [PATCH 1786/1786] Bump org.assertj:assertj-core from 3.25.0 to 3.25.1 (#458) * Bump org.assertj:assertj-core from 3.25.0 to 3.25.1 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.25.0 to 3.25.1. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.25.0...assertj-build-3.25.1) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Trigger notification --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabio Borriello --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9f55646da..ca8c657b9 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 4.11.0 7.9.0 - 3.25.0 + 3.25.1 2.12.5 8.0.0.Final

      + * This module is intended for internal usage in Bull as it's a low-level wrapper for + * runtime compilation of models. Use it directly only if you need to customize the runtime + * compilation and loading of models. + * Clients should prefer higher level interfaces such as {@code TransformerRegistry} + * to obtain generated transformer instances. + */ +package com.expediagroup.beans.generator.bytecode; diff --git a/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/TransformerBytecodeAdapterTest.java b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/TransformerBytecodeAdapterTest.java new file mode 100644 index 000000000..7bc8fa051 --- /dev/null +++ b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/TransformerBytecodeAdapterTest.java @@ -0,0 +1,169 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.bytecode; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.MockitoAnnotations.openMocks; + +import static com.expediagroup.beans.generator.bytecode.TransformerBytecodeAdapter.DEFAULT_PACKAGE; + +import java.io.IOException; + +import org.mockito.Mock; +import org.mockito.Spy; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import com.expediagroup.beans.generator.bytecode.sample.TransformerCtorThrows; +import com.expediagroup.beans.generator.bytecode.sample.TransformerCtorWithArgs; +import com.expediagroup.beans.generator.bytecode.sample.TransformerPrivateCtor; +import com.expediagroup.beans.generator.core.Transformer; +import com.expediagroup.beans.generator.core.TransformerSpec; +import com.expediagroup.beans.generator.core.error.TransformerGeneratorException; +import com.expediagroup.beans.generator.core.mapping.MappingCodeFactory; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; +import com.itranswarp.compiler.JavaStringCompiler; + +/** + * Tests for {@link TransformerBytecodeAdapter}. + */ +public class TransformerBytecodeAdapterTest { + @Spy + private final TransformerSpec spec = new TransformerSpec(MappingCodeFactory.newInstance()); + + @Mock + private JavaStringCompiler compiler; + + /** + * The class to be tested. + */ + private TransformerBytecodeAdapter underTest; + + @BeforeMethod + private void beforeMethod() { + openMocks(this); + underTest = TransformerBytecodeAdapter.builder() + .spec(spec) + .build(); + } + + @Test + public void shouldCreateANewTransformerWithGivenSpec() { + // WHEN + var actual = underTest.newTransformer(Source.class, Destination.class); + + // THEN + assertThat(actual).as("a new Transformer instance is never null") + .isNotNull(); + then(spec).should().build(Source.class, Destination.class); + } + + @Test + public void shouldCreateANewTransformerWithDefaultPackage() { + // WHEN + var actual = underTest.newTransformer(Source.class, Destination.class); + + // THEN + assertThat(actual.getClass()).hasPackage(DEFAULT_PACKAGE); + } + + @Test + public void shouldCreateANewTransformerWithGivenPackage() { + // GIVEN + var packageName = "foo.bar"; + underTest = TransformerBytecodeAdapter.builder() + .packageName(packageName) + .spec(spec) + .build(); + + // WHEN + var actual = underTest.newTransformer(Source.class, Destination.class); + + // THEN + assertThat(actual.getClass()).hasPackage(packageName); + } + + @Test(expectedExceptions = TransformerGeneratorException.class) + public void shouldThrowRuntimeExceptionIfCompilationFails() throws Exception { + // GIVEN + underTest = TransformerBytecodeAdapter.builder() + .compiler(mockCompilationFail()) + .spec(spec) + .build(); + + // WHEN + underTest.newTransformer(Source.class, Destination.class); + } + + @Test(expectedExceptions = TransformerGeneratorException.class) + public void shouldThrowRuntimeExceptionIfLoadingFails() throws Exception { + // GIVEN + underTest = TransformerBytecodeAdapter.builder() + .compiler(mockLoadingFail()) + .spec(spec) + .build(); + + // WHEN + underTest.newTransformer(Source.class, Destination.class); + } + + @Test(dataProvider = "nonCompliantTransformers", expectedExceptions = TransformerGeneratorException.class) + public void shouldThrowRuntimeExceptionIfTransformerIsNonCompliant(final Class trClass) + throws Exception { + // GIVEN + underTest = TransformerBytecodeAdapter.builder() + .compiler(mockCompilerReturning(trClass)) + .spec(spec) + .build(); + + // WHEN + underTest.newTransformer(Source.class, Destination.class); + } + + @DataProvider + public static Object[][] nonCompliantTransformers() { + return new Object[][]{ + {TransformerPrivateCtor.class}, + {TransformerCtorWithArgs.class}, + {TransformerCtorThrows.class} + }; + } + + private JavaStringCompiler mockCompilationFail() throws IOException { + return given(compiler.compile(anyString(), anyString())) + .willThrow(IOException.class) + .getMock(); + } + + private JavaStringCompiler mockLoadingFail() throws ClassNotFoundException, IOException { + return given(compiler.loadClass(anyString(), anyMap())) + .willThrow(ClassNotFoundException.class) + .getMock(); + } + + @SuppressWarnings("unchecked") + private JavaStringCompiler mockCompilerReturning(final Class trClass) throws Exception { + return (JavaStringCompiler) given(compiler.loadClass(anyString(), anyMap())) + .willReturn(trClass) + .getMock(); + } +} diff --git a/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/package-info.java b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/package-info.java new file mode 100644 index 000000000..44d760c18 --- /dev/null +++ b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Tests for the bytecode adapter. + */ +package com.expediagroup.beans.generator.bytecode; diff --git a/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerBytecodeAdapterExample.java b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerBytecodeAdapterExample.java new file mode 100644 index 000000000..67f0e9290 --- /dev/null +++ b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerBytecodeAdapterExample.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.bytecode.sample; + +import static org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString; + +import static lombok.AccessLevel.PRIVATE; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.expediagroup.beans.generator.bytecode.TransformerBytecodeAdapter; +import com.expediagroup.beans.generator.core.Transformer; +import com.expediagroup.beans.generator.core.TransformerSpec; +import com.expediagroup.beans.generator.core.mapping.MappingCodeFactory; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; + +import lombok.NoArgsConstructor; + +/** + * Example of generating and using a Transformer at runtime. + */ +@NoArgsConstructor(access = PRIVATE) +public final class TransformerBytecodeAdapterExample { + private static Destination getExpectedResult() { + Destination destination = new Destination(); + destination.setABoolean(true); + destination.setAString("hello"); + return destination; + } + + /** + * Entry point for manual testing. + * Run this to compare the usage of a generated transformer with the above reference result. + * @param args the args + */ + public static void main(final String[] args) { + // create a transformer model + TransformerSpec spec = new TransformerSpec(MappingCodeFactory.newInstance()); + // create a bytecode adapter for the model + TransformerBytecodeAdapter bytecode = TransformerBytecodeAdapter.builder() + .spec(spec) + .build(); + // generate and compile a new Transformer + Transformer transformer = bytecode.newTransformer(Source.class, Destination.class); + + final int anInt = 42; + Source source = new Source(); + source.setABoolean(true); + source.setAnInt(anInt); + source.setAString("hello"); + // use the generated Transformer + Destination destination = transformer.transform(source); + + ToStringBuilder.setDefaultStyle(ToStringStyle.SHORT_PREFIX_STYLE); + System.out.printf("Transformed: %s%n", reflectionToString(destination)); + System.out.printf("Expected: %s%n", reflectionToString(getExpectedResult())); + } +} diff --git a/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerCtorThrows.java b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerCtorThrows.java new file mode 100644 index 000000000..904bfcdf7 --- /dev/null +++ b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerCtorThrows.java @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.bytecode.sample; + +import com.expediagroup.beans.generator.core.Transformer; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; + +/** + * Non-compliant transformer implementation: constructor throws exception. + */ +public final class TransformerCtorThrows implements Transformer { + TransformerCtorThrows() { + throw new RuntimeException("simulated error"); + } + + @Override + public Destination transform(final Source source) { + return null; + } +} diff --git a/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerCtorWithArgs.java b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerCtorWithArgs.java new file mode 100644 index 000000000..8edaa424b --- /dev/null +++ b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerCtorWithArgs.java @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.bytecode.sample; + +import com.expediagroup.beans.generator.core.Transformer; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; + +/** + * Non-compliant transformer implementation: constructor has arguments. + */ +public final class TransformerCtorWithArgs implements Transformer { + TransformerCtorWithArgs(final Object arg) { + } + + @Override + public Destination transform(final Source source) { + return null; + } + +} diff --git a/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerPrivateCtor.java b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerPrivateCtor.java new file mode 100644 index 000000000..c8f5e9f70 --- /dev/null +++ b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/TransformerPrivateCtor.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.bytecode.sample; + +import static lombok.AccessLevel.PRIVATE; + +import com.expediagroup.beans.generator.core.Transformer; +import com.expediagroup.beans.generator.core.sample.javabean.Destination; +import com.expediagroup.beans.generator.core.sample.javabean.Source; + +import lombok.NoArgsConstructor; + +/** + * Non-compliant transformer implementation: constructor is not accessible. + */ +@NoArgsConstructor(access = PRIVATE) +public final class TransformerPrivateCtor implements Transformer { + @Override + public Destination transform(final Source source) { + return null; + } +} diff --git a/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/package-info.java b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/package-info.java new file mode 100644 index 000000000..66298b47c --- /dev/null +++ b/bull-transformer-generator/transformer-bytecode-adapter/src/test/java/com/expediagroup/beans/generator/bytecode/sample/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Example usage of the bytecode adapter plus other sample types used in tests. + */ +package com.expediagroup.beans.generator.bytecode.sample; diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/Transformer.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/Transformer.java new file mode 100644 index 000000000..d40f75b68 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/Transformer.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core; + +/** + * A {@code Transformer} can convert an object of a source type to a destination type. + * @param the source type + * @param the destination type + */ +public interface Transformer { + /** + * Transform an instance of {@code A} into a new instance of {@code B}. + * The destination instance is initialized with values copied from the source. + * Values can be optionally transformed depending on the implementation. + * @param source the source object to convert + * @return a new instance of {@code B} initialized + */ + B transform(A source); +} diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/TransformerSpec.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/TransformerSpec.java new file mode 100644 index 000000000..b8c14b2ff --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/TransformerSpec.java @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core; + +import static javax.lang.model.element.Modifier.PUBLIC; + +import java.lang.reflect.Method; +import java.text.MessageFormat; + +import com.expediagroup.beans.generator.core.mapping.MappingCodeFactory; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeSpec; + +import lombok.RequiredArgsConstructor; + +/** + * This class is used to build a {@link Transformer} implementation model to map between a source and destination types. + * The model is a {@link TypeSpec} object that can be further modified if needed, and serialized to source code. + */ +@RequiredArgsConstructor +public class TransformerSpec { + /** + * A reusable reference to {@link Transformer#transform(Object)} method. + */ + private static final Method TRANSFORM = Transformer.class.getMethods()[0]; + + /** + * A {@link MappingCodeFactory} to create code blocks. + */ + private final MappingCodeFactory codeFactory; + + /** + * Build a transformer model to map from a {@code source} to {@code destination} type. + * The generated model implements the {@link Transformer} interface and provides mapping code + * to instantiate a destination object and map values from the source object. + * @param the source type + * @param the destination type + * @param source the source to read values from + * @param destination the destination where to map values + * @return a transformer model + */ + public TypeSpec build(final Class source, final Class destination) { + return TypeSpec.classBuilder(nameWith(source, destination)) + .addModifiers(PUBLIC) + .addSuperinterface(ParameterizedTypeName.get(Transformer.class, source, destination)) + .addMethod(overrideTransform(source, destination) + .addCode(codeFactory.of(source, destination).build()) + .build()) + .build(); + } + + /** + * Creates a name for the transformer implementation that includes {@code source} and {@code destination}. + * @param source the source type + * @param destination the destination type + * @return a transformer name + */ + private String nameWith(final Class source, final Class destination) { + return MessageFormat.format("{0}To{1}Transformer", source.getSimpleName(), destination.getSimpleName()); + } + + /** + * Creates a {@link MethodSpec.Builder} configured with the declaration to override + * the {@link Transformer#transform(Object)} method. + * @param source the source type + * @param destination the destination type + * @return a method builder with overridden transform() declaration + */ + private MethodSpec.Builder overrideTransform(final Class source, final Class destination) { + return MethodSpec.methodBuilder(TRANSFORM.getName()) + .addAnnotation(Override.class) + .addModifiers(PUBLIC) + .addParameter(source, "source") + .returns(destination); + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/error/TransformerGeneratorException.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/error/TransformerGeneratorException.java new file mode 100644 index 000000000..ab7e48b8e --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/error/TransformerGeneratorException.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.error; + +/** + * Transformer exception class. + */ +public class TransformerGeneratorException extends RuntimeException { + /** + * Constructs a new transformer generator exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * @param message the detail message. The detail message is saved for later + * retrieval by the {@link #getMessage()} method. + * @param cause the given bean is not valid and caused an exception while copying the properties. + */ + public TransformerGeneratorException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/error/package-info.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/error/package-info.java new file mode 100644 index 000000000..3b19b5403 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/error/package-info.java @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Exceptions package. + */ +package com.expediagroup.beans.generator.core.error; diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/BeanProperty.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/BeanProperty.java new file mode 100644 index 000000000..8f274da58 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/BeanProperty.java @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.mapping; + +import static com.expediagroup.transformer.constant.MethodPrefix.IS; + +import java.lang.reflect.Method; + +import org.apache.commons.lang3.StringUtils; + +import lombok.EqualsAndHashCode; + +/** + * Represents a property underlying a method according to JavaBean conventions. + * The {@code toString()} implementation returns the property name. + */ +@EqualsAndHashCode +final class BeanProperty { + /** + * The length of a short prefix, usually "is". + */ + private static final int SHORT_PREFIX_LENGTH = 2; + + /** + * The length of a regular prefix, such as "get" or "set". + */ + private static final int REGULAR_PREFIX_LENGTH = 3; + + /** + * The property name. Retains the same case as in the method name, + * minus the prefix. + */ + private final String name; + + /** + * Instantiates a new Bean property for the given {@code accessor}. + * @param accessor a JavaBean accessor method + */ + BeanProperty(final Method accessor) { + var methodName = accessor.getName(); + this.name = methodName.startsWith(IS.getPrefix()) + ? methodName.substring(SHORT_PREFIX_LENGTH) + : methodName.substring(REGULAR_PREFIX_LENGTH); + } + + @Override + public String toString() { + return StringUtils.uncapitalize(name); + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/JavaBeanCode.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/JavaBeanCode.java new file mode 100644 index 000000000..6ce7bd387 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/JavaBeanCode.java @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.mapping; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import com.expediagroup.transformer.utils.ClassUtils; +import com.squareup.javapoet.CodeBlock; + +/** + * A specialization of {@link MappingCode} that generates code for mapping between two JavaBeans. + * The creation code uses the default no-arg constructor. + * The initialization code uses the available destination setters to map the source getters. + */ +class JavaBeanCode extends MappingCode { + /** + * The source type. + */ + private final Class source; + + /** + * The destination type. + */ + private final Class destination; + + /** + * Instantiates a new JavaBean code model, source and destination types must be JavaBeans. + * @param sourceBean the source + * @param destinationBean the destination + * @param classUtils an utility for introspecting types + */ + JavaBeanCode(final Class sourceBean, final Class destinationBean, final ClassUtils classUtils) { + super(classUtils); + this.source = sourceBean; + this.destination = destinationBean; + } + + /** + * Models the instantiation of destination type with no-arg constructor. + */ + @Override + protected CodeBlock creation() { + return CodeBlock.of("$T destination = new $T()", destination, destination); + } + + /** + * Models the mapping from a source type to a mutable destination type. + */ + @Override + protected CodeBlock initialization() { + final CodeBlock.Builder builder = CodeBlock.builder(); + final ClassUtils classUtils = getClassUtils(); + final List setters = classUtils.getSetterMethods(destination); + for (Method getter : classUtils.getGetterMethods(source)) { + findCorrespondingSetter(getter, setters) + .ifPresent(setter -> + builder.addStatement("destination.$N(source.$N())", setter.getName(), getter.getName())); + } + return builder.build(); + } + + /** + * Searches among {@code setters} for a method corresponding to the same property of a {@code getter}. + * @param getter a getter in the source type + * @param setters all the setters in the destination type + * @return an Optional containing a setter method or empty if not found + */ + private Optional findCorrespondingSetter(final Method getter, final Collection setters) { + final BeanProperty property = new BeanProperty(getter); + return setters.stream() + .filter(s -> new BeanProperty(s).equals(property)) + .findFirst(); + } + +} diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/MappingCode.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/MappingCode.java new file mode 100644 index 000000000..26aa13284 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/MappingCode.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.mapping; + +import com.expediagroup.transformer.utils.ClassUtils; +import com.squareup.javapoet.CodeBlock; + +/** + * This is the base class for modeling the code block that maps a source object to a destination object. + * Subclasses must provide an implementation of {@code creation()} and {@code initialization()} methods, + * to create mapping code specialized for different kinds of source and destination. + */ +public abstract class MappingCode { + /** + * A reusable instance of ClassUtils for introspecting types. + */ + private final ClassUtils classUtils; + + /** + * Instantiates a new Mapping code with the given ClassUtils. + * @param clsUtils an utility for introspecting types + */ + MappingCode(final ClassUtils clsUtils) { + this.classUtils = clsUtils; + } + + /** + * Build the mapping code block. + * @return the code block + */ + public final CodeBlock build() { + return CodeBlock.builder() + .addStatement(creation()) + .add(initialization()) + .addStatement(returning()) + .build(); + } + + /** + * Creation code statement, models the instantiation of the destination type. + * Implementing classes must know how to create an instance of the destination type. + * By convention the instance identifier must be "destination". + * @return the code block + */ + protected abstract CodeBlock creation(); + + /** + * Initialization code block, models the mapping between the source and destination types. + * Implementing classes must know which properties to map, how to access values from both types, + * and how to apply transformations. + * By convention the instance identifiers must be "source" and "destination". + * @return the code block + */ + protected abstract CodeBlock initialization(); + + /** + * Returning code statement, models the returning of the destination instance. + * Implementing classes usually do not need to override this method, unless they have a particular reason. + * By convention the instance identifier must be "destination". + * @return the code block + */ + protected CodeBlock returning() { + return CodeBlock.of("return destination"); + } + + /** + * Gets class utils instance. + * @return the class utils + */ + protected final ClassUtils getClassUtils() { + return classUtils; + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/MappingCodeFactory.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/MappingCodeFactory.java new file mode 100644 index 000000000..594be5a5c --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/MappingCodeFactory.java @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.beans.generator.core.mapping; + +import static com.expediagroup.transformer.validator.Validator.notNull; + +import static lombok.AccessLevel.PRIVATE; + +import org.apache.commons.lang3.NotImplementedException; + +import com.expediagroup.transformer.constant.ClassType; +import com.expediagroup.transformer.utils.ClassUtils; +import com.squareup.javapoet.CodeBlock; + +import lombok.RequiredArgsConstructor; + +/** + * A factory to obtain an instance of {@link MappingCode}. + */ +@RequiredArgsConstructor(access = PRIVATE) +public final class MappingCodeFactory { + /** + * An instance of ClassUtils. + */ + private final ClassUtils classUtils; + + /** + * Gets an instance of {@code MappingCodeFactory}. + * @return a MappingCode instance + */ + public static MappingCodeFactory newInstance() { + return newInstance(new ClassUtils()); + } + + /** + * Gets an instance of {@code MappingCodeFactory} with the provided classUtils. + * @param classUtils the class utils + * @return a MappingCode instance + */ + public static MappingCodeFactory newInstance(final ClassUtils classUtils) { + return new MappingCodeFactory(classUtils); + } + + /** + * Obtains an instance of {@code MappingCode} from a source and destination. + * The returned instance is specialized to create a {@link CodeBlock} for mapping + * an object of a source type to a destination type. + * @param source the source type + * @param destination the destination type + * @return the mapping code from source to destination + */ + public MappingCode of(final Class source, final Class destination) { + notNull(source, "source type can't be null"); + notNull(destination, "destination type can't be null"); + ClassType classType = classUtils.getClassType(destination); + switch (classType) { + case MUTABLE: + return new JavaBeanCode(source, destination, classUtils); + case IMMUTABLE: + throw new NotImplementedException("Transformation code for type IMMUTABLE is not supported"); + case MIXED: + throw new NotImplementedException("Transformation code for type MIXED is not supported"); + default: + throw new AssertionError("Unable to determine MappingCode implementation: " + + "destination class type '" + classType + "' is unsupported. " + + "Please modify this method to handle the case or check the implementation of " + + "com.expediagroup.transformer.utils.ClassUtils.getClassType"); + } + } +} diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/package-info.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/package-info.java new file mode 100644 index 000000000..d318a228a --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/mapping/package-info.java @@ -0,0 +1,22 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Provides the models of code blocks that map a source type to a destination type, + * specialized for different kind of classes, like: mutable, immutable and mixed. + * The main entry point to obtain a mapping model is the factory method + * {@link com.expediagroup.beans.generator.core.mapping.MappingCode#of(java.lang.Class, java.lang.Class)}. + */ +package com.expediagroup.beans.generator.core.mapping; diff --git a/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/package-info.java b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/package-info.java new file mode 100644 index 000000000..1affc99f2 --- /dev/null +++ b/bull-transformer-generator/transformer-generator-core/src/main/java/com/expediagroup/beans/generator/core/package-info.java @@ -0,0 +1,25 @@ +/** + * Copyright (C) 2019-2021 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Contains the main transformer model constructed as a {@link com.squareup.javapoet.TypeSpec} object. + * A model can then be further modified and eventually converted to source code or byte code. + * The main class to obtain a transformer model is {@link com.expediagroup.beans.generator.core.TransformerSpec}, + * which can create transformers from type {@code A} to type {@code B}. + *

      ?2=x_f#H~v zXZfL2T6x&h&9hF@nM1m(kEW8Yg=$@94eW0Z-%AaMso_I2gpz6UbVhd`Jyknj!%wkYdK* zV}!(JoF|MpOa({lvOes8ZStqZ676QxxU^wulc7!+XbcTeOM=_3m-t`LEwssvEILnU zbXJgg5STWEo7BcBIceUV9{M@}F%~Ss1z}kO@qV_lY^I0TY#05}I4cOexEiaYG=>Yc zI!p^7bobdanudQY@ekOU4@5Mc2_K^s3MKLRVXC;S!NttMM*v%F-oPS_(;v@KL~dKs z;t6smLZtL%vu3-*)-VEmG&m+cV{We{YA?ag9ipw7L!Z~(;Xr7_A5OMnV)s;0u=~F4 z7Fjp0KqqP(V;%_Amyz~mSC!#WOVya)CF=ss-krW1;#D%qbgx6g#49m{ z7tFrJPS$v4hX;dZpz36*eXC-%E8%)U%VhW~w}zFE#YCORGPjpu-gYY4KWmZksb1Dx zEpz47B|)pIOP*p{ot*8_9Q}at-3=Zo^Kz~~JH4D<)1yuD0*v4j&|7Y9&3#0+t!gqK z5A3dHBCHSv29_xwWZ(lr2`4yCiWQSPC)2GQQw^T9Y5k~l+x?TczADuXll^v3(K(?D z6DuS7Lr7(=Ae8Yif825GA+%jdQ>k&b@!TdK>-$Gx?3a8-6(O!7JfUzrv!;N^Rv-ny1=zqDw*SrmQ)K z*6{J49p1x7R^?jIHt@4}R?zVm#1UmAx;zRz{L~y|@=d)O*Z&P*Iw{$`WnYLhtNqKf zkNgBTtS592&JX$2w7!|JRZW5gMIY9orpA_kiu5MG0>5?f>N|}$-Zt}QTyph!_`{C z9N&RK-YGgNWSzeUeedrvUSI8*ti)&LUTi;nj_Rs9^xSZ$y|ZZQW3I0Hy?N_R7bbf3 zrp#Y;Zo5)rhv8%$#^_)?(Gyn@Z2ATcg)!}lcSrj}y+~1G=LaG~_N_eitSwtmHN0PG zF74bz)KNM*M7VmC->oI3;&#{k&xfb)gih8ATHJ-;JsFi;c`6S$U_ZScjQF7f4hygz zsQ|!o=d_5vfm=xN>`#+adgv>4fs4q<|Edp!@11Ef>d_WSS(yl8l1MVi%&HDlx+N;J zN>TSoXF-Q1o|jsb1tPx7cizD#SNMe$f+j0ZsFRY=j_J9E+gv01#j1f(dSW|pldIY1 z$arZid+)!QUUw?6K4>wO*ByX5(oo88fv>|6a8#9f;b|PY$v#(${=`?i-yyx_ol$CC z>X11xAmrBI(l|3n+fJ@-@tU!$Ew6DAwVDQbNp+9$Q?(()88dPHatAa3_)5zPSjBj$F1wh+ewP---UxJB9}Z?~ELx)abf zG0^cUmdQQ>?QFZPO;O(!v6Ap{&3*jaaL5Ea7lUTfSj@(??$egdRV#v)_JPH0=7Psz zu349{@i1EFAwH}AQE+|O%>J|aizNlX-g6~!X|yjCa;&vJJ=`N zO+X2EUnD>F8i>PlyXGVUDwXzwp~Ldy@G?Q01{Ga+#EZby4{SFS=)L;-6Xnk4Q|*)r zCn>h7*yfNJbw0L(v$hu3NCMAq$bWWR!oxZ-x!8-S*)0}IIsvZ{LDCU=!`lyFI`;`v z7XORLT&Tioig6W|&;1%EEJ`PO^LICPRH!(=7VlsBS(TC)Op8Z@SKu8g;7|iYI zTmSLdw#TV}AOEc5_qIm5L|LfnJD2tfpUFbEWQxI-i2?Iz;8IY$MzqfxAM?6Q4!5Nw zK%t2^+yOoxv|*Xm_pV?ghERcgi#OM_h2dCoF8&Br$iar_Iw@9$o*Rtqde=8V?O@J# zU1=qhI2OpAB1WH48iXc3ZTY~fQcKj^8-rC!utA^r(2LC7F&H}@8L?6nJKLBMtvuZH zU=}~3{LIPlYop>|>?fI*m@&gZyFu+=*1rAdSE$67g%-;kDgSgKUgL^F{xbU6T`Gk& zStIQpmwj+S@aspx?o$J6_WFOrqGZ#CvWwov;XbCRQGElMuSX6_){cgjH{hrszL#>eheYxjyoKk_N#U zXkmQFs!IW?5IwE?bR(X3XY}W0aFLUubWqznvif{E0w;BwCTEP*uf}bkC7$JYKR()n zQcLNDzQ_cMPVr>kV2n)=skQ8CkC34|f&sFxdewQk@A-(wyeSQ~SdmtD+TDe7E}ui6|^4vQ(pPCz6`usD4~*E zTYR21m3Xn*IlCpXj_(nM4c1rks5w6tSKgxtM{ivdzpgyE-P|1qm2qtKw+lrQ4?mIj zlEd-4mcU66$3pD{uXRpaI0OYR*+JX)L1exCfCTJoLVE5Th$?{i{FjWWpNLcuo{x|v zYJm;-6^i%$wpe$zjFyF@X7s4Q4gVD)?rjVRxuUJ~`~w-R5WfSJ!d=%@BNF|-YK$8X zlWJ}cb|o7%tga)i{i7^xzD0%=cuG>t%`3g#4pXyVu19HEY=D}OrQAO|^ajN3NOaW5 zQC_3uFFgknK<$QU+jy zoleTdcFGxy5w$ylwnk3ok>;Z>+ZT}u;fPuLzlp~9+?T!M(fkV)R^ zZ_h?W*oPIi(^X~zaoz#il&{%?>iOJwcFDp!UCz1MY)WL|$MQHv$2vi%aJo?NXi&mI zSuO$cb`Jb&!XqxOt}xE{-213R@AZ-A5^g5_p&D*DdHoWOLLeMzE3lOWH-K-|#s)kY zHQRVxT33ekIrcyy0#yNt6H{sS%}P=kbt!`p!xb2Pnw_$)iD+N@X2GQGukg4RGy;%@ zp)u#|eIl5OAb0#!vWdHY^o$ zjW2Jo=_8zPda`z)j-bM$vGo#B>hK)jvw{a|Soat<_$pU-sza)oN!1}{Sn;2_4e7Kp z=ZZ6$*J8J$rYOJk_!svD#&(@)PoKZ#Vd}NIb^$!wA&$I+u(NQZyOKf&wa?bRb4{d3HMeMjTAI z@KwvS-=j9OFYKv;8;^pODB%AOOjZc=140#3zVx$q9T9@B-L}V4FRR5a*ru4`0|v|^ zio5^NwSf~;7nqY?r6mbaSE;Iqu3RoW>Wx!R%R$dtpZRK1cfQGKr684Ji0)+w6U@3w1RMw`2S)1{w4r(7A;HGD>X+6J^`!FCe6!SJ%0I~z3 ztK7LvWbGoSN?n8p0I#a-9s@w}b@CbOF@*+s)yR>f{|0Q!snr@>$sHm%j7I-4)ekNo(w@Yw8# zw2M@!aC(2NgQNp0HP!IwfyPktI^j#^9M8a1U02@<Z) zah^xxHqVcLqwf&~z*ZJ>?F-dHa~J5(ru$@uuS(XpS9s=JhvXB;=j-fX@8;}Cc4C$E zI}yGGE~pOwfSO1+8{9h;aP-+|w_f89!VpL5)=LASq(05qw|bXf(qr`DUrE@ zmxrcxz=C8hp9T_`9|BowM^8KLUZni&m(?s;EH^KmR~%gLw)My!Y&8Xh+Ij%Z$zg6ffQF5Tr9I_nZi@?V%Xuj%9sS=z5AoGJvY%Lw=lPUFc3|F?Cj1FvJL9erYzsEnT+68SjxcZfggM`b9_|Gsi+ceJxAH(eq{NQ%#Qz`3=7uLkzzX} zcAF51{poi9oWwLte{ZpKUJM>0|6(t0KmTXPCqs*!|4jXBLYSwefbrBwhV4EPar>dz zz?V!-a|YF#c&sUzx9lX57_bRv?qv`S9vDMr6DWu zmG!c6x9mk6Q3o8(H>Vk<_t@6K zW@Zg(Ea!7|r|dhe`(M~}C8oSp_vQ<&ujrWO=q9~fy14PbFXsWi#9U+CjOpnNZ7O+~ zXZ!0zotHqK!62=*!e)%dx77g0k2r#f!#Flv6XmykpB~|oZgX|bjr%Gdh(x1_i6B{$ z`dv73wF$mq4`mYG{^76A6(<>D!fOa_cJ0vTyc;*RsWlF@9e3s~;l9>(KqO(FaNUwU z!W`%_-T}Qm(7?;RS+rPghC4I>7iM!?)S3-2l`h$YVT1nqAGU#I{N)AJpB6o|oXP|C zUQt)}8$ZzHbMzm!%MBhOG+ta;czW|pyNa~?gQdaUP$GmT*z0HBEtHT?Z*Y;)b0&7r z^>}Q|gEWmuDRT3gu%EVdX2s2)u*EE@>MTkXYZ8L_&tSY4v{ukcrp(qpY@ibEF(3a- zOWFAEw~@V(<8QpFna$19ZsQwv`-&d_49RV}My~S@ynFMvt}nkc;H$}0CvDCsM8}Mn z536_=DxrMhDsMP8VeEZ#>+H-KBZ>t)Ep0_NlUgYUCCX+`AD^0BLt%~<-3!!=X^h8h ze&xxLcTF^{DOLE>BXZE7mUXqTIm>$ux@)U3*82$Z*m zcmVG=vSR~_o*Mj|cQw07bPZ(L@r;}pXK)705gp*~8#n1Vw%J~Vd!4u~dv0uFP1cS6 z+HxD^J=$p??{fCpU6l;Y;6jruE`CqD^RFON(()tJfn^<|c=1hkGM4vQr*E3`apti% zUNNozq;hpC2pPN~+9NbmnZYfpLkd{w3q^X7-NuhX@BFp0!rHDBbEG ztw84HMA=#y=GP{%#>-<=^yBJ0^FMjidZs#hEZe(3okZqiaO}C3iSR8gxNP${Y$x<} zhg{Oc2R{L$**9z^ey{C8I8JOTIw|Zg5?&c$tq8F`mEYj1-YZ8zUH)u6TpAsLP<|Qt zXld4CNb&<#%5Qd1!?QRJueFE?;atP2FLV)UvfDYuu{{P-e_iadDhyFIl#&W+>$X2} zXFfK^XTwx2RH4$tZnwZHi{)NzlQW$YTCX0Gf1sdoxKnzvp=7};JJj}JaC*YLUMS&B zePUd3`EeWfPq=f{s-R9<#$-&?IW{&};%2u$XSFJtS7bI+mdu)!$7c(s*J+ve7V>MK znE&~{`OEx|n`~F=YMoo{jV++?yx}9dbN)qV=h_YYm)0L60vfC{eVcSZ6b7dWt?=9b zqlfL!EL;eI8Khg7`R{VCmpg7pvuWIE_r!51s{$TwD zlsEIHtCyueFRm*SF4r_1T!F7!F5ke}CmwK4cy2Ct_6$>@<)0m&1IE(~VjmuT{7Y>F zI(zUSFpp&xukJUlb?lr(hpPH*9T|ulknG=3A5P`EfFKaKl!c>G$r6b#aJ(q`?j9A9&-Q%_ldMvQ{)!vSw(vRWZ*!T?-apBS zAz2asBmCVbEKhux&_CYyv%l$3)$JlCN%iRj=J<_k{zPZDWDbD;l%F~+AowcxIjN-A ztwr+Ck&3KtEIXl1gfWsc^1cx7tnyNi+lm(19(keh+@$*U<~`~f5Ozhnn6ogaZn$k0 zcbB0uYSOk}X?R*4{5z0IklARuoa(6zj zL{o^I)_wecD{Fk0RF%QtxOxJ}5M*vVUuklV^C-XUb+N7%sZ7O76!hZ*uH`>PFcBLl7e$G+-SntIya4}#8 zwZcP3&+2VQZuy{Pl-n`B9-l%J+9T@2`SFH-@Tpo73_RrYMQ#cEOV1(EFGB2E*p|2G z9JH9*bHodb4wQv1*&nxy5@IxoO56X70`oRar_G1=_=}7ezM$1ahsK@C0w!!Rb8q3# z>&&Ws3D^v}g1}#Aka7KL5=fOxyjuxSn@s#Ue?6fMRrhKh{tUEKA>NPo)?Ny(E&#bR zrpH&znFx=%+x;P4L&<8T^J=L!uwJmahGcvR4+zwR4JQKO6-Teq9~FM?%Q#A0ir1Ne zG|VG6mcExCT`HM|EXFtRV<*2ZdwcpDs!Yc1JIr{zzaS!Ce_}EJeIvQg%;N0T&CA<0 z|Mn8>HtE~Vs-)?vJw$K8+^mB@gA5JOgfV=g)-l+eS9M#<2>N|teG~T_#`6%rF8BNb zU8Srw75$suFaR4H!Y}-2D=-`UG|q2&XyMMnRU%T4z*BWD(tRT+OnqrYW4#AQ*nfkM zdfY$3+PXGbsFHzBL*WoE3ecPIz+ea2teT9Z2Ageb(vcoKfRNYUWi6nW<|F0Po1gA? zGOUp(2>^9$qX&12mcRANf3QCtv0+;8+H=pX%Qpf z*TO13z(FSCwZxL)J;&e_x@1Rm7~56>fbhMcDt3VOb7AN`2vo@#Ba%nyyc1AxU!@l0 z@jX>!z>7pDnAN}JzW@dF-+InopToQ#8#dK&Dw<@1=nub}YBCTX&O4O8*^EYdKhVu# zc6$&#Y|ukD{pOT2`c1;XAlE)0^mP=FM}TnWabsJzt#2xGmO!K)8*K01r9W8V+5{la zt2Ei<{F>EekG`9DRC>iJ&&&PpO)qtGVzaj39QUpcTS5GM29s*P1eNhYrmxfFCVDTJ z6+c=`fPFJzyi_*LzSOaheEVm!tfH^d$&SMe^ciQY6=(A2V;83*%!w*vj}q>DuE!DD zQiw`K{o*lqV;7=an2=3~e*dKN?Ugk$eSK?yiU@PAIQHb_ZpN3ZgZrA-YTwhU!Tt^I z$i#4=)moj(nzb;9oH{F&B1VD{$IRAo(eI!D`YN6+J|t8D1|ne@zp9UpnuDkL_SJk7 zIf9D|^!Rx#*hPO489baJ;25oNuE&m2O_;gIo3nM&l|rci9&Qr4Jh_ z;I?U*4VY5~p!m8vT!e6|mPrt}g3zJTPO#D3z+Vz3#_Q(vopvzFl~Qy%vYt0nCYH{F z#y4I3gIrR{>OB~pT2$}0-R2cIxG`cA-%fkmBTY24sqJ~ni?-@By@YN5ocw?=&eGa7 z#l4BM7g9MdOn@E|<8(FN8m?+2h!5VOVs*E)!qT!UFrJCYT#-U}scVitq0t_7`;*XL zE^}XO?87#{9#e*p5|hRnA8czhLf-N6277mcHMQw_3tOn5lpgoyI$^mOGnmzWswgOe z|3OwUQ_wh`wocOh`9Y^pzw&B&Zg3W_ym_oJsv$7E{~6E(;uKvQUyN`1ZQr}FT?kf~ zEd0!qGw^reTRtb{+gY72Okmu^vwo1|KjHU)&WUUE-f8<5XfAbwo`jba%YSlxyX0yY z-?TKln2~@`B=j2vpMQ2^WbcPhQ?vGEwZlhKz*76aogQdSOUMOP8UJ0m3nRUPDvPSsz_aY(+oYa8dTLp0dI;e-gA>=ibQW zV{XcYAkF)N)}!8{*^5tKM7#mY-GJQilHgX$I5gT3?dZO^5v8nQ^lM$^OUQwDnYb6W z19;qhtK(ih~AHKAodXRD?D zR6*@A4b=#gCsm*HRuNyOm`NMSs9$lA6g;(G9^aBIJV8k_sX_c(Oj%7 zVVbW|>YTFKKJ%V%k7Z+(@u2XnD@6M1%Lv6qzQlbf2H7rV47EiaLUx!=9=J^_3vSEo z>i#0@Su0cAcr;q0!H5IBmw_?%`>{X)!-6&Z%<|XuBV}Kw=da9v9jtM!l|g4u>vI;g z2BHlIcjX)YX(E4Dphv&_aA%zC-{^{CHzKalWj;>o4O`TtQ*n#f*)Xy695-e*xL<4| zj9%oRW|esR3xqVDNt*Z<(ij~fR*a;}t%@|a>_w_jKUHvJO}Ce1Q^WyN74dH{vroSe zuSC*@|NO$9`vv0*rE#XkNMUmw^*vngTXBr>{ij6rR>8*gdi1-x#Ww*um8Wy4jy>Ku z4D>05H4En5=_pN%tTfi&`UWvE!B>{CLDyT$bA zyq3s%{LcisJfVo$b9kypeg)Oxz=T7d zlq&J7q(r9h8n-GDGlr$M2Isdb^1RRKtF8*D|+1hqED*MY|> zuOp7YU1NW*8gq<2+Hi}#pltdEGZTuIlMF5niuc>UzcAQEBBM8UiaFMhf9~(4x(jUs z=%^xTjPc&u|Jo@!q^*mvdqZ;D>hxQ^O1&wvCRCi-iF5ryrmAvUl066AFZCa)0()1B z!)>t~@v6|FKjv4FKm00^SG5tvt;1eyK@UBb za*fEUE8@kKJcy6kB=lz=_5>r8enOOviD^v^>-FIBRPPq7WZp69q@V9D|F}>m5Ek25Q;sONj=08P3z zU}qJb=OdKQHh}El&n?zefLiyMMLf3*D}PF>X8(g8+DXjuG~V)_%KfUi(r0Q9wR#R( zckGYLV=ugUQ19GyM&)^Vs9It8NvEA^OvStgND@SQoh+3OSoSo z;`lVIy&&qLdz)W_?%$WQwZR=ZojoFZ>+j2k?Yh|!0$rR6g*m8HJlP-WAyl31G2oHm zLvu+OZ76xO2@XSWXxU;Tp~+fR7%xwrmw|36k<#hEPHB<&QqAe9H#=3?h}T| z%=g~?0XhKIoZ|$l(=XsBiQKJ!c4UtGt!&!#xAWhVP?E6Ke@C|rCTj3f`5||E=Y<0; z8s2u9>l&ThCBCWkHohr#&2RkBP^>B}XdCc5Ryi*+EBvU|eEL>z;F0B$*fm(Hy#3yjz3r^Gu^LYO7S(Hj1zgWJ@2(~3cDm@m81t1Kga^q;DX(=oyJ z1qnCe-0JeGQz-{VSc2Mg-`7viJZm0? zUpKCP7_ooB=$u&X)OO!Fq4RWRtJ?!20z`aFz}6b7K+% z9h*+yaA^#EXTo|KqkN&zY~X7Hg|*=AzdKkU?MCyJcTXDU_(lqLf3(K%&+<zo{u+BD`>Tg{(@us3sSvnB5dfpH17EI7cT=C7c` zCL57bELiVCfVw&3;QPD@eoo&iu80-{O$s)7+J>ZVj0=PO_`5 z#l@j$beJNwGXCVXq2;j7z>Fa?%T{x$eqvmtMypz(l#;&IwBbaW!&W%=KyE-QAv@Y}xK?`J zvR&qBh~Ghm2gA+7^xUv{sp8K`Lw7TacANEnj#5T-(R5#c@q;+Dme$~>^EJ1a&?II` zbyu>R^Mm$*8N>DK#RVC484u@knXz+-kk6`wz@@<0r>E2|ga@_)%d|?~)xNnIofYo) zH3`t86RgqK3_vnrmGs(YmT-?v-`yP-xP_)NMi7zD{>L@wL;_Ly!wz;9x5FiU3b*~E~w;%D7 zLX0waH))fLg(2|JqD3llL>Z@)5#Ll1xBpr>uE|Bwxq%&O&UjrQN0q-d*wSOoHGy?L zB=gp{yu#`Gun|?Wd7F12leMP*5o+wW|7VL71txF$j*9g7PXCg?4Ipgq+mU_YNO0So zN#>ICy3Ly3h<<}_f;Hrq@W->dIZZ^<$3fp&Dm@x6gtY^NO5Jp-lM1t)*L@Z}$*h}b zNae)4Q;WF)ID@EiyEH4^9c0j{Q5&}7~buCyx~j!XGUWtQig5#EJbp7|WN3?X+PM*BudRYd9Cl|-TwagWVw$ksXim~6YvqpmZ{j7q!8Sm;a^8XKrb z=T^yXg_GW#g)ZYIpD-+i!9FAo9_rx1J9U{yVGpa`|8{n6|8ZD0)jGfbjM-jD7TSD}*#vsSeLW@eI^H zF*1Cv6OkIUU63%6U1+koLXMUm;JZPkaDpcd ziDqx2hO0I!ugR#2sx%9xd(ZO?*AWHX3MgdVD8G;Ph-XT$(YQ-31V9B5Xi%JQ!aO4o zfBm{ad9Zl8(OL3^np<5qBh*0MNiChhjSRZk0eN}5ej`)JtyN5N3V<;w^6|UpBBnk_ zZx_)+5pc-JExi1n)MpbGBNBv2*B8(^AwH9q_{#q0x`)su%kqo7$PfwyxWDB3~taakDGYiL+4!-1JQRUNAelBXnSqHRzYt zf_Za*^(n>UtT_p)WqDG8d!? z-r&g5nv-avt+`UlFuEPXx%j4hHa8Hj0}j_ubNyX&!wcpKtCDX@JB54u2P&=?o2+4; z6}pt(bemx>sGYg|2>koUO^)A$$}Mozh*5Ii0{tAQd*$^_u`d`*7UHwn+~qY`MJzoD zP4`wIznNqf(p7AaMfU81u6bh&mhkkChL$7-zhqUg$J);Sol=etrh23Iha zF3Ebq@zx&f;IHDnHJO8EKvA~~=W6kY*8=p9zrSoDyyUHfb}48KEJ2%6X3P-P#u3>( zpuc=m`X+OrhH3bxxyg{ZjMpVbg(1nxka@m_LQ8kvTkhBDb=|sOzfvpVupoZceH{$n z-n^-ATNG=N`;LG+tv2AyVsHB_a%i*nz%BR(|I5smepDMRNi0EF=j*1d+Ny#6i@d;B z`$0s2JbW_*ddr(*Zr@-dhYNU12_rHDphD$f_YeaCqZeEyKj~Ey;yE^n&CdmP{PI@i z27X(%vwu3vvo4Q~`&(#9D81~;M+c$*%so=+lFktL1*k}5P<_>LC?G>6AeG@PGtdC+ z%59GNnti`g_E}|QdNpewAx+jnDz(YUdWdkFdpI!M!LXrpVJ6jZ1m)Qzt%oBx7I%3R zsvA&rtOLAVRI;iIxGnDbZdAv`Br>bU!-#7`$Y|rc8e82_(yr#P!KWqAMzf$|z zbmyxGp=xGvwvn913m`z~!SeOG9PvHF7+}K?A8^Zp<# z2=Z8l1DvTdN}1~<;pl~0{TwkUC8r`6^5%NL`1Z5}!!N8L?t_PYdHEsz_QI?AuDMn! znLqo@Rc^6x44YB+wjbQXk>F(L^d-rM%J^r;PLcJf_y92o3T=Y!Z*eK@5S35517dot zfTNH~I!S`KXM!9SBfoM5@Caj4NNB*EzeaR|$^wKAX_&}b&>rL!Wf6~&bu%`O`<{F) zI^Hk?U*9^Bebc9e5?>tFezzuf2(C#-Hz=&`)?#Mf1pS&F#>eqF~d$e$Zr%S7G+G%s3!JMK_8BdJ{D^iH}0} zp_9=~x}G^+;Qik8+vQbHh337FgPl;T9}vKjEY0%|;{uyXH(7}5|6l-{LrwyE?_0!P zxZMqMoP!7Lx9@l3psIedBFHMqqGSoOOr$(L^PV4!<&EwWx&K-;D;nK6dY(pEpEemvW~_1mS;;s~!W$0X)!ioY`@I-me! ziA>PleV$S4|J6P5TG4ij$o#%Yd;2a)Nu&?2fs-LOS=>*OfjCTZDqYc5YmTTnDT-@` zWq~_4flg5YG`Oq~VK8@uHAndXl(DwA?_ZjpU3*oV*t%xB=9oW6V$RX#uVG;?zNkk^#e`Jk{qNKgK#yA>14zXo=@ou zots5#NCxJy7P<_L4EqZul#-S>dclya5%4f-{Laf~s>os9V`-S8^rbjw$;SsxO7j6a zjd8&vDqw%5x)NUEHseCXRKj6~RGY|XyP^Z1hMVgMcuwXY$FVE*w;$T-MbZ_!6Zz_0 zK`oVoF8BI+kZ>Ruzw6S`mqx2Lq%$8GB@r4P57z%vV zgw1aq8{F;;coei^hsnM2a1mpvktSVuVa3{m8B#2lCF>Yz!q|HKsD&UtKx1imWZhqQ z8lQW3SX0U|)zPAk7!TbOOKU^g;OxyDB&W{p?J*L+uIf}tu>dDoHn|nStT-m%WQx_j z`kfkhNTm{MUu)VKPTW)L;3erusSi|$fvJys=MP5fMk>jgtnE3Dz zqwN=SPg!V@%RWzj_m#NA)5C;mWUJ^z<;ilr1+Pq~pCA8U2kDEDT7c#PT(|J1(b)So zBd{IAL=<|wsuKwAT^t?!;FjC}vAD5J@fO=zm6&G9SbR$I_N+uc_G>TK#CW0*#R5I| zYWm1TD)_^9Hi60i7z4)p}bZl^UsbzlU)RL9-==ciN2R)Nc7&W z?LHtJ@B29$Inht5?f)$?LN* z`JFxQ)hMqqa;Txetq-8g7TOw$1Ks1yvRqS@!NvASGic84>gM~`c zK20w5{5pYVlyjJql5>5Z0NZH>nrw~oNOZ(xi0VW^z|nQFbTxF5G&r{t#8zDpppVMo zm5{>_YBaV91+PV^h33GRK*Lv{P!lFtL7_x`!gt^nMp6aQco(4+2dh#8s0_}F{DP4@ zlG4g7Hhm*6J>Z~F^I^^dxbV1=*X!%?erKcJS`4;FG^2_3xLeiv7d{16OHpd?@xJQ& zSvwfGxBkWMq|_GhppK}t2P61`-I;9e)fC8vZVs9Dbhj!*JfaEMQ`Cr zlj0rFcLtCRIq?;0`BlH3+A{DbjPsuWU?~9d0WxqyZ-5D$ie+JEVmM;eaa|yK`)7w_ zc%{zkZZoKeL6_~`G4=Hw?B)tls=4VMbh+@S{hblla`7eS8*D5ucWWBz$lN{GWg0mVjSe~hV_6HwY%{ZvN^hCa{e+1m)O0|xS>m`EVY>w0H zINL#@#FcZ7GwWv%x zxmml-^06>D1Jdpzx8v6wiKsfF%&5v{KYW436ATwzQsTD zd>QNc>hOiu;sLm{?NJ*ssW2>s6C77UBB%0J%XU`r%+E+7AFC+p_vr6~DhHK4bFFqd zSu(lnKBmrRazvS8Id}iw}lh!*sjHxY*~noO<|;>L8A~^w7LS}HZOsPM`pCIKq8VZ zxd1oS60*RF1xeaPW(4oQ4Ydo5)3`Jh0{H|?juZ?YCw({`%v8J_Qm|M!KDhF1L-8nJ%<%M4TTJX7ygNM@>Ge1n5AU(e&!*V%;Dj9}g75Z7EC ziiC6$XcJz?94LaCj}j7BK})DO>U(;-p{I1f!-Ltt)29&QU|a_TYkk2D-1-HzD`4=c zVZr;1N07NybGv$w%ReRC|F<%?*SHyTEFSu~Fs6z3f!@DrViJ#nO?*vTsBV|Lc`RnP z_sidL*T1Ye2o>gVdtUuH{^@#HO7t3XV9|NPv~|WA zsiin?D|b0~QQ?%UEALE|Y*u~?#I&k(?$Nu<4U>DOG2Xot)?r<{J5G{Z5~pRhtv^s03hn807yRYFq)z!AV-OrAXjx*HbeF_qkg_eATIzDxA4MLv| z+gRsf6>W%fUa5LP+b_->l>~8Od=W=2v!;k=`sUiX>a?E&CNnX-dXYUKb{yp|vaOzR zfV9kx=d$|mi0z2Lqa*K+yk7F|-{IG~X}^yiY#Up%^fwQfaNxus9cU3pmcReycj$4_ zY)EdAWx;CEiuJt_0v^qiOPq46SbXQkLUYpcA^7iL0-e(3l4>47h;rAdbwFseCm$){ zZqEdn!q18a=Df=FU)S1=3`9)5j4P2mCgJJ$ME=6%q5WR79rSM2d7YNFXXCp);fO5(XIvy+}tSl7ukQd$T~20i=zI2u2B+eb4(p ze%IPZd+mMTVl7W7d7k_Jmh1Xl@CSg68^xJj!{Aq?cw$`pxlYH-1;p9Q?3OH$2IA;3 z)gQpxU*okja-kdq3wga_umnSeoaQJ}`!*VyP+?SaJ$6n-by%_#8=n^c-iW#g3tCJc zUZ8CzSS4oQWSaFgsT<1#jpIU*Eu`0nz$cS;Z^vd)gx&LfCB&pD-*RGc458d3KK`c^ z*d(Yh*c?P4TtYWk&KNB&C*o1|_i}i{`nP1{W6Ix4z$0_rd+LpG;>vmv`YpcIILjBz zaE-JkdlLCeqG%zSUvW|i`nQL7f4fo9bQV%h!su-M zIOMHS-lSSoN_M!%LNw~_cwqGJRXHF==)T0O>H}l?i?WCx^222)0jh4zo6aWHcC?Zz z0j~jdAg+x>Nz$Nl=m0jxjdOf-V;JC+|2?6=198D1Ng8y%wpx*NVbbeQ3TS_@>(*tZ z{Eu_JC3GA#?;!)aTMsd~1INb|!rYKr6oyQapu?dJ`?H?gj#taEV-5-@1@byw7`23IW3uQ(C@mVb9& z3GTXZrPJ=d0+#>HRGlL}>YY}`5WV6BHQ4LA(4ygZmsMJoJ^i1oZ-Cul_$WGOpU8JbvG((RlMICNIiihXTCo$lF=gl2AXmEZwg(f zLl5lP%1>wDB8wKsbv?HaG$?XysQzxgyuj+~^iX=MD?NMk^B5804mqV{eWVZZ_>ncg zvtbzheM72uLyFt2^EWYt;Px!&n}{p~>q1cQitx*ti1l`D&KrB`GLdqg&vbEliZ8DPEn4Ao&lFyj74HW9l z>=4q^9P)ajxLS3Fm_ZHTC{&0~{Z(nrClIDI$`pc01#{5$@R#c3={j+2zKpAiWl6$f zgAn2z-54*AC+5_pjP<-U@Vc+uthLrA)oeO$j4@(hniwH>>NZhn8^#0DBYSGWBV7_@ zVU32NZqefEqci6GyrI6~*A~lOn4riXcwpYrd1`9~E|Z)OknRe-fAZcG0=A&J1j@yp zH{=PIr7NWzdbDvY8$V8p6xRN%UB%X*Lvy)4>zoQ7T~vWuQ@=h8UnPyF-1%JAqKrMe z#_|ewO8E;hAL2{Yv8ize7?6q$-Pzf) zmUNcx3M*p-*y;=+O>hs&81zhMoIDc!b2f;I9X6^Ky3qO}=aSa|(nr54wTzhW+~SZU z9R#!(E~hOnPFt)MD)3K(`hGP9`r=@5PyfgcMHoFqvLB?Py^ajf{%p70-L_h;3kM2) zVlKT6`V_#Pwn08!fH2~JGu$jv1>pi}&rcs&- z%8;Gkn$nwFIel}AgqgB|cFVMqhN7vK>bA@@)o8~>*8ImrIX@wvNu3Ven668nA=6m9 z0aQXzQCY+p(mghY$G`Ol`p$7VSNzBXU@toGdyp#Ns(FaaFhEFg2&<0A#oUm3bjS=k zT6l)jHOlCIl&sC0fSynO!LR9H{#_pq3wx3*%uzt#KR>QP8%Lhy+zDHS_(d^TAUD_> zCTqDPWt!lo`Mk?_hf!%QhOf3gb^Q)8yV}1X8aqxDx-f6IsWry(Y9s^{PZ;;PMeEf4 z4~Rb+UqlR?Z?DeDi4@u{FxSPJe$h49%r1u;nz{zq^1)x6r~M3Gnnm&g*~U|->(4ER zE)j8+oe#pt&(N}KEg7q41}<)W2XtjvhvV|<;k};Y(quu7qG$ih`9E0Azc+9D3l-7` z2J>jkx>f(s4;pNIx&Z`S)I$BbB2A5ar0I@5LFx;iZAlojDL!l#Y>*o7M*|O|?o?9| z0I&8{Km2WQ?W4736?Pa|+>A^e*>n_X11V~v!3oWN8569`3oNPPs6zfel&Rb2-aFC$ z4zee0Pd{UQuuLs~=!Fom74w$za?ke+mg-qAk}Fjl4s`864aklBdtw1D;pP1_n%#N|MTxPJeh_;HN|&ElDICYcgM_Re8$7Yk2q$z44S&ajGfi}vL5X0%eu8X}vg zojmC;!}<9S?!|>pqrx>%F3A{-8&PB`UIT@Q-oO;xkezEe1NURxJ98Et62^cCD3NeK zF-C|!Y7O`XhYoh;sf?>#xR>S9#^1NH1=(fYS+J9XCp6`8npJ9iaWbz1&IulvFD z(%VdHT^H)){FtuTn3_w?%;1}-V-YFp!l21)L(ZG6;N`A+?l_gVj-qE>X_#>4i?ImB z(?Uw&4vvP8%X(cm;z$CR+lU{~vYZ`8OBR?dce6_%f~X4Gs(7*rZ1*@CTu3n%seLeN zMRrLS=#A2oVeM?~V%7uukffaNu1pOz96{FAgC@`i)vpM5jL1YD!0~0qN`t zC$LZ$Ta6ppS(nI1%lp2R&vVZ9QnlqT+>m}cw(VT03D?<<|2TKpW2b#p9O$)$3q6{i z5Yw_v+hZC>rG4~iPQwd_acw#T7Z*|Wa~V0NH8-D5{iXMf5#Z*YeKm+f)9I#1HTd1~$Y&cP@QuVfP z)j7?KeD>A0#t~siB#z9~U0PafP$laV)SK+$>gMyAmdm#&^_~w6#UB>sL>@jnE{?;j z=wIi=i<77=>4;O@2dosvJ>n3Ej+aOl0fApHBV|w;v^MaMB-|Rl*-suL9;R~Mijib~w>Y}tr?xtJC`xFIDC*nyB@m)GRJl0vvr zVeoQtd`gp5RGx}MHT=F8Zqp;G37?NP^BgG;iTM_1(TaH75xG1{L9_$9s}A}BC+>qF zXNZBw^*_&rsQW^HuFA`^qmpNqNqXC;O9a6N<=$A7Xqjct{|gj~h-@-|u8%Ko)szdrdk+ZKAT zd}r}{wSSFBJkZk@F^&mHe3K>A5|UP(Z3GP}pQ5>V<(vQ1q8a>an_Kh+Up9NPRn7%R zyG8KvI0-jsMO)^B{KPBgGjn`+<8oaCX9jFdm+$$0$|bcfrU9~T#UYv!c{ z2=!Yupv2k00cQ>YqLhfSHd*Y`Z1=^*9@;*-TdGKeX z#?*f!sEA>oQAcVn)mID6B;aH!=Kp5L2W5=5N{8AC%L!Gcp&HFTs7M!+bAnQH?qz0U zB2xhbJ=V@jz(9u+D*fwSTE6Gn#jL}g-i29<+n67JKJwqH=u$}=&_Um2Z)U<(lYb&n z5O|(8BIP{Fh@OeQHNE%6LTU*WOY4ISzT!JfTkO9W8z@czm9`K-O~(NGH$-^VZwT`T z=c;2bYw_`~EJ8xi^?Z7}sX-n26?*X$n1Khj!9NdSf*AU{5K-GROq;loKw5HhU>tSw$CT1gDhhqLkcYL3G}RvCxMcF^CC8__(_8S82TP)R1~? zywdf#*TKvA;eK+Opd#@P$ZpAPv1&@_O3DWt=gB5cBx33d;@mdx)O=^QpxgA9Ng0mA zD0xvqg@xUy3N);4N#kC<$Ak%^x(C0?Or*nq4}IuI%0R0zB85j2Ln0Nr{|J+b?wS3^ zWSbnXW>ao@5cT<4%3+6_v;+KwGpHx?Lt(`#e3LfrS*5v}-;fGfTA?VkgTgCcEunaI z!@Bvplp$L&p)2a=O7dDc>9^aYe0}fE-y~O2?nE8TU49QtD5J*Qt1R0?5w_85L@G&w zC&sZn+&*sYROP9oz{MxJ+n>O=Cw8dxiaiV-EIG6_r>eE%qfg9` z!ZB}82Oj^%`{^#>>T#L5#v7I0YRC{2cb_1|kz_)a_bJIIEs4n^1yInLuHDlZRJh94 z8vC7lof8cjc!{u*aUNjS?#2Gk>5oPCz?`9AlN`w_@&01E)lbG+rFN}EmE?9HC9Xux zUt;aF6?ddGW{8%8)`G_s_}A8u1K%rp=Mu_QnQ7Prb!nbVhr4>As2hdRMp&LOjN)v| z*<%?aMZ5B$VwLU$MadHS#e*V`0u_EuC7UI0&xaSbKbMrOa>Xnti%=oZV7K5E1dba> zp{v+f-XumU8305MN$1cPRd(Mn92K~(oPD;B2m4bRJd*9fXatRrMQ~(>zeL|cr#--k z44FAwKsbWrffFq8G6H<=o>u>*5`XMkDO4~(de*C3WaBAiy3P^%c}&?UfBl|obzzbt zgmTd1Pg)>I)X3^k8T#;CabUvs>k~(dSLyh|#G{g|kbX>+h zOGok4JG}ys&)7Ii7g0$_qoWqHzfkZuwt={sl_wC@-$$fWo@GXHWIX%CvixM&*>VOt zJR)>AKR)v4PAH~J{y$$nZ{^<;J^&j>!mbRzM(tW4P0Y`117_w^RQ=KarY{#T578CO z@|T{RN!q|=PHOyBX!c>>tI2dj$ZkW!R{!ZR2-G| z_Y;}}T+|67#-=?sPJ}ar=(2#VMth(~yb!BC^Pe7(vVOqw^TJ*7!pUAD_qdQP!5XAX z;XDd)ciW?hDwS2z9FLGZs4ptAsR^*e8)HrxPvI1DWQFsl0WL-s__f(!v9H1rJCY7l z5IXKBg<;;t4trxBf4S$vJcC`Uz*Pvqwbn?Is1}+|$OlQ*VPT~w_Zo-9sO`T_hn?Q? zhj5zMfHZ(O1y^CN3ZhIYRPUf}EGGC9_R-_pB6<&hWflzd^3pkg!i5$r>ofxwdJNXgAP)kYEj{SVqSXG%aQQ)f9>lr16M z2sA0-RgyLu+shUrv!emdt^v5Az;?S}y)Jz{8ne#1Jk*WU4(?8uzhdA)-koie8We`S zbqa;479<5BVuDv6%OJtJp$~#TBwU_ZCnNGYnO~mE}e2`>j8 zI`^)7B@EE<_dhEo-)<37wtnVRr@ZZWk^(nN9Wf46JA9FUcU}6*59Oixq2zd#eRm>w zbGBHRH1iW&$Kw*X+tJT}YY5{wF(YMBj)0b6fDt3TmUs9BATDTrcJNy!GNoe@>ruh_ zqtaZ5HIc$R*8ktjOn{gB69EN66-(A(Dcvks%a)=a`rV-cD+G^Pjuc!|y-6dTZ6p-9 zl+0n}tO7I@e$HF}rfi==bD=sn6x<1XG#ayRBeh;QJE6|d^=up!D_$H2$(w84-^U7& zRFiDuBN<;O97D#d%g3fm*;u`Zpyk!yL)58scdIS|!LfVjPqGN{R2=d+8@GWI(;Q(* zhc!HENC6f~eYkurZ~Vhg$E9CdRy+>#SxLlfbNI)Kj>z0(b&mJj!(THQh^zs{yAL<9 z+yLm?xZ?+hp^Ln8s6Gb%+G4!;|q8`tIv zlEpMHFGvt27RpUg{npa!hI)20uj196D+@i=-VrIgZgQvL7g#+H^@gG%oPgKV`<0yi zU2E~ov08_M7}j!*bMEt2CH2H=Z@T zyT^tMlOX15Z_x%X*-FIp2(;RfNb)RHAYKDtFIwoic(fza7K69=(VUO7O7W%@R&PU3 z4_xLNy|{;@tdJ_GQtIEf8D-B)a_lK(_kP!GFrlpX;=*=YJ6ZW{Up|Llhrj4dVCsGz z(Sci1+eX_uI91ByQJFvss2-@>gWj%DQT-A#<__f(>KeGz1pq>qCnaJFNey)5q%=KR zmrCzlcP9MEK%8q|~FPD73vVe3nMZ7uwFYB!2@lSS{e zolDite^o6MI2fF#m`O|-`*;l`)Bc^8OBmT=w!XXg8*9Nr)KN6!O{+9cM!HkUiBXBT z`Z~zi?w@KkMs-@wCGq;dm*m{f)C5{fW{k33gVM?Fl^)VXjfiD`P;$H-T9pI5k%z2J z+GG|<0C2cZeH30>730{_kGQI@SduiyQy8*!Afps>7HvP1tPG@onT_7do}mTZ4FQ1s zP56lu#4PpEO7wl)_QcM77P03Fz_g1QUJ%k@ni+aLy=q;ky@ z?I#rM=aQ)({)?NYtB&XP=#TB;5&@Q{@s$ewzJZyq*OzSJX5mEfENaklHvi;KQK)p| z3#0ON-bjC&bc7;*nI-PCw`WOF|G+?C3Qic9&-3Sp0+DHR921t9Eyuo@o5V(cxHQ-A z!-TFVG7jt5F0|yI=Cl~?iB~=0Ds&8vcar6hiIiJ(^5kG%TL|}qh)u}K<%sl#ooG}F zP4a$g=m*t#(Ov+JuzOPQv%Bxy>i0nx`5dCPAf6U%JaBP5RwyYvSlbhAsOkZJ$OsKh zI=Xp4U8>PfTb4ecFbaCC@E8A{h%~F8uk$ddD;|k0)P^XH0;$bSn`)sJtv9S&1E`4)$!adUeT)(>scPt&reLn)VkA1Jk`?%}@0 zZ1_$3TML0LZ;wZv7H2^yvF38 zkldD>I&V}sVj+~FvxI13wiXGAXow;Nv9C9zcHwG#9v@gdvJeBOzvXcy z=`JFp3o05T7;eRn9WCzMLCiygh|1lPH@jHp20FBg+qWx z*@sa`hNZQmujdC%4_qDvHL;*p1-{9UI^UF5AVTVJW%p zZ^1VdP7l(g5=J3d@@>}i;2qtf{^XPNcIlZR=l!T0W9d5qxD;Xvm34R(%lo5&;im3o z9`s~*oin04lo(XJ*yO`k_B+L)DP*SVac!+l>b48f-=}IcW)6}r1x6|x!d47Hr8n%))VZ9i%4l+~r!wSYKO!Ejp5TfeUFDh;(p#P& z7Y@wMAktQ4cq*NX8UMuXIl3dxaT7S>fG3}9&}G{otZ}p3PkE7MA!_*2{)e}_!5fo5 zchBs>KE+=>O3b#|W}~(_D+y+%+vP7DBofck;*yGib__=goc4WG|+5PG%wGd6HXDspKEMlgCL4Xnt0eE5{E> zhh>xakF?Q0-(y?_IZ4(-1F}9z zmxO@CS5bK)N_s)!RcL<9gfcx@?=@Y+z3#wN&YmotBc?Z^f1_SIN6Exv^fO2U9zEY$ z^xZ4sj8ulOQ)$D1il~d&W6IjE^Q!dPXo>R$mookyO0vy}D!wmhLNRSAQFEuP7sX?# zG(p+I2~@_C&~<@>K=;Bv)ThH(j3hb+;?L)lDDUK)CZbhMt?F72dfQ@dobkx9{7g8Yv|q z2@8YaL}Nx^+3gqal#NcO=Y0^J1IM;zOnAKHwKx#C=l_3>ZE;QCsQ+_pD+K=kj%{B% z#q`%fJ+Oz_;ZCYPvb19rWZr}@>hHW*S>np+WdGf> zTVJCg3%4#nSstn{z!i^tIE#mU7G03N>kP9n1|PlyafpKDp=jlqWF^j3 z9}eV5iz~sNOhpHR%jv&;j2gI*tpDV^f~yF;^+jbmv6_iY>EW~)q>9T=gr8NE&K?JQ z!Y9gY@?!1!YOac94+o1!<*QCenK;Vl&_*Rac8cVDRUNPbz%~RD@E-Op()zwlK#e`o zT1wb_fw-93*>ZGU(2{Skg>34Gimfc%LA&`B1fe%%9$M5J$kwgUHj>TkoG3iJd5rHD zJ5t(4NcB4gg02EVi-dCTFZ5q*L|cJcf5;5F_5g2~9nydLxi46pH(1~;kQFJ=ACl$$ zLl^E#KESN-Oy=RDwOnhq?^CZqMvGLKxBp|hpAqG~^H9s~wzQv|wxl4gswCKJZb6~^ zMxyViAvwrc&hM^szIRc$i2Uu(b}z6(-5QmTM(_3+w%PJ)Qsj%6(aAoQYJrM5P3c2- zG-lthq{Y?lXiU7s`4lksvnC-9@uB_$%I(9*<@|?5jX;5?OzgT9@2W=Ti$3yA9&@kg z9Da?F<4r!q(_opHQ~gl3#dR>XV@rB+6eC&jXb*6aoItfxWHwX#J=U&{u4Yx7P1e2p z-64}94D<{DyPmTpfe%pIU8q@R>`l@d07t7w+0hjyi4^^$omV7;TuP zI<*`$URImWQ9z};RKqpC?+Lk`ouayztGlwJDU4R08oTsRfDIkC0RG5i0Tk(Q>$tVC zDOmYFc>OrN5uM030xKeOHIy|ILe>CjpP8#mvo0+84g^0pXbp_==%p~c z!jGJUAcmIdh%Gez@ZS^XuCKp)`qh1Co)C?lsI9%t_Ox+ao}mm^2y5O0_rEr6BmZJ% zfqDZikhSyfBONpBK`2CCDnT?ZVDyph&S;D^8Z-d~MqKzM5?jI=M3P z7uW8%Y(R!LLhA4@r6;)@KAegptsvLFQpN)rIh~0$Xon|n5ATO?)tb@2lrkYXyYPDq z*rNxC(+9HlQ1@qc9Q21Dy9(Ia?Nwd@`=Pzr0tNvobyO2;v03`}3{-zEq~zClop>FE zkpj>QCE3XhRN{z5x7i6eb=*BXQOG<*E=b)Nb?YN)%!VA4r{+$8O6S?8tru=eC3}07 zLkdCq#Ze-{DKWOV@ zga0#N30dpWd;R(L_9iDIZ^1&03LJI)R#)O*)hHymg_E1TJox35e3g`3PRlV(Dj|(C zLzbep`YrJAXyX#;B(#Kaou%j_`dDAKjHjHDkn^}&&<_7zkZJDKhNq)f8ZuCQMYR*C zT_fSB!yjz2RGlaRF&X-U&J>`ltkIX1Ne);hb#(sovVj{qXK)<*Gso-?ZXg@2ptX3gb?{QdF{46!;HROr#TT<3 zuv1_MWkd&+&*Jb&D}tZp@{|X4mR|NYh1IhaLmPnL_aiRTn>8A+Rk-K1>-o9{vB~12 z>MkJsRmj0Y%*L~2PtM9nG>vdczx2(fXTP?-)Zgp4@fW@aGpVIGMg6~wjr7+*gXrB^ z9`0spfQmGt1-J_eB7~o~DcMxR4GnP=a^ZucE4()YKOH~g>auG_DHtdZB=$YPh@k2>EF_g-+{z4mOuywXCa>j_?Cj=rYHj zHZt8WO7}U-m@{Y!lbNfs#9jPt?Zp^LT2mgrPRDda8;@wn?Ux1X8xGypm-{6kmoodB z5t}uvN1JQ1R&Gdtz7MyTnr(Vi3B2w{4UB*ywmf=Y+`ZXHjy&Mr7B%wm_>L4@+a>>R zu2}*6v{10NR7s~^GW4&{?_QpE7>Kk%&0{^YCS`qeThhmfe*qaQ=^6yI*Q3P)S~b~~o8cp=H#GmB|D zuA=^};yiL08=B9K-%OwEsnDNje{j%$KPVTg84nl=VWoj;i(_rcHpI!|&2Lo{dTY$Y ze&hWB$5T&ydo;UY`G_FkYcsY2w^kI#PFVeXoi)T#IE6O_!nd$w`qrZBWYlpT_$-u< zYm@f;8{Cyi z#y4-RFh^tSI1ebms;k)&w`b}nIrPw1BPlYG9-I&XH6kyJvL~8+N#a=Q8oNk!?$EW( z6YY9I{aUqmbdLHnr;S?$l4AHmlA*J+z3Nf1d1S_4ZA<7`ShiF!3Se>N3j(*T;?>uS zxFlKpZ~(g~RIhY!p}sy~Ud?3~aN|Op>Ri4Gw6r(a=32b4s!m`*=$~F^CmuE)H^e6l zD4_P~liBx@^+O0SAdwtp!qPidasF3k&;eB-9U`KR>#JD*|FLG9SVD#<*(jsbY--?Guum)GFIk zR#`8?ks8!nL$f(&*t9$Kfw~rZsJ~2`^KEY7%aUg?EC(3qeL$6h&WGjMOm2$Nu z4SKeNw9GujvWCe!6*%`2zCGBH`P~7n1$a;ZE0Te$Wai=&OxP`WxaJBzqd&4bw1hYa zlSE%;*Sw_X%Ar!OEpXkEPIqJfWPM2RW#$KNW)rOl>g9H;cn&ThS#9Ba7AFN;@7e%F zlL6QUY>Pk2v<0H+fJkpas7$D?>7aymw8mn(GhZ`a3Ax!6m1)alg~F9p_)-BBR&(*k zO8j_hk-1Xkc1Osv9V!ETz(UsKC{lOk-`M!t+ zRH6|*R2rv5?m|9(v)?Iz`s>z^1HZ?x^=StaKedawGaPJg#kviYtA!^=xCoCyK zssv>E#Ek1TGNqqXsb`)p3XB0E9T5VCAA85A2Q?@8apU#t9O*UIi?LegCWmr$r#MG7 z5*T${N&c(wzWIgj&OT045F{)$soyMC|RM4_4lnUux`oI3(>cMLyb~-BtwR#dn^@=pcd^a`+0~C!=owi zBx(ZKzOG&x-gu{5!E9ezt6%r*W#}Bd$T~FM`V|e*m6MQS#ZiZ{e1#P0Yo2!*LOPw% zMZofhB{SKcXoS$PNr5%tmS?ERhF|ss0G^@s<;(+YA$&sawi$JrUw^8W(SVJ{Zn+Ix z^EneVWbs1}-9B;8zdgL(y#NnOWbF@%0(Q?TRfDu_>B`1X9G{r-QF8Gl!A?LS9Y%D> zFYd{*C_|Fw0<-<6u9SRGT0}c0z)}Vj!+tq#AF2=unCKC z3!mlbFAs(>%inlw`GC1JQ_tA#GJE09tRGtShZEJ{(B-YjG#c8 zF(jQq|H87SR-~++>j!CTA1=+`9$-~aTW|!OX{~tu8dUqW&S`EKeHC!!t=7ub`rT!v z0XoS|=S!P$!i;maowkNxMzsTI+Zqk;x>g%GfU6)&S-GS-YtVx-iwd_>bsL(ZMvhBf z>r#lTGIp=K)>o2m<5mkk*jF7I&P`U;rUey--o_>3@^;$V*oSS@TV?ZVGoLLUAzF>d zk;^+n3Mbi4! zZB_7N7`R**_$OMOW-?%blq|wB!hUHA^O-V$on8)6vFeC&`lquX5m2Iv z0ZmE%X`vt10-&1WoLTbsuesoAz2~@w$ce{@ph(U$LF^xIZ7B#x3Wj;eYB~hw(!fqJ zJVH=!qLpi%`Il}~osVJzfe!S&KAL1tFW19%FC60Ouf}qlr#wV`v?ihw6ueT$qT*R! z8YrS4*gf?LrIS&H+v~oTLJnaF{)(X4e4$a8SIvXsXmL|d^>(+AS>Dh@d)A^3eb=te zQ9h5+F68&nxY)gZ8=8nfpJJJ9(nzVR@`{Dtv%utwq(g^Vo_r8t@k-5$BiFz*?iX`i zU_3gFwq!^f${ThR$D0`XUD{l;PTA$^YvDSHAq%ESKv5GgXE5#_)}+n6;Y4GY?AHT` z)6V86tpf8`NVWOcQC$;)dfC<+8#Rz|cZF&zuKs)d=I+NMi@>8rL{7e`t6rmsJ-%8% zO6a9LAgZd(+MC9_UiTt6;wc}TOTKsLBvfPWk5n}{q`qpojN~7!vn_r)i_Ixz%xPUN~v%?IJtNJhL4B ze!~*<=I{rp<1B7GJB*6xTFd~cAVdx(h;Ogr2#(f2&WBqA7l%g%8d)LOh8c=e*O`H6@&}oyUA+Uju;GAMPr9yxyrls!g`dQe8I>hKClixCJ?KW=@GJ5i zl`V|c_A3wCCpzG+KY306+#K&MwX)Q&omd`xpv$T6&=?E|H1*_?gz@Ct^~ZtyK75(9 z#)ZbVo=_8Ca|LkG1acH9tEWgIjw$DO)0mE5R`7csYb_#ZQ%)88p|IkiC+jO!3NB4A z=W}7Xb*0lGLLBSEUqJ>hM%Ws|`sCKf5~+R=$?{L!m>$`Am^4w&`~&U%&Z`+BSQeDf z?3Df|J!P_;JDRS)Zq=o@vawtcOX-JEq@Oprzw+KE2Sg`4IJ@rbs<-&KK!LOngln)8 z&r=Je%&!VByP0nZcx@e!&3|x@K1_VXQGvBP$n&?c=EyqaEug} z+ryv0*p{NJiaM} z{odibTUTc!>j9laM&OsGI^Jl-$(tuZUq3V(Uns6w@!g3H{l42*(2m&+_WZU{G}5!( zp?ZsY$0YO)0s6L<5q%FKo>M1tz!o4V$|5Sn(unxDsJI>1G98q!wu}yC=JRLnX`yz0 z%aho62?)OxPL}Ulj0?yul)-A62^pGZCx*5X9iAr7ia8HlipeY6vG=l^+j+G2|27K! z;(rwSeUHQIEIh6S2zNN@FlyNQOADLBrpP@rz=t5@Gu~F{C57GOpaI~nV%LMI1_zO$ z|BhqqbK?xDap%M$K~-kC4f;78eX1pI8WT5ulB` z&oewG8djufJiprwmVaDfwgi)*oqqb&oW~V^*fcycsrIfnB0KJ8xY&)hkPc&}{VyNh zJ08zxw^*j>lCFoFhtO5M-H8FHH4?jHJ|GkE!Q~GW-_4^d!IoCMbhGK+@AX3;akrn1)iG0vH97s-4_@U z^cCNmYqZFxzoN}bS&?ZxFbsf~|Y+CvN-u729uyJqnom}zA?PTR1SRUv*mmitop zQ9~Lnpl(!9C|)fw{FhCbg(_{sp#ALaHcooa8W57$k&W^0H7XE*M1x)VYrpR|H=^ls zfu!c}?b-$ETv@CDYFGP`UYy1dxp3B8mo-d9oaPuE{>qVOe#)}w=G*tr3y7*Br6{Oku#DVcDARY+?&iK-Zq@p#fN%FLBPB`;d%QjqTLY_<>IliTg=o?1j*#8Iz~|rpITn*<`#2N;WF`TiW6WPHg$QoRZw67!3t)*BRH( zIX@XQ)-GC(lvc0>RESAAR#8?nj(^Q}8}4x4g>vZX*6PK#u$eKg)2Yj~Bp18c6ywYZ zmk_sxHAk9Z+xcqtwtV1RGkzG`BzdhdFTf_+GhvZ3{*{j>>BtpbJZyc%sc!N^N0+Wi z6d#2Qv0zMCwxKOdob%E%Wv#QD`d*A~J#++<3fU3uW#{DHe(D|a!LY3e@!s}!JnGZs zr#q9FH)te~kP>N=!fi!zcx`%kaH7v3P@tL7`$;f@-(!0Jenz{tL=&}GTULvfcoXc) zX6j&(1#`Jd>c)LVGI_@(WstlIC%&9SOy*mpTd+s}Jz;~i5<6ZL z{`bV~FPJayZib3H`s0U3|Bszu|DXOw|2IQGrv5vAnUOf*BNYq<5Y`)5uR0?+At#}D zpTnnqI@|!D%hwEpvL2x|733o?2u^a^Fsv6AbdOx@5AU{^JP8%73?Eq^Ic{6{ejR8#CLX{NcZkBQ9iF`ZCC*czgyG|gamgeR z_)V~tMsbZ0%k$58;?RoQXn%9XT*1Ggc&n|r7S4@DDupLn(<6g9EC@O>Oa4TKvh^0| z>qCyimn%fq5!)@_$((Q2#}PK9Ls|OQ;!bg@4NUAf@AD^)vlA+}-k^6<2BPfQe=TLy zoU|ML=|bfJq8VzQ|7CLOelRN43Fw14`4;9Yw1+2V(HoSYCiJie$|@_(4F#(efS z1GtCFn<%as^jyB3k>~~|S-$dVv!a_0*GEWPdUGzu+Y|aQSJWB?ynvl>A;n@%xjOir zLyNjDId0R7X;%Ju>sq{gB2iIx7$b=R zA8Qu$Oy|ERMA259(j#pkBRy4v!aGc(ZJRhmnuQ?x0jq{G^m|gy*BdkOe%Jmz;WQ7| zxW~9Vuo{q1v*c@6(sAeW%*KNFKK;S=8;%Q2`vT+L%TvFzHq+(whmFe=R3!5Q^meP# zWBgUAK{MG8jr-jNurgA<6E#2Fs!XrWXu57IM7McmIvb6>kz?HWQWQ62Wn3nVmRC0z zcnQ6SZ@^Vwi~plGDJa(TR%+Y1n%YFS3+!{%yOG{HPWu%r7kFgip(|^Vt7Wk}$q77s zvU&vNU3kqYGCvRH|8Mxs5K~>`+XbkB^OGExRThw=W5~b2oq)La5AQwjyybpra_^WK24;tbRXTN`%Pr|mTw{*r2bRV2PsQ8*2dG{#xlfm1zD@o%G z?Je(zM;8f2JCjYQ^CbNZPV=XoB+U7(m_+sDQ4adI!~3s#O+1uZS}6ApKF!5nBLDw8 zAmh3w(hIXPo;zQKldd1X6Jkh`V<3f*%$gm+KliAbziiu34WRB98F9N z>-|!?FR0r|%2@b3!>|o`V$=F=@Z$fTRvC$Sl&tqI2$vy4zHPl&kBe!~LkTU+>RyLBRaos4QNWk@9R~|DTov(N@q0)T~TP<0z5vn6->;ShLgdD?qk(< zm){R!Lc)?l_mn#K`X%rGGd(H@mlV~UdTD8DZD2Ru_e^ejSY52^7Z0HZkRD@d80u8p z8|qwV>UOCtXw)<&x@03WFDOL0McM`yx6*Df$N*Y}BH#NG5jC>X_{vPmT)t^ukf~IL zQYpeDbHz4 z$1T>^%*cJf$5H$m>bq;c6hq#o=*C<;U5dUg_e&Xw_YlK|7&=7d4J67Ay;CdL?8OLf z$k|gk3QFT28?D?ZOJkeb6l8IMf-{wD$TG1H|3#P6r%!-Lo^`9d7PkpkR@Z%2Ak&wd z%)sBGUe|bX8X;-_ssj;aU2GjnjqrKyaPiaF#UEq_Im6abu zkUc#FchAZvQosLM;3XZHEndE){`8gj&J=kH?8)7$0pW0Kq7!}n;cr#furkrHb?%+s zPqWl!i9fEJKFbR{OH|&ifc4y(0$E2xrdLWC7D8d(j%i%8#udxjyWjswsq@gC$2*?4>N#8TOvn~TE2<4x4ozxu0w_uwakr>kznP?e!NMV)HkSDS6YQD?B|E0?ku z??RoZx9S`^1zKaU-Y!_1n7qq>Mg51Ny903W5ZUV+M-=z`#@UI5{Axr@XI48E4anVvV zqg?2v`ryJabB7|BQjL(#D3?=K=)4io8mGZvpUERZC`J7Gb zUzc@+M9!`~vc7gk*Y9a&R+)c})=&d6xSUYGwcYLTz9qJ+{DvFRq3Ozd)7I=8M$*@N z9Mqj6^lY5&8GQRSuV7rcME*wW9}odf^pOqlkoK|zL8zq#o}k*#R-rX2@Z0l?7EXNGEwIueRxMKv>8=4AEwrzh1-hFzF9n_Vb zP`~u{ox1`|yiju`1vsX?xuaz%(AUflu;^4JNVtuhl5ceD7eZ56I+) z=CgW=Zq152cxpPx@}=b~Wex?!=@)^`T$T4LA(CVomEP(WJy$zdZr6v}3eXh?D53x6 zx4{CsV>(|NZin5XIxfYJ$6jaAG8;jtKp(A;{z-(BXgg;(jzKIM3fik&pZembJmYih z;<;ex^Q~z&?mf)Dt()-m)*LM2|GWj6#m{j@@f$;TT6^TKD9UD2rv|}%JM@mOXTKXT z9$k@zSc$}kF*FwPLY%5>M8Tu~XVuwj+RjgH*p22;(M;+sGF{bu=uVqq9i6olZl<|+Ts1=-Fvo5$wj{-LwY_P8>ayFOfeHQ({l3_$Phc7`?CkUtFmquk$p^I`Nk z0z_O$Li;?K85(RHP9TVhN?MA;-^yka3)VjO+^Vl~_sW6kHd&vXdhN(2O?6N(0nL@A*K zm{GcvL8O;Z1vFC980peM2T}wSVLTDRBZSOz=2`E%*83;CKd|x>YbEQPb?<%eeO;ex zB%o=Qb|a{mZ5S4G(NU_sW3;_QqrXVgu;`q)TTn5pbIZ5`Bt{g^H!vIB>2A%!rz$Kv z8;yjIF>xwfC)Q#<*@_FN_=|FjQrT!p+*$7B{1m?0hr3t5-tozQNcL<5gDkmqRexgh zmXY^SE@Yr8s~dL8_wDF$``WDqQ~QF_s~Xy#6snR{Q=c6qqdXy-8R6(P-quOokc|%R ziM)_xU2*G@S-;iJ#eRo%d2A!I{(|ClgpP=ktN7aIfVA--4==@EYi24n%hNmz z2KHWHdt%2@(oD0ZSSi~8=cnTHn0}*6_{_z?dBxizEB9jr6#XS7ZDfiT=+|m3jVOl> z)@V;j>)bGx$sTu01$*6A;jbOC#OFmZ>4grLu@D+txUU>~)!MyYyLvf9LWFZ;2a^CB z5uet`7vzRn#%#5gwX)$iJL`x4@2`V?RLhg8)~5XsIeaSP8Fs%yqM}*lLG+}eY~~@l?crWv!t{U$aseffl1oA z)MQf@Ycp%iXBvfGzczEHIhSEt)94&M*%t;gZ8A#5>?S4#)Uq-SbA~eP`tE{=5ank< zzGB(co-m(N&5p78Hf}%tf3LjUwOn{NYDjmP`tvNp^Y98T8ng!tsqzbrI$1Sf4zvlT zIi2L0y)nKXxMn-ob6BB!bsiDWa%bE}FGBuFHD1Rn|kpd^|{8r+M4G zl68l=?ZzuT!R9Wt7QYiWh2v`-pK;_Owpp$c8TA%L@6+wRs=sbrcvhP{SyOK@TK>02 zw0@%*#f2DZHhC=-gI46&wNwjyo-}GQW7tVz_MTiCyKFrZkxvxeu@hH}JihsIw$H$|p&DSgZ8e@F_ zj_Ze&=cSEw(c$acq@8HDr1-PYlI@j+S)`Sn@mWhb`7X*r`2~4w<~5o-WuZ`R@bG&Xg_VFt@s+4?W6?sxgHeZhzbLl<`6x^iL-ujT&O4 zKI*QQ$TbhSBv5j##$T_|RUn5NcmrbGnUDE&Tt4-GA9l*UW?!`0j;EgQ{ip0pzIfy< z*6u%bQ;(xyC1V@!?0d+4t_k_wJFeLc3|Cw`vF>}QrjGDR8AKT8g`aDy2N%_{~R<2Grw^hIKiLVQ7 z8wt8Nh@Is5*k=_xg;tgU-aCiAs6ANy6lyzfJk>d6QW2VXqF81>B&T6AQOw6z+YBKT z9-Y2EUrRoc^;1@n=i0+gPA~!EF2yT_K1Tg|*t<*NQsEP=-$ z<&1@l%C45$XPd<-TG^z9R;>TdCR(F?O{#ylm$3?&?<8Ngb8Fr>)2?W0qB@M5hogrUk^}ip?R*LxbW&XAHq9~0m_J}jVe2195>+QetZpDw*|46gs zLVCe(#O62u$?x24UB=tz0rvoF*(``i6Wh?>R@dy>yuGp!+i2TVu;NrHX7;zOd6MEK zT9Tm5jk9II0H$bjIT%8992ZS?Csq@O$K+CIPC`WL{XpWT{aeWS)WqsAdRL<%^>MD& z**dn|VMmhf`H*K>4M`=+VluUhZNcC7xme|^F00>uA#z z;U0f}ux`^7vt7vbcG)ldXjwXnv8gD+j0kUhM~QCs`K=a;z9eFd+Wic*RtUQ17$M-n zlHYBM%Ik#DU9!pbG8+S|7Ri84e(_v5&q6lxgbo?t)@C%DeKX#u^7y~y@&Bok|Ns3^ zd=8Co&gR1TWaFwM^*0xP_{2m1Q+5oJd!G9D*k6IW{J)`DYLWc0f8YGy4GVhTiW@`N zh9+}pP(zK{yc0P2c0``Eg96^N9gA5Cby(w8Pu3Sc1>ND98qBRM4KPp%_m@}Jn(0A_ z+BPp|Z9n#(jp;58_I>O9=XD_QV_;v9Zn}7Q=cu8-Iwd5`wd&9qN6qRYQjgo!8>HZU zhj%@xqlme!22Y}fMS&(osh_$&{zY|N_Fl5cXxQ}QM}B*;WLt(LjiUPmEV&g36h@5L zy3}V=-O7lXZwjEfbGNP_Bx-;XJEdMafI)}yP!4HW8_pj@b3~x^VthEh(==y5#-4<= zfTt)60MNdfIwkb?VCvW9XY)OSSsrD1y+ObyyS4bX@m{3b^Vznx^zAqJ+d=VKw~xzx zh3v1DT0lMorgF_SxP>XyGR-b^I(=lL*UT1=DQE6(&k*Ay9fDHF`T}beRaH>U0KFf>eg1?Q6?%PcKow^O zoyCladyG}tX~ZiPhkKXtj5SfRDf=;VN-E4J_?fBn3O-FcG2(Beh}e}?{^w6$Vovi+ zCw4#o*vBYJq`tdcvaza*DVD|N6a>cORAGYD?|hZiFYhu8CR`bTHLikxa7}bC)>kqy zUPLP>(>qj_ct+oa7SJ?Zy&1fG+faLC_XU=0jfM$q9I$h^xKWv49X1gqYH8o{B&p-ffxK5v+RrJejA45-aH%_0C4u7EexpO zd;pv6oBysN<%7HR{YDk04h zPGndY-5VU~Go<;+NQES;-1y?JKGmm|X$V;|)~SB_@Y4&B*gv0I;erQ z_@q5#17%lj)XS5X=vTb9T$?lMYRm)vzN2W=z<5!+`AvG7Ck(xLmy#EJ;Iv%jO=j*O zW5RHMw)dzC3Byj=LL8->1Sks-!op01vScWiU;;j4@t9zaScKCf-&dE07T%aN2Wx+y zK{8Z(^hv|u8=9QQ9Zo1=4*34h@oYmxTW^Y->1nR?as8r*RJP7J7I7r~BL*2yn9yWA z8gK7bQf=P2lMvxdnPZGL*R7i!yt`n(Rhl8SF{*GPS zhuQpl>?#d%PSg*<-hScmg=ZUhH;(fD;j8lmk1BL{zCaUae_;X20>x(!NOOC)sfSlV zJj7059qD`-fnM=atpu1PBpZpLzlFX7fv3hs<$mUhF!R$;y*Nc}I2Co8HM{rZzWdG7 zjT!a%d8kL;7sC6C=Q`gdY_WIkWFb0&6_hbr%K9{&XP-vO@ha=N7-HPvrau?2Ay&8_z;Nh|2db?%u$_9{)rblki)o*JWGBt%RdQ* z8H-7J%$Nbi8A6=cB)S|Yw$PwZv{*Z?mB_{o3MncO4Zd%j!MN!a#Lma|s0Z9yH>=uF z4DrnzcFeUX2`!nDOkcEU;+ivj(VDrUCIQyw!H7-6+Nq4!UGRXD)H3h;-t+EVewPL8 z2%4r8m$BHT*Dh4I#=YW)bgflL7AMJ+fkxawC}ZvP2AF@JYst#sNshPxBaaUal1K49 zQ}h_&5`)l~o-<^k5xxf=9k=I8L$a7j?jh}ua=sG<#= zdeJfeHP?PA-Opy!&mm6}gXD-cenprxSu$s2%iga?#)tx*v7jw*LCc~|MtdSMgf_;hP#KPLH< zHwOUo8e=k<|NUP8p}ruwg+E&c&%xOcA2H45(8qJq9biIS(w?9T(#_PF?bDgA8BPdCJYt z@JuWb0STS#ISQKST!^q_9$bfgX zUFBA8CN_pIS)n@SFwau}C@~_hS)WfuL~Vp8%TK%d_u`+7P))0U3C3p7_5e5Dm5D~@ z@r(0pA@*QrFpDI*0bXP`0qep^t0+x6h7nZxW_Z3PZ|LTd)@a7Q70&W?+zRfJ?nuKl zdqA0a%XJ){)xR=j7Ec*RpANcEf+3h@#+5HBWly!22V@UB{}pStsx>@YpY|FXN5D|u z!BU|q?FEO`x){0l(~OPp>pHE8=#?7EVAr>y&zU~fg;35Q>WtP6h+REJU;T06?4o#m zQVcXQ^LvAo0YA}Jj1O`e6^8s(-|&_FBm6ZNZ@gNJ98d@!Fka}nbY!=6@9mS-cQFTV zeN~wa8q0NX3l2=&EHo{i7XmRc8^vLqan4y*d9-GJm)`~5fON_%YdadA6Pv_P(5}6b zr)D_OIqI0MsC@m3tp5x1jI44~)}}b-wx9+ZsX5i>noIs=DA3H(pt+oC$gUKc0IPE1 z#09E-VZ>TjcxL7Gtb9UgH<*$6k+a*<{2-R>TgK@qEsDq;Sr|7QK!SHT#RRfFvr6!T zzbVK;KK>IY4cyLR!j!P~w%{x$;t0(_7PoGhB>x0W5k>HX#Uj28GFbJ4{~IA(oT;u1@wS;$jxQa_*6VMsb}?7- z^c56+DO4Wf=jsFHKx&s8A_y(|pA`K4{O|>sI_F}b3IdR|l;6wFJ5GJ)cwCFUsyxJ9 zNPNOUI8zu9+5=DPHq&Vp)iEf44*_t|g&1lziyz?M7Lz(Dr6r~N?vB4c&`aM0i#hq3 z7Pq^&L;fGo-JiF2SpOb7c}w0ilN=AH_76x#_=FDseTh9;E%P8M6nTaV&$yZ6$0e8X zUp9pu^wg(+{(5i1)qy;1d==&M>cywgSnmRCDy+nlRB4gecbEedHn2Oe2c-#EA4Q?k zxz}t!Dx`DEOm{C^HoQb@R5l!2R!aQHYUHTdPE#$H*)7e)=FoB{nwMXUqE@sG!(Whz z4TZv>MZbwrdpaX$GjWJv>>otG%MTlmN@-@c?@RMf+nAHe-b}Rnp)7xZWEJRTGoEU2 zK50+-kDBD^X|PH26`t)hTwycxsp0R}$cHt&)7*hvcE3^4q0Lexi<|g)=Xl#KVCx#8 z=g^}@Ev3Hag}z^s&-JP*`0^2NAmj8*g?Y$w-PK$u7v24?w}&NhOmm)wFydI(DL*&O zGQ8`iJ|g|mqfmYc!a`m#q-t5IPXwta*E$_%TTInvHq#X)k+Mm-cYhxZ7)shf?3+6@ zyI~_0!E`X+Q@1k6Ui_mgsnmv`&T3xBwVV6Wf>0B^teZBV=+B>CSb#DmN?B=8P$x72jE$H|sVDV5@=H6ZN0;H<4ie|ownfm+}y|b1sUsU>R zWvuO%MFjemq3LG7D42qfsd)2*-2}EEU5CX7LS2f2Ei(-*=G8YkI1biUg_tYN*`sES zHyTDHGRNAJ@?wUkCp(gmGK9^PnlwgB3@6E2B`=6psTKg?Lu&0)1o5N)+C5Fw&KL%wT4EWM23=m zpiE2Af#TCnl7w+}r>rg=cx^VVsn5Oa4I|XEwrZ*<>8fbiDb^T9@z*c@MvPcI&uX;v zsU0s+<`DSrG21k2;1mwWz5K^feYZ%f?|v?De{tBHe1Z8n_wJqi?$5_fQwJn`whr>D znD-Ta?qAgADW;$@51!nrGzMN`1Ft7lUXFnF@oA4D?nyHzq2YF(0?Y1kBg6Z4KqhA^ zU(Q#Z5-Mfr2Nwz?+m6`l(So2@G}V9%w+~>FkNcN#ox}$;d$Ehm_9Z{j_%fr|gjd9W zkC{!y>qv7+m#Sf>+xu|nQ#TWN2K@2Au$zK3H#dY16Je~ej22_X(JQARvBshg!UnBB z6w?1|++FZvP;+RXsg0!h6bY<(O3FwWOnu%SzSgr2MX*l%=etiNo$?3au18OM26O92 zR{lF1kP5%B8;!dAz~!eO^;af1cs1(5JNcM&$QdOjV$Y2(4XUTd)ayE(nkGG@-vF|4 zkzdMnPi`9i6-q7Kbr>@$KI1+SE8B8DUd#Vnn|4r_a8k0SjFW2ph;awPP{3Z2FiC<^ z8cu!1W(Z~stt*~k<#2-}S^E+B6T9LXttlk-q#Ercrz0s^zE|8v#zw7RGNfiSf93%``JQS>wat57DhisWoig>M%|V!Ca;V0Qs^1Z)34=8{3e2p8+cLX*dJKM^4Kq!VJB@Ftwag64-z1gY>@lF1K;5U0 zxwJ)|`Ff0u`V6JzzT-L46*G|OchN~NDYAW+Ztc}mbcI-S0^ZF5kQe61=OZCoB>ecJ zo`?A5<>F(T{cTao4kq&EkBSo0xGHMHc3wn3Ok!+Yo~10aeJ>Wg`(|X0I!9w8RY4R9 z9JvlI*ZSXr`~ylYpFAM1Rp`#yr#J_sN=#Pq;1Al#qPHxHX-B41X?X!g?+>7hv9=oh zHuA)5!Y#6TEHoh5(S5quJ;oe3{lItlJCrBM=~&8o-`D5KcDSm(PL6WTX$m!pZ?XPg z4Fz*TQ-nHozS4pS^u%AVFthNo@G~}drrj*qO@DHwEzDZ6iufMf-h{J_R?)d!xJ-Ef z&!7FS%P7|ygW#D`Kuih+b3wPsx=vN|L5;6Sxs6(_)6!hA^0i5Gy|3kFF2;>i(k$7V zjgs_E{`)o*V5HA&{+U~!8vt2UfO_|N{wdxKFx)tzLYFB>T@&!Sj=e+o*8}i`gqPQE zqvSt)yX|B3a6ZcTZCytc+M(--eXg-|Ly)0HxzdPn91(uXc>>kDn|F5X!&XYN1Pn{5Xak;DdWoInJ3#6VTz8MP8oa{ zI5WPhBf`;97}HN8cn`^n<{1MBtBRZ6(N5Mq;y=|jur%C8-c)KXAx3l$7-)fJs=GoTYO4iP2 zeDjCBnoTHG1=>m~^%rzz?VL_LuWm#^S+AEPXZ4zM4i;1~Yzw&)m+10FbFprQh+Yd4 znZF7_qFh4FX|-HV}2=G?nFT`_?D(A|;L zulH>eux-eTA6J#~>1BmSD{pbOUPg7<2P1sRp_RgS{FroKIbtJg)isxj)FqYw*S`g8 zRVI841&NGjaimjVz4q|*R6wEiv(N|B_t;xZP8$2n$G5O6d8)0T(OgQ9V)Uu6HV%}>y6>6F1I$!p6Tl5m@=CyltLx~?Yyz4YGx!;YW&sC?_v;MhP z0<0rmBn^1}drVGkze0Drd41Z;XTIyVfEs_JPTUC0#rUFIj70I=bLD5KU)?(V&j#Wy zQs!vb^n%z0H33>a@wxzGKrti{(|;SDp$BT2+{tasVDZn7sk@CpQLN04GZD-SWe9Cg z0-Y0=-A{naG*ZL0>}mDK$V<;yR-fZWfy#X}3Z&pzDdYxjdr7~RZ4R!zcd zR#({wC8F8(F5&e~)XnGIs{N?0p}b_M-d!(mLVw!0@w8zqV-mc!e)T!@L$V{cO@3?b3hSTw8K$a*22RV*{_Wy}7{G0Yj++lF%h%OgnsS z{~@T!nUehYh9^DWgF3%u6dd>bOi2j^_-Hsrbg z-8v$@o-i~b=_;2;yV3YwmaHn>P~+0Lhl z!o|62CquB2)`s~82gaRzDL<*B{Om^m%6ld6ms_2--R)t;A*IN~2ZW^kKe!beB#x6D z&a?|C&P!;{m88gf^oDW;uT3w!W$lxoWYGCY)(qk@`)rct7V@X*XYKZ_@lMhbO32lJ z7#@Z6@m~gV^jmW$JO43$-MMWNR0y$Jg&_*mn4A@~a?8^-e~mFC>X@FVYZM}TEH!Bt zSzQ{P^;f(cV!G<8Jq+A09Ofw?iP#s2OP&{|F4({xG0g~dI6&gxV;&Kf5@npY?>F6c z)qM605A=uZ;n`!aQrtSQ=jzG@TRE17|1&$`So+wpjaYI?qjmfOw52(^5lRj zc$stE;1jE;7uX$2R+vBcU#hm{j1l}aSnPD&o@0~Eb8mupw$SN^xXw8e@txnBG~xL!LkXufZZAC80C4M<(HvJ8~Kz7 zkOd*jmR6V1l>QQtA(t0a$*8j_AvZny5}EPcb+}TQqlG#H2tYA$Nk_G;#S@s%C%N!$ z7V+%`)|MHWYRsf(j+PVA79sO~DZOb% zz8zD%AsZQ@nkN)es(PX*c>B{dja6L|u;uO!EZv&=q2xt(xOIgcdKw&mtI9?yu>ZoS ziD1shDZVtBG`nX!8jn;M?*J=RhHoxEi+wx-d3)^bjVH`<2wksTawCPQ%;tZOMcv%f zI0`+kHSqjg`M`ZJph0Lb!2Ywy1Pi@lLwQl3ic~^l?|4o_5E;lRO-1M4{^p#unFmW- zfDDZPJUnV_u6@=nrn76A{qHe{yekXm&^=b#PqD)85bj7cfNO+ZEi%<$;l<;$W-`RD z(V5tRBFv*;KehCUpfrMoktRDfLBFHbUVmi9JvNDO-O||0&sy`*Q=~{*2k2mvRvua$ zU=VZ4z$YmL%|?VV4JyUi%Hr%5tSD8EF3YP^{2^uP3$97Z@bmTy&^vY>F;Ez8Cc2Vz z`*ag^F_lVve$7hvFVG@pZAMXd*RIdLpKm*#r(jYBBtgVdhD5dK;syHsyAX8jU}yMyFr?Ee zjxr)JZ_CKWNsflDZDZW`|cQ3{9#} zaGr4eZAyWW^mp#GesPPz(;M$D(-Pvxiyw4FI(oaJS_?L?Qcr>au*Z5JpeRI=vA$G3 zBhlz9;$Lf_R+79_Hpp<}78Qp9vrgcAL}Qr0(6lj0U~Ba_Tsl!#_>;2EV}@%5-eK-* zOvYUi@cdR8iqQR68wtg_7g1K9mKb%(^Z6{#kok5Z!1&VW_wvc-iO}HlxTcp6#LzK; zXYzEbbsDZ_8}C;- zQe-^1WK7^Fon}@NR9&<`aQ=-it?K#t6_aXG@|=%T>XRXVxw(KIpnI)bIRl8f20p3V zx|{bW;}iYhLR#{VGuu13v%z(Ae2o`a{2PGIO1x^l>BvP^wSf&*5z_sR^4QADY@fmo zzw1uNAJkL&c#nm$D)AXCvSXq(Ny43dH~YCpfgX1Jg4PA`Gt`;a{C*w95kzv}hhXeB zqexBS!MDD8n2jOV_5ABk(7b4PeQ8pW;iLzhi;I~{%BNc^SlrU9$;t<75;w74@8zuQ zyo9~qcN7521HOdurqMiDRsgZpRfp<+*g0s4ib0hRF1@8gwD@2klrJ(1bg@1^h~oww|qg z?+HdS%|qF}W2v@)i@Z+Dmw1>P=@^_ouC67nzJBqWIzI-AWMGq@J2taxid||mhPlP!Txr`UM>bN3!5{KkeWlPc)?Q_EA92fv z@;J34h{$luX&J>At_LjHd!Kn{WSssxAsw2C04+%hxT!XT9 z(do(OlV?{@=}5D13)4)bE;f)#;hO{g1{x6^tTm-g58NgH)2d<4P*W&iJuzTkSy}dV7$jkm0|of4Crt=ei0pY}gPidr%S2T#XEj=eVzMKawq3c^8J*p}DLEu!h<{L!ZX`O{fg-a`8WuhLC?LhtQR6 zp-$OxoW!y+!qWKn|qw)*`1sp@ef=S#_DyOor-gg-?Pm^|_z#$>t#jc~8 zAd5|+vG!g3u?UnrE(~bikC`T4s;O({2HAmGe_myob>|mORF^nU7{)*fM0=$|K<9cH z@QDfu=iXy^QReG?#H$+91dU2>-%PzEX*o7#+2fwpl-{I%3Gue=gV%!#cMD$?_fQM< z+#A-t92n{9>*gc!0eXID;&^DzaLBTWm1ACzt26-js1TiB_s)YnyPjDr2S+F3FjXXl zl*U$+_V(TSo}qB~OZeLJ)j^K#a;O*htpPtA(A|o1`)|?CfBoVcYqjhU`xNFuT%#ghWDv%M(#M6KcqC%n!`C4h>)jdmU9Grg&&-DP zQ$y@d^U>aUKYmOGx8x&GEP#&;i2bKhEzPWQPI`M*3gf(J_H z;GQ{^=Wn`WdVR+NsJ{fNueX^Up&` zEFmhbrr_gB9og!^yeX*ExNJ7*Q&Ng}z7%OVe$lbqP{>}!EVx<8F7bnBYkGb9eo15S zR_jUj$AFI%*-}f%J#*Lm`Fh@V@?Sn9JgH*q85Fa6KnVD|cjp_#$9sow-yF$5gEImT z4}bOI1%TIC5ue{m$7CY)a#&6e5%9xH{J9sX+~m_A;AgbDMbi6b64#bKaTYUCHwi#U zG3%BwUL@RNfm9Q2VPkzxzbd0|+gcj$!I&9G7*#{Jowq@TxDcPtaaXRO(QqK7q^I5@T^Zjn*r@ zC&}(USg%;dB~40Tfx){}z1lr3j?q|s2?x7Usd}az%!~j%{g229b3kSPDc5sI7R79Z zhFU_vE*%fp=PQ9|`=k1VnEYM-lEr2&S)0528`qR~#*jJ)MSx{5ta$E7ai$2xP-g8m z?{Ym@Jj~63EV^eGYq^W*12W62A51NF9^Wl&wiI}Bv!vz9*qYci?j0%7=B)zdppq$S z_&d`*+o>!7>lMf~?i|Hk&5Tj2ypw_Z#kxW(+EnlTXza3%23&i)OVRo&u|72n;~2~$ zgduk3TSbwliU4bIHO3cb)^b2>c6Yl=z3c|Kqyc%IZ^3i$&!=dg zmvi>J!Cqzr4AjIAPsxHgeBmP?)%mF4CjdP}TB&r(UOjVEI70or+-nO-IP9w)SU}Jm zw?$OfJAdH}4k_m={uu5TAno5{usvAzBk!<-Z)r@h3xi>OFl*n!+972EI`&)}5wo;# zM2xGTlTbFvlF$TZ(R<>+AdFOdNt5$rJ64ctmJFwVVPgzlhfUl}?09FWzEJhDV$u*7 zfT)xW|9oW6oTq->+yTC7U_AHb>q}>!&H;&Tp_yLb#$MxmwVl~u6FWGomY8%uXk{?6 z3c^TALCGl!`|`j>2G^G_0^M8pHMnr<;0kF3B?U!uqSlh9D}RCxm4|rh&)8k4x^Y9d zmjk#(ixlJ;;NN2-RYF)#TMH819u31Dr$IGwlL{BWIrIX$seGLeKB)AsJEp(&P)JDM zk`OQ{;OXY?K(Mf%jExSByp?B~+0L`K8!)LfRVd-ai;|GzsE&v?lyxvqYlIDfq_jnS z8Z%on>wUVLfADdxFAj`J9kDUw5RY>NDp<&dMHuT#&zgB#D zJ;|YSJ4VdC+M`1LF`L+c$iGmNRiD#ZFgFS=N|e#v8dKP2p$TVGa7wNcc|)vbjM}_j zfyO-?NqxvMUFRo;jmZ$EMa{T)o^nrjN1`ct6?q2wNh3V-IkEz5=WlL2%QHJ!FL{(N z*9)LhT9OgCpN`4~#Bs94Ll)(DW%9j7>|5(uq;4{GO@S<++N)aK%(DZ&F|Nz7U^_Me z?2bRN_RPhs)`SwADf@Li%Z%B)QQD)J_*;P9@2w+XcHj2vdsughW!gu4legU%X6_^E z#%^s!rDb_+UJzko6@&N{Y!=8GZ3ywU*63O>AW`3;EU>j{h8HUkC!&hD=NQ0qScYE5gn@&jj0Me=1`on&ZzIp)hlfzI#BFn@;U51Im>JqKjiSRT3tXWY&8B)*?z&#ph3 zr4AUqS)XhB>8j0dwn^CV)?4qBRTmo8MeB{(gW|DCT51_2$I44c7VdH0;G*crapJzc zSZ?jZVT{_zoBc#}&t`-Pvf!e7o^+dhEZzFPuWlm|dV#d-Glu8cS|ovy{(<1UI$(C( zU_hE}N0v+d>kE-uwDiKraC|evkhrN)n-yMgwt&-NChwXTMr=#2N}fFs&t;RAdpX|- z2rDLDnddN#vjRfd(HSjJkL=l?^9PhwUKY~KoCslj8(xDMhb|y4DHn6_r+p_6Q0YDD ziAUm^V$oklx2~fd^VG;WqvK~?>g24`FisMCEkCw*4YO6!XxA8)Z~|m(6ZKm^84#38 zV-)E;SB;{i%NuJ<8WI&RY^@tt!VQKO-DBtO=VIpy9fIL40YN7}IS1G`vPYOBkWw=CGApNxaK177#{joxN0a4qgJG&)wW_ z1up|zQ#NI9y@ACYwL>fH@nN_)Pmt?Mzq9h7V_=p6g{@ESQge=~1MYEy82ewA#5DgV zc~%`yttS?VNR+#5c#TJ+?OthkWygK{s1H zKw1{8HVsnon?I{PPlA;d(eTU&7+=G{@i$*!h; z#h5MMlS`Hi8$3P8{BunPA~`xO8PZ?i8M@#_A z5(i*MfAV5jy341hI0f+bjV?G1e+rAIDl5$(g6e;H3i|qYACgb92A5XSPiZKN6x zVuq&JCeu-;lO@9NC(w`w9C3-8u@B6W-MLMl+0QD^fu2BTnD6AV<5)pQ$Q%x+@{J zV$dp+I?j3$@QEEBTLhOXnJF+-Gzs&`MGSb^xpU9#+D_(oW!LVJ$6(oC2Xh7i?#s`h zrqXy7P|06GiUNKRXly%4ZCFW-)k}%VA3z=zlARAPRArR?IM|(+#Tjdb(U8(dc{ruE zEj|LD6$>T36pt*#lJtWr?vb=Ih@X(v=FPHDzNmTZ0|= zRA^H0nJ;X07!~f10$)P6nCO`S1)l6tH4n{&?f(Yaay@@Os^J|!REIi{Uc4wzf%Q2% z3Ijn5Nz{8WqPS~7#U=xP8ap$>%%_M9X2pSUs=oxVQ=i9|!RqrYYG@_{s@^WIkito` zlz9eM8l3@27sXN;Z1o%5o=(MJcqpYc*!_Mk;*Nxqn6)t`X(0aL_%5Ogo&jl75n{OL zP$%Q<2^B3H$*E(Xr~6Yno%McDR5 zm(`1-TQ}mC19rDx65=M$Q{Rkz`BwC%Iu(l0UcL!tchuxH!z>l+Q`s?+TTIOWjCrAh zXJ-GR5QGvkue2|5pEO)OJK3o?<1!J(j*G-gavFj{A%yH?qdR3Pt3Hhyij{gaDjSxZ zl{{Q24;?YTN5H#ubEEk3$!}y$wsIFUZSaLPxqH2Y@;F7n^_wD{|AmC6^NTZE==+Qwsvhta7Ra85COmKOpQ-?x!l6r4vHu^g)KA`W;Aq2Q9VebBRW3Fo{xUkFI z8G7L>VYC}yh9JVk^+ENO9#KaFuY7@{e&aPzUA6u`vo&tY3VM)#f^atd8&C4_e)t@O zq#P7Xp76Z;Ee{C~g9FaFo;3bXC`E+%VKf%9ETrPhAyUP)TimO_(=po0)Q$oREr>hu z0*D%<9YqW&D@}hM>}l0b&QY*`oC`iL`o&j;{vufom`5s*N?lu1nD1-|BuQhs)TX5# zBkK_rRR`)%Pnpx=M~hFh z&ANU#sUuBt8F0;@gnnHo*6xMx>B-)8i^F+nwE8KBUWt}H!0h4kP_j_G3|=I87A?#F zVHoOf_IV4&F`00{4N6v7q>(aEr}$F1%it8-X&GX|cg*)@;6t=8?f)^u2B|Cx6bm0i zg>>`jd`)kjGc=TqwY>+2#`O1SeAy~WSrxJ8Z(VVzLg8hSxNED$wc+6Mc#izU;PVd} z&a~LofMLHd^uvp6O^8HK)qB=4-#OZE73S7V7>jpMmJx80N}nupen5-xHv`vkwrB+n z5veSoIkn;a??V=nO?_0s@@x5$WMk1EgFVGc`^c`%Xc;G%tHOhQ$8-m4act1^U=Zp! zG-*$V>V@)AZ!|BA`-Cq{XHETpQ$DJOA|2P34q5pOv>1PeFL?AjFNpOPG6W*UA+YM$ zD^E6>Hb~fiAw!S((Uwc1t?EAqjRDMnsx4$DfMGSMxA|tEGjnnJ3YM@)8RNgw5v&Z$ zs23)?r&GArp2e<{nwBCL3W7dZD4z9|csz;yZ9{IR*0EAWe;b9&Qa(N#xrcSD@Gu4Kt3mtb+K)mNz4YPv|g0?Og+_Xx`v z-z2njU1WYy4@R3MGYt4^Ie^0clYRiwKJlbRp;8IOB?@sT22?**^{f^f;XBgncjlwm zRZ_73y*@N}heP*12R?9(UX&N>^K`n8O42vCU*7?eVJD}!vQ)Nn^{Ww&cn{PT!&Hp= zb$w6ROBaSQ>X2HN52eB0c0RbM@Um zg(gD0%xayxUTep@tDq<0e3XJ>{<%=81VZY50fQN}xn!l}F@4^J`2iLF1ga-`@X!i^ zD`v_|9$u?Tm*BsF+BBZ=p$G3;AJ?RCAB&4l{?Ck|3v^8mzBnq}AqQ~mHFH(*zUGzC zWk|@S)>5L_g^TQN2kH^Y%IfWZIZ{Or%EXGw1P(7Z)1>r`4HmC*TO*~TM4JuA3|{o(uxh#!vFN@=0xR;# zi9T0_oMC2o&_Ju!d;sSFA}RbBz*XB3Wa};mjc7vpI+6Vh;POK1p*7AM_(o}jFiU6! zsIMXA;$nbQr~5)=Lr#@g{)!Fj8&nZjQXv+UajQRG!irfX#Ges?JkZ$(x1ZdMCgH*w zv2l!ZlBpT{}8$gl~*{Ab}Th{pBsHu zqzg+K3S57H)kykV(Gl-tJl+LE!7_>z^d=gqGFrE#YyDnIT9f^6v=?+peZdVLS_-7r zmdzgQ8D}skJ$`Wn6`4Xy6IzIDWOhp&(d2Zx77Dz$NIwJ0aG$U|X`cqO@F$anK0U@t zUV%nGPS7S<8E3^p69%EJSi4cxO3nTqF!#`pCtAf3q+K`kg0iaqJ*LE;Mt9vw)ioOY z-v^)Cp5jb|J^Ug0Y76$B>+IvD$&Qe^w-;kijPEC>S@V(E?%<4b|5rn=K`2UJlX`2LgvG zJcC6fH2;AMAf>T+RB9QL#64aR^Ln87g!Uxlja@u}IV9dputSYfF9V*joRBj%@sPlkW#Ni%O9p3U|VeIo=*{+TG zjSrhs`HXD$ruiom@4jpv2X~2p_o^h_UyJ^J2`$~ub1lUbr_1Jvk*HWl!;B1Xf|I@2 zaQ_{}1$K+$i430QJ9h-qDt$6`Ifv8KqsfXbx$Dd%1<~G3`c?{{iKqE9GLOJiFR(gf zVeQnw1t>=PqrnHbv@TM13j(XXby#@JI;w4JZ2H>@Q2VV6YFpCm-FoK9O3+9j#Dcgt%|0F*%eG4=9#R!swAWf7is6c{%G+6<~r3B``<~@1;@4ogv*!y5#`(PjD zEGsMPS4sjq*mBQ6{?p-$!@l^P;82H{%VG$6G%L z894}>DAU($!}QDeJ%AGBBHH`u+EiA09PD`Uo1elj%V6LOW{4=>66l0-i&%Fjo&vJ{ zD1KZFeNiG9LIuZMHPo8chNajO1RhPg?=X7#DVZCw2F5__z;_}Z#R^uXEeJn<(f+&@ zSSSxBa|bpFs1M%m`p~BeVJCFq(GoTTx?){Qkm^{PVMhAwEurdi>CO{1-2v+yO(pkW z2pEMrlQpo+G!i62o(mV)HZ&l31myGKNPn@pgg!-a@w0jSmMPjmWwHhbqLYhYq2qwG zq2VaRn8E8H7?}tGIz`W(coAjy~=Ni+$Dh}71GE@iQ zv&_B}WJps}`rVJ>tg(*Sw118<|AdkdN!6BRzfu5LMmv_TZ7IWm(ICfe;bwaAk0W?Dm7hSearAJDABCS zs?EDyfb1prd$fFoXf3AdrKWujcFPJtwZl7B5ITjToCEAf4(QE@rvN`Nh}-Wd-*8UM zSrKpW9RNjdAxE&bEw0Lmti|);N55C`>`7*OvTb)$@$Z79&v=o&_bTF>QY)67$CEhM zSvv`azp(S^fr$BEEX<$~RamC>`;W4;=)Qq5#X)-lUj!y24zjK$M(=O-_nw??K;9tB zBrSDQv{kYMpBC3`I>ShRPtu;Tgp1C^reBuj&ByYIbLCAjrzJ4Ie)-DpQVHx)U2uHoS{(L|qjBEnmac_9{V_*#SWpzr>V#v71~ z=k+sTg|Se_bZ?$Y5Q|x%)CJaZ{ zIR9KQkOjy7y`(PTV8~0nZX#Lk?W&$J1T>x7<%Bba8}+qzbv^2A$JcVN*?z!5!EG|a&5OalQ4@F%C4@vlGSnkUG>`Kbvu5>ehgS^*BL0#h^V~axF9{l% z&vL}s$d3UJX)H7DVguB9{b;_jQ`IMGF_)+gl?mzVhC%t_#Xe5O;~x~{Yiuh9^z3Ca z-JFBp(3J>$4kJKV!wn{s$=R8`26Q!EtoRyFf18f{^R-&R=(vE9pneyDKTPEm(_NHw z+yg6Oa@wmR3kXjK9DAi{lUAc$1cAT6?D*Gv1xxA$_|H_p5 zhD_sPHM*qNW-ME(ElGU;H}SzPaD^k!j1>H&H??U~wJne4O&`G3GKPB|r0?9X_{)Le zbsK^SS_-;)sd9rBtYDZGXu^FQp_0fOLW znMf~ypI1%NLW>1N<`)G|mu_#txnoKLueEm#CM$pKh%|*VAx`P=VxawlAnjd=s|HV& z>f^p=pqEC!)#xsz7-soGX~1rf6}I6RjZ4-KX!NVdW33^4Evs;SF?%6=x>?erpv?e} zVMsQvI{TI^ql8e(vH|uOD(6@{4t#8#3qD=xZQ|5vHHuCS)>ucKz7$|0z=Jwt+IN2C z?A<|BB-sEmNBy_@C)O`~tqGUM2{KG$47|oqvEYe6_2oFtPRM zFP;0zNCOWxw_QiM?Tk{rHni;3a<_=wKfJbheR|PFuJ)^7tq0&5NbgXy>#`TYk4wMy zen>6z`fK*pl?K;YIdT$pDp6fKY*gogeMt7X8pjVys1cHT3+g3jp{f%F7*;i40a}9sBcHRvJ>+ZMddwP z{uQO%z^FKuyV(9|=99}WoP{+(GBh>>_a?>QTH?vF5;#C93xv*Vo<})Q49foB9p_b zA0=hG4mmaDW*V;LAs{_wKn}TAm};a=8-ac6ELifhOkA5?wu8$LwWdEO>7LI|%M#5C z73N>1@RoZ=Ri}I~!H6<)rk%U*IMEAA_z+sSt&!uVNj$~^M^Y-msZ8X^=B8@qRl3O5 zW&JYD=cC^z(8(w$EEf}qX^+ciIwAQh7Nz@=K7pH+9JyXFsd_`l;caZwK#_8K+?k1n z28yb0Q2xAId2)OCS&(GaTa0Eam$k7pPd<)vvNItvC44kW;UW#`l|?m>fwjGFdj3bd z#(WN$hS+M|iok61IG0^^^u87m+Ew%};H+KPxHr*Gfwl!UaT{G`H^~gC>ygq6B&vm} z-vXCCX#8vk6Nr&tYS6>`MmmA8YVhb z#r9+*nirdCmdQ*{ppCM$r|}l1+;k)=rNoNZ|E3{+WVaE{wESfxG)?r{Gmi)TF~ZxZ zN1qoI4vXVZI4`<87kh_3#zn`Rij(;qJx(i6ihi(;5Wq)04d~^W2@1hW0(}Xc|+RN5<>N#;O zN$FAz*OO_xwm%2tZC2B3hXi~94-)Z@Fz!qs&A1sGlivNG!_I&7g3 z!4L1j)xnp&lE6+%#cc0yc!$aPk*k(luW>!^f>PB=Wa(g#_YLHt3>__Bd72`mHyrg0 zC1?$KBQD;mV`-%OD01a_0CT1O3d4Dt{6*Cd2IU(59g}nHB;bfM)Q-@oM1|W?FC;Ae zEjtuA>@tDl2}G5sOku8+DjoFk_}UV*`2ED@yA|m#r$$;tIKhj_h&B{QP{0wI$%f%o zA%dmZ#-eDSAL2dv`eDsB1#@s2w+W@w94?_B7#bdy-{mHp1she5Z1Dd=%bVa-N18r%Y*@E`}ik#4K^Y9i}*mNLm^tgMPpcD#jY8LoXYzT(#sUN zQ-~I3`^)?4!1%V)(#~8K6GkLJ7rw|BryK{#zKC%{>_`@Zngz39W}N`@-Gsk4_(wkV zf4JUrAtaJ7eLnbUN1Y?+`>)TW;r)hKZ#FbhIlDglY@U~7@8xjDMNpwY{~T>1=hm8O zYLkSPqINWyo5x;OI5iWl@!cP3EE7>zbKq~pyDgPS`vHo0u20rVxI#xxf)z76AflFu zQEjbGA&XE;o!R)=oQq#<_U~4^h}xH$-;rA1U>aQezrs1o9sA$me*dq3I*~Wi_es4H za`Y10{yA2qFMTY|T6GW#Lt6y$bW%}FnJG%sGx03YqoIi!lBGR-)&hCOG9&~31GsFF}dx_cFQzYCCeuI?9A7rHvxGB=iG@SGsEeI`0 z03NJ&^5btzu~6r<%Xv5L<9>g8m)EU5`Oe+*^QDZ+z&ra**h8-3L&-Ku9sW2ED%o9- z{VV4NOR1BDyHn1Gl?g1EuGy2I3FJ`L_$~2Qi23_)Op!;x%3P)n_qU=P^=C92+DzTk z%B6Z%_GlZV>nr%o(ilCZs4)OBot2QGU3hI*H&KPU_M)gvc!qOf z14W9RX?Gi3jG;YqVzKe`dlQoR)qR}mPKR!zlII=-9IITE^lBUJBn7ZEBs#T6DStp3 zuw@hVfz@+FVH6WzeWKJ$UAL&qyh)@g#}kN3f^BX22zn}bLJSCmM47o`go_;5=^pAAuB1l+!wq`!ET-VNSo9$0f)}+H z4*EaFZPGDqs@nu+h!8l!sz;qRl;Ci)9jKD3e}a>2DY`22Gtw%&9yFuzgRj5eDDUs_ z$()@GD3gK^2WJ ziZsacV2>;R>-qNiRL?W}q8nuk&Q%b%N8Fc49+%(}U6GoLZI! zM^Z3_W}L$=_%LC&oJjSsA$v0^{-RqFBk&$1W|Sv#CeAP_Q3~+2BAE@N32y zvzE;#I?U3t+MCk0gQZek{zcxgyB zyREliXPtZ6OnpS%cF$S2+Y*eP0={lQNv;uMT=#5Jh*&eVOnBKPqIWzwm1?FmFu5=2 zQRpEh)}f}`lWG04r0QB|!`X+`cC>k$>f|cpJN16CV8#o6cE(0SX4ePJbasjF7-!p!`GtuR1?TUbNZW>3)xi1vgGT+oAN@C@_J7j%MCX07 zo_x;RbN)Qv}z^)~>q1FuhQ(^EA12~`_6UFY2B zZPzcr zmN&V|jGt6HGH(1rKLSF7Up!-yFB#wOQ=sJTQn&7UWh@*mEV z;!dNoE?N_1dEIkXOgqlL$yI1yk+V%p^CLrV!(Txi=9i>kCgC_}LyJ2Le05(Z&lKQF ze7f!tS`cuvf=HVPFLi+8(oMB$`loBH$>~xTHf(FH7Q#w0k@>&9>Iyk|SWN4_?C`hu z!a}d?hMplNX(W{3L?54LVPU)pRmRy($u%EMr(Lg9IUP)f1+1Z6%9{WC-yzZaVkzq+ zSa~fACwdfUW)|TWOY`EzVHUtzYe!$&m8>yJzqgTb@RVq zu44QrG?Q*_2|7_TMr*t3+9EERso%6bwaU=&+gbg>S(uIe*v>KF3Q-n*xG=KTm{9Y7 z))53emiMfybL;H3JN7)7yF2+{tivuW>|TxJFG-i*2H!ghu|IT~{{Dkh?k32|8(Ep` zw0O61Ozy;BoKD<0;uy3)Bb9(C=p z#IHCh+D~*6Qi>VN*N-Ga6uAY7Hw{X6W5vzd(|>)|JXycJ?cpw!a#ed00`Twc=hj(1 z`5`}PT~bn1ZCv8_wpyH{^?4#u-n#lig=Nk~%M!2CHG`SC3bq%wK2Ij;hELTjpRTF4 z?zl12U~Lc9*^{j!0;Y1;tn1gTE5oyMdWJ{e{NHcTPQXlnK_cZ!c*DYHIQ-35gYokl zAq`;Wj>$xj*8B2vff`1F&o_R4*tZAF>NY|`em!^P@Bn@H&ANNbM!c;B2&eX<#*rMzXxAf5NsC!`6 zNNY)_>Y#5yo#WPy_=A_w6G>SXH{v!qVI*3_lCw?&SgSL63E|c zCK4}pyRJR?|2P2k|42SP0c>9#;gMKMj~uUV^gHowk&fCGq5N~KlW-_aypQ^4^4~_3 znKd{25+P(L5jTbDjQyT+B(dOv*8}(1p@;|%8UAj z>+b2B7ja$F8*Pimb(xmvscrI*jbOlFzq#hD$L}9@AY0Bt^THMWbn!(`x<|( z(@d2TpH=3Fn&6XC_#b47ZwEtKF9z;nwLfcx?1Uy%H=5v%{(YT@gd-u`bLLSgu(+QI z1_CrHfeR_#6c8uZ+zi@8R&vmNke~`i;}yzh##&1%zSIQE-Po3$ORw6GM_y^~y_ElF z*M!zc;IC7SN977XEkEUwaoUA!Lx*zDa7dZb^<4jTSDRk{%@H!ItMa4`sriEr4g78+ zP{0iE#62Kd#Sia}zQ)a66Rcgi+wwPKhMZCcC&`FkBqt0`kE&%?m_~3=EI!FvW0j_s zD!LxS34N+1=fbibCpq9_I^{U^2UM@JNE4(Ug89zCqwddORLl-Z>AgU(e&inR-&dm&ZLM;?iVr z2uClt!DSp9Uh$-;vGVRe$MS%|w8DE{Y0DDADO~|AL%QP+Jg9=$565W|h`)VA&3BJ3 z_G2xrvNCVvF?GXb#-Lpq`c#dNs(=Hm!0zRAy1Wmv3u!2^)08`MASN1j_A%6}6@Q8v z^-ir#8MxWtAnRCUL+#Wr0sTDXycG2#Y9@31r>jh1JQX_D`8i*aA9G7@#&Tk(CQB*oJ7+k@|EenDC^qdK@!qn z@Kdh4rZ#P5d=9NS>URs9J0pH#`}0JTK8_F~cDVt*MNBep5~Mr5mYp*bE%y0Q7JFDq zD!oxV%kcQTRI?NcMU~d{cbLIU8=S!!CevcLUTVAKx6PyOKdL-4&~_OY4zJyhjX5}q z_@Oi(UhJZGqsjQaHjQcvK*W3Jo0XR5UFNM4Z5$lXc5e?q<;wK`ZwUkc#wh&H7WM!C z^xr>7*!(Pqs73e*%n-g-|M3XMg_-MwNTkxitnrorci;DXRfnYgcYRF6fp78J&H-Z1 zaCQa44!k%(yg!20f=Y2?`yn6Ra5=CLKX}{;@B5A((*A?^XX?L-IbrVo;Gz(udxDC2 zQhrLW)JIp2F38KS>_?q66yqp&0-Xt4?H2lzF8@``(V5PqbZyLqtB;{m}6GTkA)PWG%;je>%13ah70!S=J)ZmL%I`rBHXF3+T}NQa&$7JBn0H*03+ zURU)#D-u-9Q)Bb^(Tgfq+s&TgyHZAGhe(|!v+B*8^Wzn`)YxcgGtuDo&vDa{ zhnNgtuwQ9VV98QAaRaP1?My4Nf{v_&O(9fbo%Ks#k~K<8*z;p9IAv3-l=h>D=S50- zs{ULKJ=cGOVj<7^z1I4NcjjncCoVzx;Y*5&**Bvs3TMEmpEEdR5r*)UA zc?O*MtaI$etSoJGd3_-fAsb;2>af4FeD8B)fgSX}BA^k-%qW&N4Xw#Sq8=#I>SeX(Z=;h{W?KkranF$qVa zE0pVWN6MZwyDbrCkbu`GiLB1a3VVPdT#O&99+|9EylT$mkiwgnHX~}?f_QgTn1r!` zU=p2m(S<9k(vpu)JM_S2OdU$Fw!?mTYL{MW{{GTX=-YlIT1A|{xIV(UApLeA6tJUz zAr#+IX=xiEZ=35h95=Wz9i0)m{{-3su@TTLoV~n%e-i0Y#kp|!80GyA<@bsbgP=8> zpdD#|F|0oL(bx=JyMqFJdyzkYfCYXBI7oKxe*WW4o8EG5Qo7cG&(T;b`wtbBmGWH- zKL<60Ga2AJJshUw6I>ALAUX?-=nl*Ks`oSZQa@<2;2wWZ{CpPZaIDHQ(>I^Vez%1T zTq;$tre7<&WGii#}i)=|MjOW!~ zDZ5lEY9z=d_Ms!dxJ<|<5fZ30zE$_D^qQ_TMp-{9w>(@F;Yuv9^4#w5fkjsa2wi_glp$jq#aXGgLV96=Nn zqG82>PEYXWB!>Qn8T+3)N#1}qBrd$gR*Jhc?K{;D-rW{$@2^=HiS?I!(Vm4p+v|8X zXYa-}J?}q#&ex_ldnk| zJD_>B{WH(9Q@K39tADHWoTO3n&OQ|q*}(NYY#6R2)+W@Vg)N^4lmL?%enXQvx2@j% zb8M+{5kQvliFyhEeaj>VVnc{Ai2LsOd1;IA< z?fDOpy<)9zBhtpA=eGWsw|JIYGamQXb?;DiIOGHgTp8D`Os7r{d*#``UMZZUTa~%D z;tfwd^~Gr8UX3wl+)Pv;F0O<4c3cyWgltOgbz_afh5$j}UB`X;%?1-mB`VQILeSZU zsJvQGAFR~Lo3Dg?SkIo`J3G~E8=7jk@KoiA8jwJiK63{zc=!UcTP@C;G0+eWKkBd< z>bX@j;|#M*df7Z>XTa<1S!O;RBRKfTKik=5Lw^z^Pz`0Kzu8UH%l5Sp_ihGS`3Ebn z)Q6j9VbAyB<)+DElhu~tM0iny`^~f*zlq!c#|Ue(^EJK~(HCs1Zg1FC!&0%F zVU-mon(V6-9PwAgrped1#<2u}H%lDiv)E)v2+lOoV%8V)=H6}@St;_`GgM-w7bj{2 zsR$o9s11j`i*a2xe5vq_-JQqHOQas)Edtm{LRr$#@M#;%LA}gNGQEpHFoJ-};qzAgJ4ce?S$>C)?#M z$AB$GC7h$!RR%_X%+1Ivy}ii2EDTozR>{cd(zlp%PVZbcdm8fh9jCRfIG6xU$q{Zk zE|E!82=fKe z*G2`N^2_8mwW)W(kkl3&&pj&}tszaGPNHVe_?e>Vk*Yk;Ha-Ie;aL_<^%qCb<>o9! zZ~2|ntf4q`g=@*%WwZVBan->4mvHIArPdjwZ{=p3_C$o)=1AnTsn-?ECelot0o$(5 zZ$2B^*yvYv_e`p>@TZ*Un#|E){jXR@=#Id&2fCNsx#R}fDu%sI*-I@MUcH^kwHR?? zlbJyBaA;xK3FXSu%WcSe+^P+vf$1NVMJS14XqP7|nY`k9-Qi40Xkr&+Q%TH_$Uj*G z?3}crO%BYmc=nXX_C`DT<=)VS>;E~{qVeY%5}jNoAWD4sseocHR(1Mo&p3n(u@GQE zPt*N1K!^Uk6lDx4z~c=?HW&G~zLxV00SDLFS@ahMwETrLlZ|((*b#lHP1%mc1JUq8 z?bjsc6?aLYpGWhUbCV-YSUim&b-EEXblKiUnx`)*LS_tnVB$dqW z`m+uff_6qzmWGH1;W z9}|4H!|Cfwr2@;<{U3c9VT*3-Se(%fuz0D#WZ?Y9J$O{_WaS&BZ$sbwRksEj#^>uN zMnClLM{zz^?ml_nD3IFarFLV5bN!(YpQAJQ&O~)gO?M+#4d<%tdQVEgv`m2Cxyo59 z)HZ;%VOuTA5Qz@2pRX4EbAKK8H**F5189I>S?Zx!wu#LlyTZyZe6rJgxB4!6lE%{L z_U32Q_xot6U#Pp;@Zhe!Om0Agyk&{+89KW(e7`Q=1vFv1491-RW7*tS-A*j^Wg05t zRoSyyNLg=LS~=n!F2>?Tw)ynk%_bQ5_~_{M{KjYho{T;cG8l26W7h~qe+}qSDZG-X zpR`RHU;W^fQcV>d)L`8!4zpr~ z)fH^1MCO|D$2&c9%O4j{TKkcDBtsehokfX+-HuunBXTF|K1VSP)y8%|s7O5kiPd}_ z3eqW+4$7|;dg-upo%;VAnj{M<`MkS$Uzesa{eu5D$#RS zo+e;~8mXi7uR-0V7F^~j)V>jgC>5frY29x4a@|3!kOf^rHHG=*0`rS12%2U{%qqS-h}I-~nIG13`0K$N z5g%o#aKkB%HRSg|_kWHP@~>U8Fk^g2oHHSj()(JrJAzSzkr?jkHuz~2P%y-j>y_#x zHhi@$GH7t;b)R1|dw`m$mvoh}NFD*Ah=D2N>QTL1+^k) zR;u7>J5Uvn_e8b(k_M?b*&Mr3LOW!!X!yFsaUQ}(8GC0QF~&cyIr*Nyg}YYGr5E}| zGZ~A#QM959|82N+luuQWr9?R6S%xC*@fb!*1mOz3yCitjTgFr62g&-aw8WZr6NmWGP#-# zmst71XOi^N%bl--huSNg+6LwLwIPVq>3)_UM59X`X)bg(eDdry<;F;>If>X+iL6dr z;DWnv3id#~aB9$~0&0Zr#1rmSu%YNLIx zDC(J0a?^9x&b;q`0N+&niKSS`!a^?|7X_E8`|j#pKw~b~{VyFmr~MrC8_OTNjn%JD zfIsJ#>EC-~DhVrr&L-3xFr#jc<{us_Svr=Orz0F!b>}y#4J#_NUXF#;o!1I8ht3Ja zpAF{lUr6Vc_mtWc=`&B+p`&aOJ8?O7!TLC5L1`ANlA+`KtLS`h)VmhwDH93cm>Izey)=dkk1)oK7F1lX%(!}P zwXS#6ohyv9;TTQ`JGgwX9JIZO7XV3hekdT*U%#LIr92WCyL;Ed%r(ulYxeg9E3mj4 z@-hPH{)$R}Z=698Z?g^Do!l>%KiUxTVX$_1Il}4Gy&NtNcNJew44g>PiLam{ualNI zKSkaRx4Se!{CGQwTpOyAEmrXGsZ5g7N_(9ba}k}n8(o+>Y{xUS8kpIFKaM#ec0pmb zf3@I_C<9xiG$^@+)%IU%HK!$hzSZ`DPgB5JB(=cx`){-vs?}(?siRz2IqXOQmuA#? z_~eVBIXr zFohd>o1yFZlsvT`aJF0{9jC!}adf#1m;ZoeKB$!EL=`1sFkG1x_sRK6@EaLSJdEGr zXfoIQ-WAV)750EbhHJ3g()v_|vF6WG`Py(JD53OVX$|t?2nD#yOg{#%z!EM28DCl# zg^(7&^7Up5sX;R252H$w2UutrZgaqp-|^e~3<2lnG!qJ&w>(vA^H3wkE$}~+?lFjt z=({+w^v@~?0GL6&t*zEg-{tXv>5Ycf35L$m!{$ZlYE}cxHXe7o%+jFNzM0Qc!);2j zXK1j@>h0KGOlDQmo`$Ljh`L-+>KSg@p{vOYg%-okd1CRH0$}09aT}6uB_eaUE9Qz* z9;R%y`yLmp$fw&!Q-$bK!U}u+TmSM!QdPkxP<5N^2 z^m1~X>at4eDgDo@em}mMNv7`(9)-^wFfRiDH-IVdkEwgWvD* z>w57(k!|l@m1m?-g-Kp1W`!%s@PE?Y9kqkidyC!;ccqpF`ADf#Z~0BpmZW+9sGXwM zJ=|}XzjnSMg=S5^=gDzi%FneK(+#}b55{lrjl%eDz6|B_|BEf8@id~4iG`LDXP>OE zz6R|eH1wEZy~H$0_w0V`6El3K=Ox=YRU3gZM=Yt(}QfKjq2L=lJ1 z9D|13VEhs-f@NE54~|0$%tS*~U~Ck6uQqIPv{{I=0r_HE!8LPctdH=c)d|rcY09Mc zgZ(&H`^Xf!S$vyov3OGL-)y0X9B**+vaAX{_D%=S;`!zdDa&@YqiMH2N&#wElNd~_ zE{|WwN~}@VR!r3!R}1ec-aApy6EkKQF3Y+C+*5mSGhby&vy(2QTzhW&l8{1jdO9ToXwx-+maNS!t<}s~=H*DSrklD|wru%qL&w zjYeowC5{*3vWk?H&)P}s^3;_@IPjZrZL43f3wn)xg&ocmYih2LH{+{Lds=5f%U}y{ zqnRieZeypv`enJmw^B_rFl`Bz*t0`-6E^`y%TBzBlfwTA-GpEcidkwL^UpEi^#%F7 zKZB7N=Ew^dhe@PzEfj8`U)7lRleXE~nD+q}CqrX}2f>}tDq}D5JWAF?`A+EMi6w^B zyLEeTi;#*kJII#}ruhk<=U%0}GsBw6~iuEg8 zB_eT1^Ui4|=O8&$#Ju5Cl=3NVee)nGicvUs%K!+oMU*p849?d|0-{i~X zKr>#NHO>nbyR$7Hmt8cJ$p7;>u#>jMF;Gc^CwLP=o>Xq?obQdggVjT4sOv5^QAK5B zk5%SDAk_BFTWUFgXohd<%b5{&LCva&>ya*@@ok<*N<~_K%xMqbr2f~q)SF+`M2}P@ zS(y><7x_9(Bfe$HzE*SGa*u1dyOL05Qut}ES6sQ0 zl+&7Yb5+jpw%GfNVA z$}8WJ=t7&L`}^1e&87IJRC%9>R=k^PEvu!Sx$Tw1nvpt_QVWH`uhtp~BtBW4!gbjU zD3Q~`&7UjNJ|V4gCdR``_Vk(clluKDP!E-&aU?SMDa!ZU%!o(g7<;Zv(z{?mYN(bG z_1Z1>?U>*4#jICkpYE_Sxes07-^)!RcqKL})ld>dSOe&E=sL~?97#+%COp~^?j z&dz@Ba$+(K%gHCrgKD#B)V}`5TlHn%Z2~`$olGqiWJ9m-hhH0 zTVGxH`(nV5yy_YFIw2plyz@NJkMO0KCt<0mP)C``nf2yj%bpBdu zzNSGo^|MRo zlA^#~QS80I0WIBDVqp4Ecyx*CfGX*;?+-r6x}_`eC7byL@p^-Wfceaog%^IBZsptw zPkXgt#9z29w~CoFGk9s|6z5H>HcLFLL;02Sb1u!`5lf3)frh^VYsq*sCPo4rRyG@q z6KCsWKznp)Aa^IRo%aND`~in|Y4IEwLO+sY4`$)5mV*^W&{-xuech8<4Je0R3vP#k zs~0fJ45VA(?FjZ%YmuXpyR7^x_}$ikcC2Il`&3OH3vt+43Mp@BB78{kNj+9Mh;+iFkXLA>%~UJ=4Gk8xb)+qyELG~o zqDd4hOa@Lo5$qJs8<%0QPhHJ}O55Y`T5BhFlt5B7@*ZYeVWPsmJ`~p%OiFTohrbf= zSGDLg?MZM+hSDgD%UXN2e#ef$I?S%z&N69Pi&Iyu9%USMCf}*35wmw0>A4 z-kEUj^Ut+?F51qoI5Q`xd~9=BqJ==~4G8buF2?xVi)Eo{`(h$^a<5)k)Kd{_h`C?W zT#!!IW(AEC4V&UC-Eo`;BIbtv`QC-llj?(VDm!ty?db9ln_`d`x-ZKcKZ@3RZk9jX-h}7vj$1wvAIg-n1rztwj z7hH7T!D!+GS_}3ZQr{zNweSPYn>neO-x(OdXZlf~kQ|9hLf7lEe`&Q%CcOI~Syr7+qF3>#9Y| zI|uc1z{hx1iQ+5x?o$GWS?6Mnj@0Y22cWyvc5t@LciX1?+|8d4N7Y5|`Z?#hr1yKe z-Q8rA#D&kI0%{}r5($Eo$R!kM@m#y$8>r)1W_3a}T@oTM-Lr-;@`of+`};YqF$c>Y zs3l5Og~HSt8;Qj=@4;}!TM#zjyhCa-CO=-!erHtU{tn+5%+M{uUo622amkMYA|gR@vq$`EuhP$Gt6(RFFTvnkr6M_!ewulH8d(Yw7UG9YVCRX6+ zuBGB&=)OsrN6oD+Xb^cMu*|clOl9e+CI^JBo`39Eq#gEw_0*r(9~=FYuNT2f*S#Y= zfQ37K8};R#8uU=p<+uyn8QFgZL^LH)Vj98O{&IfGiCT{CL>wYetP>iAKLLFv-DcaN zOLFLR)}cYCI+#fnj^;A)85hbZ6uoW0SzVFBIu_(UMl!le>*Elo}jc@&OCtI)2p0=!xr9X$ev z`5%JMb7zP4(j)nAf4E8o%OHmeoW%*|**Tfd-0cAL>$ICv5y6y^j zcvOEbTEYhE^M!MK9Cx;YjxrM3^VYf&7VDO(<*vc zjuUBQFX&;$pEKm7aZpEdY&X4CM8X1oaZEQAf0g+f^VcVw>nZJ}&6}f&OdMIeDsw~~ z3{rN5%OnP_iqtIiqE4|WxLx>#JGGhMFb1HH(>VSq zWtar2_qVpwYocYUNamK1FyuF|uVbI&Q>aX?JR+m@s*Ak~AXbLu=b|J=L*=@2!$MXa zE_%~?vc9QNOEPGkF~5xGbT) z7UrvGR3z}}j*9Kd*r^##>%8etd1H1S`;M|HhLGzOuTa3?E&QWwkHvBm5FF2Ey00y`<6n_VSjPB6kJwBYTp8031Syh}PKz zq*vrp`F+%>KF`GqaZ?EKuf@Ew{n0snq7Zh+ffc;i-<05fX1aqn=IS)whS|pl@*z&) zjo4p1-MOYI>M`}3V-@~Cw-+iO8>tjypI$!=MHMf2rR{4s&nYY&i4TVc&t?Qf&GHk1 z*Sa&KtgA#PtL1LBrYG>`Fx4VH2G}Y1I(~37Rj*B;+U7SDcX?<)vyV4buqL)lApJ+C zqQvwKTk37RD3SR=tCgd3V6OIc!&k3UWNCv{=kU@iV1z5X2d8B3qUR}{`Wbor-%jYT z{78yp4*COu{{iwDy1fecKM$)20f@N=m|qq_FX~7mv>tZY%6J@LcnKsgHzmKF!>#VW zHwIm>l?19_45TtX?=Nil+cf1r-E1dTVI;So?*;2Ltmrv%65 zuS%^&bKM_;1Y7-jdFb?g-KgR6^GvW!(B)F5jj8rwucqQ_St8wz3h~je<{1iV%&kJQ zy6>&Mvdjg+)>2)9-?DBcsgCV~&KN$Ve5Uv~xex)cWTWw-oPFg3Dk}iZw{q>t#bG=* zq@~NpaqSO-8SLVH7Z3$4fd4txM%Wgpz>Bj@=zS#p#ce4d&?wua7ofW!rwz3%0C5(B{224j^a$}*sp;vo);FUwsiV6R?$~&U;JR}> zg*h+6xpKp5z!Ne}e9MQ5MU+948O$AL+J~Xu?jAcc$eYoGQDWR8d+aHQ1pVPZLGIOg zcf0#YTw(N93mDze7H!McyJrAH!wT$~^WEM`-?B*tBQJJx~Q9b%^Wx0g!M-r|jBDX2!g$+Y0zLzHb>Yc}11?EiEFZWx?V z?eHLsXE%`@g#@z_Ws5!4zY6liyi)M=Eos`;;rT;;qQOLw#*~}Nkv!YP?_QcGX4=`7 z^0#&A9c7k8<#_VqoNXlygU@?IJI86h6TL?%I*?jo8mxmJtX4F9H&e{V%|H#Yb zzxJN{d?bp19f=%`l}kWFKKn@s>4IRuk}-Tp?WJ-7sF4J!N!wqL$0MO3QtFXD`$6Cg z{1-5?$=%=iV`kb4OV&tb1T>Ax)8sz0YA6Yignhfm^aeiVDEc}Xqtiy!Mf4`f$#k#g zmI0qT4Lp~v(3%4#DwQ^p);XaqHio$?1tpfj43VH;{}*%b`PWqTNB_Q#*F;dq1||~q@0fzzL3$T_gZ}QBIC|+g&RJk{3GY~RJd63Vtj!hdoJwIJ*Ikh-Rw7d zfWoCGBhX6gM&;9=(*s>gEmCh&#c+E`D#-(WAjU9trTq)Kc`ze1N!2{#Z%#Adw zq8ij={4kJ%WI}SlewTER%%8f#-wyldr`co zySUvS)#U^ixp-tS0-`HZ$kRDETM;QtMIZu6@rRk614H$$%VZJY#IJBf?RCJnc3Z1i zAV;QmK>a#MR&w#LaIEy;FJyhrGD79N_KQMcCBOfV8wlibCBLshcJHl`<*%)wANEW2 z`-%RVG`I4z!7GbvKx5fGfPe<1X(Wy^yMlRAk_-xdB051A3E_k$zl}4nJCv>9+t|u$wsJ@ye*Db5o5v%&NF;o`2M!}kd-4| zezlOvh9Tf1l^)yOM;5dv$1^(t3v?R@b@mcb6k44@nCsj6QE7H@yW-S|0N8_>&-@{1 z$94eiSIo>st}HVw(8El2lIyrucKPWPLX=sCqJ{X?_NCNtQs_PS?5dRz-Js&UCI5!q z&Ze#T&lKWg_Dt*r56ywex+{2P*aRk#5ZP6FBM>Q=N@r^)7Tl8Y3{cNjn{Gf0r_cg! zG`nUQ@>9jqtE^*m4zh#)di2VeKoSbjmuq%@u+V$M@B!Mos&AEX|e2n4PvC@D_IzAWQm z>!Jiw9N4j%C!Xe6c)7bYrtS-p zz$R4Dvff*&QC#c^3ozXN;V14OO4Q58_VqbiNvem46(h&1&^-2~D@Oqu=SMgY!xvRK zc~wGG!NPTJ@{?JLHO%vptpQN@#`l6tY^9Chmw$g^Or(1&bHbpMqTWl)JqvmYyGE_d30%x)Uf?mkdeCq{8>TEyQ?K5 z=xD;{_eLS8DUsb0Q8aq`WvQ4k@p% znDgHD)|rC#$!$A*S~hE)t6(S@11qUMUBGy&+}52zAJ&-7_u%bB6!0=+ZeG{^Lmmeu zj_}sbY8C2`QBdO19^DSK`EDaloZu;$B6(;uSP})bX&cj+VPxK#)pzKQOtN2Ej!}+O zjLK=wLauy^y4xv-;Dm)74&r|X$*B;(RtGh zOAhn^>2JOEUPYRgr)n%R$F}@{SdI7Wh&>zNfRZE+m}i$*v+>=l5eghXD|Q(v^GmkA zb>~zJS#YQSCj4&Iy)f3Lxc|+^dK_gsb#_%y`h+KYo!3ll!VcbZ?!vOdk8g5J4d|P) z_{-`GLKh?Mj}jdY5q1f!L=FA?goWGSg;xiIb(V|q3KoIt4?6JWAva0t-Kl=RvjY1} z0HV!6uOUlVp+8-JT$p9A=;_@$TE%l8r&$FeFI$1`k}-WDrRZXRS)%^grox_Rf^g&p zpV^wwA6xTyaYCJS_8(sJ$+!1~Zz~}{9Pi4*lk*P#RhTt!FA{0rhqwoMD<$)MD%apV z3S(|zWl0}A?O25f8;oH{zr?2=&x6~2va{k>dtY^ypihRU{;6-5&%yEuv7&|ga^OUB z&1$4{>V$3=m|pR;9@TAwg%kbK#xGbKH04LOB{krN*_am*@|hH>w187}N-X<2nLzMP zToZBlE6P%XpsQd^=k#i$%7HkMK(5=v*B?KF*ajmukK|+j_saM|XL?|l=Z?JQya7vr zto^)2=!r?WBTC#xx*R$DxrY-<>GvXW6FBnqm`7OoXV?G^vJNw_-`Lj0RjI-L0f6h1 zUOlUcWyaT7{k^nvHaPdWdr2a$tJNc-?SD7(Y~>pBlB-LQ!Wf38})%=#$;d)M&MvXJQCH-KzKkO--66QZDnaOQC zA1831qDUexEU+-dx?R<`rTbQ1t6D&aE@i&bov6Zd7*YSW&awgCRt3M4b;kgmYbMA3 zUFo!$5-6Tzwr5*`Ie)L@HECR%M`GA7?;KyfMO=zr-7(FU3yOt`xds`P|K8if9?ulU zy<*h#m`c0~c@;da>Pz&_au8Y5c|10EzT>RKXWO+4L(PZZcC1S^HXn@#;%U>4mFlxP zg$Zs_@J200!JIP0w~2$jdaWmFeWcg%O>0`@)8Q8GzGCK@w*c!OICHnJOsEg9Ax#9r zm2oGv z?ayWhUCH_eQ>J&by9oOxXifVLBA7Y!(5mJts3{Daodkv+@68iTi)f2{W@J-CW zKS3T+H(|GL&8TfePegsYXr~b1b9H^O!a@paputIPoI}w(#|hirmEdsmNXV9^HrH6 zkupgpCv^JFpy}5WX*xxhY%e+&`KmisD}e0f2eFZEIp(5hG50)0ly_;fgvs{chsU^S zv%sI}T$`+8)5$e%W}2>R<2e#@LnBLPaZmxM@gj`sw(FSKtH6%?#UlHK1B$%e?hnr4 zcpoqvhoc2Bp<1!B)))4mkI?2lnK@F`0A_PMur6G5` z70!2R$fWx=M-HM$7J@>tLcAu{Ic}iqQ=rkAedD)v3qB`_>F5Ua>#g9Z&ng{bFT^|% z8;uqs8BDZ>YtvR+dP%>(*#W1?(uEuCcNF5z_}0Fqvy;Ul`z~L09Qj;N6_|Dp@CF8!kAAe&0}xiuSVc-!jYCVg4EowK*vFKj{nBuA$9 zD`Da6`Se{)tu|vXl*0@bau3*;Tlx%d*F79uJ=k`u2MV(~74Z|n#&|d6lbGl8 z)w%g5_GcZ0IGe6>NieJ}fLr2BShj%GgT0c^gO(NN+n~Qf@v#PT?fZ)EqKY6N=LEu* zYGoxd>x~{$~I^XX45hMGLo69ucAy{xdRyhO&PEJ5*cNixAhj$d_l_#1Oy)+f>)Jyq49Qmei zoIUvM>+Aj{8z)W*Gx^jKhs^w%{bgSf{L6-GF}2|Zp(dd4eHY6_E-6iec|EccT0U4W zXyg>RaZ4=dD9OBp;*jW9w-DT6Y`mn?HM94l{C8%S87h7B#j3u7WT*&_K4rDp)eS|P z8*RyO%b+>%p!C*901oz#KpXz_e9-Zyh%mG^ccD#IW|e7PLgxTv27;QYw=DlU%2+Uv zqjX`s%RvX^CL2@}{b3@~YYB_Lwj3*577@$psxuzF^M=_RU-L`30715%@ZCl<{rCi# zHFjszNMDzF=q>!CDrQ96Dw>8{f1%y|w$!7FXJc zXXMU)@~fS0zzzD=v2Ny=U$aF_4M1TLare}#(`(fas;QWdea-os3%lpb z&l{kRs)0LP=-i2hN~+m!UR!43><0iUtL>8ZGzC7N)~oxXz8D)}s-3;2Xz@R`^TRT~ zt71dISDKPuch3{&hjYVI+ehJ=+?|s!HMq7={X`%RS z-_*er)zn(|g%Rs7*xt~vkLkYz_f8nT;NDW@{I+34(!HQ9HBX&>=SDV(PZjp&I9z4|=tWVB zM8(0uLXIF0&CL>Bw%XL)A-1Xyhasi~ZRBw|<~(ZSHG-FH9WCr(IH+ zq6J(VP;U|Z@ergvdPh7^(*Cci)E_N`4eMl^6|B~tfIf`1uaq%m)-5yLxs8_2$zBcU z12PxMm+r@wsxzx5QAxMQYJ@G1Ja+!v+k2Ln=FHvYwT^#QsnGIFpZ^8}HL_JNv6db^ z$c)OrvuiJ4Mjz+Yo0(;YN+t+?ZEKEs!Q8eq^ij3?Fqlm7hqt#%00z%}&gC{BrOK5g znw)i-29flc{BUOlLt8~_Oi%2)8=Lsj5KH^gs`EKu0GU?_6lt-X3f8aS`~}piqmqW; zAbD0k1jK&^p&%kL5laxJ5os;W(ERk$cHFZ1^ajvSk$G`$?G-Rf%&hkgnVayvI2G2` zV43*kp@s$_vz%zogVv6xD+EY2A{AOX;xxz0&u4u;e8L0__2J*@7?u$tE!!rs>V?N$ zDP8sQ{et|vLc4uF=7ZfAg)Y?( zt5O}04s~PC5mFW1RBfVH$$R_XMNX!?^^(CFl8HUScU^2W`%A*5uW7dc2MRQ&U#Raq zr|}YxZSmBK<6H&xM2u}je$klkbLmHxadC=!rcF?UmS6FW#I*eHOv?t>xiWZksm_<# z;LoX^RhD^mPSh9q?o(%Cciuj&)=+V3fMJmt1zOf$RL61f_Mqw7j2EALDoq%AWN!lv z-)ieD5But?1gft_*OkvVp3m0$pSG)TcL}Kc|H7O9mm>iF|2bPet%l?`epdhfL>3PG z_b2NZ>z@)pXVdqZ`-uMk0|YSp{}QRlAd#vS>~EFeVnGU=h8xzVb(Smm-G(zwtq^ZV z6Qs>}ZM>qv3<=g0h*;fx{iSc}G?;T)WyrE zN*Qv_YW`#`vI{2d?Vw+?Ti73!7Td1a3Hhv1-GyruohNh?KV98A0?qzDJ-j`;NXrOnrrEU8;*ca3t=mpXH?vwBMd3326|T%ivRF zmYD+hGDKmZR$#H7BE<8@)Ba$GG3HOyf5!b*;v;;CR@BZ+T zUp;xKi3qB~AT3&fe{vHOe~_xIs@oo|+(vz_ZUd6ox$FZ&`UG{jOZz9_-MKnu&b@-o zQeD)AVGc2CwMn*715xgfg&Egiy!dA3Q^MNbkU2K!BWIVNvvdu;E2aHRg*B*N(<(Hg zhpE4{v(bIewpE({#971+yfPR1`)*VK_PPpBQogw(@7zf7DBnO<-sWi&R< zBc~57Bnmo?{c{@PlWV&{5#~<|#ut+IYc`q+oiu zI=yy+U!~9|QbGshJ^xva!y&YIk$g_m$ghwk=_7w2cTe;gM@q|rUU4Q#mh+Msm({?H z2i9056_t zXyz*VOsoB`j7>?ftHz3E5+Mc-l~c@_|6ClHAN;u3;f59?Fs?{e;^?bU3s_50MI6H-@N(b@#jJIWSIoY9R#+rH64{6h-5z^{W zwJv#E&ebkBYv*mt8{M;Vc?cAJrD-PUyAr45=n}_*?QsKeAe@{BBgtpJm}j8Rf)l-{ z6CLgqHlu)jcY?OVHg_-o!l`(D*9d)vYxjav92P7pITZ5z(~|S(sbzCM&!rIsm%=Et z(k8-xFy35#qYFzG{E=N4*{8wx*R3vNqQ8tLAD?eaujS=O>yg>+hdQzWBIV8&r`L=# zX*Vk2+4I=}FXa96&gIvSxAV`|6>Yd?1(?l zLZ!^qTG!VZqLzOAli4h$UzSl9dcaWl($s+HA9pGMOl}70`BMDy}^Kbv-zPIOo zw@l99R^iJ(t0nNfE@{T6O65~B!?i{88TR&eH4OplYS-F(pS=s~*1tx+T^gLo&Wrz@ zw67xK?QK~$ovZG+o^WUDRz2Qob%Ku?eYAj8VLm4dj;SnFy>09I2Rnj$6#o0c+>Et% zEYZ2BwMgn34^iaZ<0);8KfB=e8h`fKBXUaIRro}sDDNB1_KM$zb=wr%4STX{M-L0y zvS!wt{@E|r&nWdz@;7)^9HbX!OevR|Y`nVhh}pnn{Zgz~Bev$#Qf&4x_2LIM|6W5? zp5=FOtWUm&??=TKQr*=-+ClEgaxdH3oxb*$EL*#;+$dh`8p-m=3^JA;lbQnP@?>E`AxEl?y$~c8Maf*JC=#mD33>&H|N6`4(6*T7gkGy>t8t4 zj#lQe?fpE2hu$!At5X_~OK(Xi;WYNaZZ03qRlwvf9FumvvK%0tx#Ai`DMRI~o@fkV zs2Zu&PGzpWhMv>s1|}KQM>pyo)TUQkHY&9-)2f-p6}z}qjTK=|9Q8;^gT0&{&D0OPcP6 zd-ovK6Yh=i+GBrPehrR z8M)fNyEyt;GwCAvm|o<>m>Say4M1x!qcED_1?x3accy*^-6BoNJ%g162(Lf5uh9#X z!~j&f2W`pgIC#!zS-GqDzw_{~=>ia#{$(c&KK8$H=a1X^J1T^n}=HEZ}+7lNn zo2-LAFQ~uQ$JJHbm|$iNGIvNRgNBs z9}LfmN?=vdKdBHjHUB97gQ4}yE*3Uv-Vqiqyj*oBydCLZyLED}V8K)eM5FMhS7wlq zV(MK<%Hyzdv#A^J{R;!*MKlOeF&kCZ!pw6I7&mGOBtC&A8l%iQ{{_;i`jWo6Xp84! z)Gy?;(JgIdmeNlw+lZzHocEwSlMzN)WLR17??vXD=wRv{POs0jx}q={hX5xlCbF